Cgroup Freezer
cgroup冷冻器对于批处理作业管理系统非常有用,该系统可以启动和停止一组任务,以便根据系统管理员的需求安排机器的资源。这种程序通常用于HPC集群,以安排对整个集群的访问。cgroup冷冻器使用cgroups来描述批处理作业管理系统要启动/停止的任务集。它还提供了一种启动和停止组成作业的任务的方法。
cgroup冷冻器还可用于对运行中的任务组进行检查点。冷冻器允许检查点代码通过尝试将cgroup中的任务强制转换为静止状态来获得任务的一致图像。一旦任务处于静止状态,另一个任务就可以遍历/proc或调用内核接口来收集有关已静止任务的信息。检查点任务可以在以后重新启动,以防发生可恢复的错误。这还允许将检查点任务在集群中的节点之间迁移,方法是将收集到的信息复制到另一个节点,并在那里重新启动任务。
SIGSTOP和SIGCONT的序列并不总是足以停止和恢复用户空间的任务。这两个信号都可以从我们希望冻结的任务内部观察到。虽然SIGSTOP无法被捕获、阻塞或忽略,但它可以被等待或ptrace父任务看到。SIGCONT特别不适合,因为它可以被任务捕获。任何旨在监视SIGSTOP和SIGCONT的程序都可能因尝试使用SIGSTOP和SIGCONT来停止和恢复任务而出现问题。我们可以使用嵌套的bash shell来演示这个问题:
$ echo $$ 16644 $ bash $ echo $$ 16690
从第二个不相关的bash shell:
$ kill -SIGSTOP 16690 $ kill -SIGCONT 16690
<此时16690退出并导致16644也退出>
这是因为bash可以观察到这两个信号并选择如何对其做出响应。
另一个捕获并响应这些信号的程序的例子是gdb。实际上,任何旨在使用ptrace的程序都可能在停止和恢复任务的方法上出现问题。
相比之下,cgroup冷冻器使用内核冷冻器代码来防止冻结/解冻周期对被冻结的任务变得可见。这允许上述bash示例和gdb按预期运行。
cgroup冷冻器是分层的。冻结一个cgroup会冻结属于该cgroup及其所有后代cgroup的所有任务。每个cgroup都有自己的状态(self-state)和从父级继承的状态(parent-state)。只有当这两个状态都是THAWED时,cgroup才是THAWED。
cgroup冷冻器创建了以下cgroupfs文件。
- freezer.state:读写。
- 读取时,返回cgroup的有效状态 - "THAWED"、"FREEZING"或"FROZEN"。这是自身状态和父状态的组合。如果任何一个正在冻结,cgroup就处于冻结状态(FREEZING或FROZEN)。
- 当写入时,设置cgroup的自身状态。允许两个值 - "FROZEN"和"THAWED"。如果写入了FROZEN,则cgroup(如果尚未冻结)进入FREEZING状态,以及其所有后代cgroup。
- 如果写入了THAWED,则cgroup的自身状态将更改为THAWED。请注意,如果父状态仍在冻结,有效状态可能不会更改为THAWED。如果cgroup的有效状态变为THAWED,则因为该cgroup而处于冻结状态的所有后代也将离开冻结状态。
- freezer.self_freezing:只读。
- 显示自身状态。如果自身状态为THAWED,则为0;否则为1。如果最后一次对freezer.state的写入是"FROZEN",则该值为1。
- freezer.parent_freezing:只读。
- 显示父状态。如果cgroup的祖先中没有一个被冻结,则为0;否则为1。
根cgroup是不可冻结的,上述接口文件不存在。
使用示例:
# mkdir /sys/fs/cgroup/freezer # mount -t cgroup -ofreezer freezer /sys/fs/cgroup/freezer # mkdir /sys/fs/cgroup/freezer/0 # echo $some_pid > /sys/fs/cgroup/freezer/0/tasks
获取冷冻器子系统的状态:
# cat /sys/fs/cgroup/freezer/0/freezer.state THAWED
冻结容器中的所有任务:
# echo FROZEN > /sys/fs/cgroup/freezer/0/freezer.state # cat /sys/fs/cgroup/freezer/0/freezer.state FREEZING # cat /sys/fs/cgroup/freezer/0/freezer.state FROZEN
解冻容器中的所有任务:
# echo THAWED > /sys/fs/cgroup/freezer/0/freezer.state # cat /sys/fs/cgroup/freezer/0/freezer.state THAWED
这是在简单场景中为用户空间任务执行正确操作的基本机制。