引用2013 年 systemd 新控制组界面的公告(添加了重点):
请注意,当前作为单元属性公开的 cgroup 属性的数量是有限的。这将在稍后扩展,因为它们的内核接口已被清理。例如,由于内核逻辑的继承语义被破坏,cpuset 或 freezer 目前根本没有公开。此外,不支持在运行时将单元迁移到不同的切片(即更改运行单元的 Slice= 属性),因为内核当前缺少原子 cgroup 子树移动。
那么,内核逻辑的继承语义有什么问题cpuset
(以及这种问题如何不适用于其他 cgroup 控制器,例如cpu
)?
RedHat 网站上有一篇文章给出了一个未经验证的解决方案,说明如何在 RHEL 7 中使用 cgroup cpusets,尽管它们缺乏作为易于管理的 systemd 单元属性的支持......但这甚至是个好主意吗?上面加粗的引文是有关的。
换句话说,使用此处引用的 cgroup v1 cpuset 可能会遇到哪些“陷阱”(陷阱)?
我正在为此开始赏金。
回答此问题的可能信息来源(无特殊顺序)包括:
- cgroup v1 文档;
- 内核源代码;
- 试验结果;
- 现实世界的经验。
上面引用中粗体线的一个可能含义是,当一个新进程被分叉时,它不会与它的父进程保持在同一个 cpuset cgroup 中,或者它在同一个 cgroup 中但处于某种“未强制”状态因此它实际上可能运行在与 cgroup 允许的不同的 CPU 上。但是,这纯粹是我的猜测,我需要一个明确的答案。
我对 cgroups 的了解还不够,无法给出明确的答案(而且我当然没有使用 2013 年的 cgroups 的经验!)但是在香草 Ubuntu 16.04 cgroups v1 上似乎有它的共同作用:
我设计了一个小测试,强制分叉为一个不同的用户,使用一个
sudo /bin/bash
分离出来的孩子&
——这个-H
标志是额外的偏执狂,强制sudo
在 root 的家庭环境中执行。这产生:
作为参考,这是我系统上 cgroup 挂载的结构:
此处的内核错误跟踪器中记录了至少一个与 cpusets 相关的明确且未解决的问题:
从票证中引用一条评论(我将超链接添加到实际提交,并删除 IBM 电子邮件地址以防垃圾邮件机器人):
修复提交(后来被恢复)很好地描述了这个问题:
描述了相同的非对称热插拔问题,并进一步了解它与继承的关系,在:
引用那张票:
虽然 cpuset 可能存在其他问题,但以上内容足以理解和理解 systemd 没有公开或利用 cpuset “由于内核逻辑的继承语义被破坏”的声明。
从这两个错误报告中,不仅 CPU 不会在恢复后重新添加回 cpuset,而且即使(手动)添加它们,该 cgroup 中的进程仍将在可能被 cpuset 不允许的 CPU 上运行。
我发现来自 Lennart Poettering 的一条消息直接证实了这一点(添加了粗体字):
2016 年 8 月 3 日星期三 16:56 +0200,Lennart Poettering 写道:
非常简短的回答:代码不能很好地多进程,不同的进程使用和释放 PID 在他们的孩子的 PID 终止之前将它们返回到池中 - 让上游相信 PID 的孩子是活动的,所以跳过那个 PID,但是那个 PID在终止孩子之前不应该重新发行。简而言之,糟糕的锁。
服务、范围和切片可以由管理员自由创建,也可以由程序动态创建。这可能会干扰操作系统在启动期间设置的默认切片。
使用 Cgroups,一个进程及其所有子进程从包含的组中获取资源。
还有更多……导致冗长的答案……
许多人表达了他们的担忧:
Jonathan de Boyne Pollard 的“ Linux 控制组不是工作”(2016 年):
TerminateJobObject()函数
Windows NT 作业对象
乔纳森的解释中提供的答案是:
按照上面的链接获取完整的解释。
“ Cgroups v2:资源管理第二次做得更糟”(2016 年 10 月 14 日),作者 davmac:
另请参阅 cgroup v2 文档:“ v1 的问题和 v2 的基本原理”:
请参阅第 3 节的链接了解更多信息。
Lennart Poettering(systemd 开发人员)和 Daniel P. Berrange(Redhat)之间的通信,周三,20.07.16 12:53 从systemd-devel 档案中检索,标题为:“ [systemd-devel] 通过 cpuset 将所有进程限制到 CPU/RAM控制器“:
我希望这能澄清事情。