小さなファイル(8.5 Mb)をflaskテストサーバーにアップロードしています。
ファイルのアップロードが完了すると、サーバーは次のことを報告します。
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/wtforms/form.py",
line 212, in __call__
return type.__call__(cls, *args, **kwargs)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/flask_wtf/form.py", line 49, in __init__
formdata = request.form
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/local.py",
line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/utils.py",
line 71, in __get__
value = self.func(obj)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/wrappers.py",
line 484, in form
self._load_form_data()
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/flask/wrappers.py",
line 165, in _load_form_data
RequestBase._load_form_data(self)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/wrappers.py",
line 356, in _load_form_data
mimetype, content_length, options)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 193, in parse
content_length, options)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 99, in wrapper
return f(self, stream, *args, **kwargs)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 210, in _parse_multipart
form, files = parser.parse(stream, boundary, content_length)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 520, in parse
return self.cls(form), self.cls(files)
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/datastructures.py",
line 373, in __init__
for key, value in mapping or ():
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 518, in <genexpr>
form = (p[1] for p in formstream if p[0] == 'form')
File "/home/ubuntu/.virtualenvs/eco_app/lib/python2.7/site-packages/werkzeug/formparser.py",
line 494, in parse_parts
_write(ell)
IOError: [Errno 28] No space left on device
現在、サーバーには3Gbを超える十分な空き容量があります。
Werkzeug github repo を調べて、Werkzeugが書き込もうとしている場所を見つけようとしましたが、追跡できません。
tempfile.gettempdir() もチェックしました。これは、一時ファイルディレクトリとして/ var/tmpを提供しますが、このフォルダーは実質的に空なので、問題を引き起こしている場所ではないと思います。
スペースのないデバイスを見つけるにはどうすればよいですか?
@TomHuntのコメントは正しい方向に進んでいました。
このUNIXSEの回答は、 何が起こったのか を説明しています。
ディスク容量の不足に対する保護として、一部のデーモンは、ルートパーティションのディスク容量が不足した場合に、現在の/ tmp/dirをRAMディスクで自動的に「シャドウ」します。残念ながら、十分なディスク容量が再び解放されると、そのプロセスの自動復帰はありません。
/ tmpディレクトリをアンマウントし、Niteshの提案に従いました。
Sudo umount /tmp
Sudo echo 'MINTMPKB=0' > Sudo /etc/default/mountoverflowtmp
そして今、アップロードは正しく機能しています。
サーバーでシェルを取得できる場合は、df -h
と入力して、Use%
が100%、またはAvail
がファイルサイズよりも小さいエントリを探してみてください。
Werkzeugは、tempfile.TemporaryFile()
を使用して、特定のサイズを超えるファイルを一時ディレクトリに保存しますが、セキュリティのために、これらのファイルはnlinkedであることを考慮してください。それらがディレクトリにリストされていることはわかりません。 tempfile.gettempdir()
は、これに使用されるディレクトリを決定する正しい方法です。
君の /var/tmp
ディレクトリはおそらくより小さなパーティション用に構成されています。確認する df -h
そのパーティションにまだ十分なスペースが残っているかどうかを確認します。また、無料でチェックする必要がありますinodes、df -i
。
また、プロセス(おそらくあなたのプロセス)がそのようなリンクされていないファイルに長時間ハングアップしていて、スペースがまだOSに戻されていない可能性もあります。次の方法で、削除されたファイルを保持しているプロセスを確認できます。
lsof -nP | grep '/var/tmp' | grep '(deleted)'
または
find /proc/*/fd -ls | grep '/var/tmp' | grep '(deleted)'
_df -i
_を試してください。無料のiノードがない可能性があります。
編集:
別のオプション、werkzeug pidを見つけて、777にします。
strace -p 777 &> /tmp/strace_log
_No space left on device
_メッセージを見つけると、write(1, "blah blah ..."..., 57) = -1 ENOSPC (No space left on device)
のようになります。最初に書き込む引数はファイル記述子です。open(... = X
_ syscallを見つけようとします。そのXは、「書き込み」syscallステップで失敗するファイル記述子です。かなり面倒ですが、それはデバッグです。