IOError: No space left on device - which device?
IOError: No space left on device - which device?
我正在将一个小文件 (8.5 Mb) 上传到烧瓶测试服务器。
文件上传完成后,服务器报告:
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
现在,服务器有大量免费 space - 超过 3Gb。
我查看了 Werkzeug github repo 试图找到 Werkzeug 试图写入的位置,但无法找到它。
我还检查了 tempfile.gettempdir(),它给出了 /var/tmp 作为临时文件目录,但这个文件夹实际上是空的,所以我认为这不是造成问题的位置。
如何找到没有space的设备?
如果您可以在服务器上获得 shell,请尝试键入 df -h
并查找任何显示 Use%
为 100% 或 Avail
的条目比你的文件大小。
Werkzeug 使用 tempfile.TemporaryFile()
在您的临时目录中存储超过一定大小的文件,但请考虑到这些文件 未链接 以确保安全。您不会在目录中看到它们。 tempfile.gettempdir()
是确定用于此的目录的正确方法。
您的 /var/tmp
目录可能配置为较小的分区。检查 df -h
以查看该分区是否还有足够的 space 剩余。您还需要免费检查 inodes,使用 df -i
.
也可能是某个进程(可能是您的)在此类未链接的文件上挂起的时间太长,并且 space 尚未返回到 OS。您可以使用以下命令检查保留已删除文件的进程:
lsof -nP | grep '/var/tmp' | grep '(deleted)'
或
find /proc/*/fd -ls | grep '/var/tmp' | grep '(deleted)'
试试df -i
,可能没有空闲的inode。
编辑:
另一种选择,找到werkzeug pid,让它成为777,
- 运行
strace -p 777 &> /tmp/strace_log
- 尝试上传文件
- 停止 strace
- 找到那个
No space left on device
的消息,就好了
write(1, "blah blah ..."..., 57) = -1 ENOSPC (No space left on device)
要写入的第一个参数是文件描述符
- 继续并尝试找到特定的
open(... = X
系统调用,X 是一个文件描述符,它将在 "write" 系统调用步骤 中失败
我知道这很麻烦,但这就是调试。
@Tom Hunt 的评论是对的。
这个 unix SE 答案解释了 what happened。
As a protection against low disc space, some daemons automatically "shadows" the current /tmp/ dir with a ram disc if the the root partition runs out of disc space. Sadly there's no automatic reversion of that process once enough disc space is free again.
我卸载了 /tmp 目录并遵循了 Nitesh 的建议:
sudo umount /tmp
sudo echo 'MINTMPKB=0' > sudo /etc/default/mountoverflowtmp
现在上传正常。
我正在将一个小文件 (8.5 Mb) 上传到烧瓶测试服务器。
文件上传完成后,服务器报告:
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
现在,服务器有大量免费 space - 超过 3Gb。
我查看了 Werkzeug github repo 试图找到 Werkzeug 试图写入的位置,但无法找到它。
我还检查了 tempfile.gettempdir(),它给出了 /var/tmp 作为临时文件目录,但这个文件夹实际上是空的,所以我认为这不是造成问题的位置。
如何找到没有space的设备?
如果您可以在服务器上获得 shell,请尝试键入 df -h
并查找任何显示 Use%
为 100% 或 Avail
的条目比你的文件大小。
Werkzeug 使用 tempfile.TemporaryFile()
在您的临时目录中存储超过一定大小的文件,但请考虑到这些文件 未链接 以确保安全。您不会在目录中看到它们。 tempfile.gettempdir()
是确定用于此的目录的正确方法。
您的 /var/tmp
目录可能配置为较小的分区。检查 df -h
以查看该分区是否还有足够的 space 剩余。您还需要免费检查 inodes,使用 df -i
.
也可能是某个进程(可能是您的)在此类未链接的文件上挂起的时间太长,并且 space 尚未返回到 OS。您可以使用以下命令检查保留已删除文件的进程:
lsof -nP | grep '/var/tmp' | grep '(deleted)'
或
find /proc/*/fd -ls | grep '/var/tmp' | grep '(deleted)'
试试df -i
,可能没有空闲的inode。
编辑:
另一种选择,找到werkzeug pid,让它成为777,
- 运行
strace -p 777 &> /tmp/strace_log
- 尝试上传文件
- 停止 strace
- 找到那个
No space left on device
的消息,就好了write(1, "blah blah ..."..., 57) = -1 ENOSPC (No space left on device)
要写入的第一个参数是文件描述符 - 继续并尝试找到特定的
open(... = X
系统调用,X 是一个文件描述符,它将在 "write" 系统调用步骤 中失败
我知道这很麻烦,但这就是调试。
@Tom Hunt 的评论是对的。
这个 unix SE 答案解释了 what happened。
As a protection against low disc space, some daemons automatically "shadows" the current /tmp/ dir with a ram disc if the the root partition runs out of disc space. Sadly there's no automatic reversion of that process once enough disc space is free again.
我卸载了 /tmp 目录并遵循了 Nitesh 的建议:
sudo umount /tmp
sudo echo 'MINTMPKB=0' > sudo /etc/default/mountoverflowtmp
现在上传正常。