libvirtd日志报错virCgroupSetValueStr"No space left on device"
在/var/lob/libvirt/libvirtd.log日志中有关于 cgroup 无法设置cpuset,cpu,cpuacct相关的
2018-07-30 10:26:46.764+0000| 24902| error | virCgroupSetValueStr:669 | Unable to write to '/sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemu\x2dexample\x2dad04f.scope/tasks': No space left on device
2018-07-30 10:26:46.764+0000| 24902| error | virCgroupRemoveRecursively:1042 | Unable to remove /sys/fs/cgroup/memory/machine.slice/machine-qemu\x2dexample\x2dad04f.scope/ (16)
2018-07-30 10:26:46.764+0000| 24902| error | virCgroupRemoveRecursively:1042 | Unable to remove /sys/fs/cgroup/devices/machine.slice/machine-qemu\x2dexample\x2dad04f.scope/ (16)
2018-07-30 10:26:46.764+0000| 24902| error | virCgroupRemoveRecursively:1042 | Unable to remove /sys/fs/cgroup/blkio/machine.slice/machine-qemu\x2dexample\x2dad04f.scope/ (16)检查可以发现libvirtd默认应该建立的 /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemu\x2dexample\x2dad04f.scope/ cgroup控制组没有建立,所以在添加pid到 tasks 时候失败。不过,和常见的文件目录不存在报错No such file or directory不同,在cgroup的控制组中如果不能写入,都是显示No space left on devices。
libvirt的cgroup
可以看到,当创创建启动第一个虚拟机时候,libvirt创建了
/sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice这个cgroup控制组,但是检查这个目录下的cpuset.mems和cpuset.cpus内容都是空的。
模拟创建cgroup
cgcreate -g cpuset:machine.slice/machine-qemu\x2diso\x2dexample\x2dtest.scope创建完成后可以看到建立了目录/sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope,注意此时这个目录下的 cpuset.cpus 和 cpuset.mems 内容也是空的。
此时还不能加入task的pid
#echo 8324 > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/tasks
-bash: echo: write error: No space left on device而且也不能设置cpus(需要一级级设置):
#echo "0-63" > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/cpuset.cpus
-bash: echo: write error: Permission denied这是因为上一级cpuset.cpus没有设置,所以先设置上一级,然后设置下一级
#echo "0-63" > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/cpuset.cpus
#echo "0-63" > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/cpuset.cpus
#cat /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/cpuset.cpus
0-63
#cat /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/cpuset.cpus
0-63同样也要设置好两级cpuset.mems:
#echo 0 > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/cpuset.mems
#echo 0 > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/cpuset.mems此时就可以设置tasks不再报错
#echo 8324 > /sys/fs/cgroup/cpuset,cpu,cpuacct/machine.slice/machine-qemux2disox2dexamplex2dtest.scope/tasks具体排查,请参考libvirt程序调试排错
No space left on device可能的其他原因
No space left on device可能的其他原因CGroups and No Space这篇文档让我想起这个问题以前处理过,在某次写脚本设置进程的cgroup时遇到过并且也解决过:
在设置cgroup控制组的时候,必须同时设置cpuset.cpus和cpuset.mems两个值,否则会导致报错No space left on device。
例如:
创建一个cgroup控制组my_app
cgcreate -g cpuset:my_app如果操作系统是CentOS 5.x,则/cgroup/cpuset/my_app/cpuset.cpus和/cgroup/cpuset/my_app/cpuset.mems值都是空的:
#cat /cgroup/cpuset/my_app/cpuset.cpus
#cat /cgroup/cpuset/my_app/cpuset.mems如果操作系统是CentOS 7.x,则/sys/fs/cgroup/cpuset/my_app/cpuset.cpus和/sys/fs/cgroup/cpuset/my_app/cpuset.mems值此时是空的:
#cat /sys/fs/cgroup/cpuset/my_app/cpuset.cpus
#cat /sys/fs/cgroup/cpuset/my_app/cpuset.memsCentOS 7需要安装
libcgroup-tools软件包才有cgcreate工具
如果此时只设置 cgroup 控制组 my_app 的 cpuset.cpus 值,没有设置 cpuset.mems ,却马上将某个进程的pid加入到 my_app/tasks 中就会同样报错 ``
#cgset -r cpuset.cpus=32 my_app
#cat /sys/fs/cgroup/cpuset/my_app/cpuset.cpus
32
#cat /sys/fs/cgroup/cpuset/my_app/cpuset.mems假设有一个进程 my_example_app.sh 的 pid 是 13058 ,需要将这个进程归到my_app这个cgroup控制组,我们通常可以使用:
echo 13058 > /sys/fs/cgroup/cpuset/my_app/tasks但是你会发现此时报错
-bash: echo: write error: No space left on device解决的方法是:在设置cpuset.cpus=32之后,必须设置cpuset.mems=XXX才能添加tasks中的pid
#cgset -r cpuset.mems=0 my_app
#cat /sys/fs/cgroup/cpuset/my_app/cpuset.mems
0然后执行将pid值13058添加到/sys/fs/cgroup/cpuset/my_app/tasks就不会报错
#echo 13058 > /sys/fs/cgroup/cpuset/my_app/tasks此时检查13058的 cgroup 控制组就可以看到正确的my_app这个cgroup控制组设置:
#cat /proc/13058/cgroup
...
4:cpuacct,cpu,cpuset:/my_app
...参考
Cgroup change results in "No space left on device" or "Error Code: 5001" - 这篇文档是Red Hat知识库,我没有账号,等以后看看
Last updated
Was this helpful?