cgroup源码分析6——cgroup 中默认控制文件的内核实现分析
Contents
cgroup中有一些默认的文件,本文详细分析了这些文件背后的内核实现细节,以便更深入的理解cgroup。
这些文件包括:
- notify_on_release
- release_agent
- cgroup.procs
- tasks
- cgroup.clone_children
- cgroup.event_control
- cgroup.sane_behavior
注意:本文分析中引用的代码来自于centos系统自带的内核:kernel-3.10.0-862.9.1.el7
notify_on_release
notify_on_release
接口在每个cgroup都存在,对其读写本质上是修改该cgroup->flags
的CGRP_NOTIFY_ON_RELEASE
, 后续cgroup释放时,会根据该flags进行相应的操作。
|
|
从cgroup_write_notify_on_release
可以看出:
- 写入0或者空都可以清除CGRP_NOTIFY_ON_RELEASE这个flags
- 写入1或者任意正整数,都可以置位CGRP_NOTIFY_ON_RELEASE这个flags
示例如下:
|
|
release_agent
release_agent里面包含了cgroup退出时将会执行的命令,系统调用该命令时会将相应cgroup的相对路径当作参数传进去。
注意:这个文件只会存在于root cgroup下面,其他cgroup里面不会有这个文件。
当cgroup退出是,如果notify_on_release为1,则会调用release_agent里面配置的命令。
内核中,该文件对应的就是一个字符串,其保存在cgroup->root->release_agent_path
中。 对该文件的读写就不分析了,这里主要分析一下内核中如何实现cgroup
退出时,执行release_agent
中指定的命令。
|
|
- 在
cgroup_destroy_locked
和__put_css_set
等cgroup
退出的代码路径中,都会调用check_for_release
函数,该函数用来判断是否需要执行release_agent
指定的命令,如果需要,就将该cgroup添加到链表release_list
中,并调度schedule_work(&release_agent_work);
。 cgroup_release_agent
这个方法,从release_list
链表中循环读取要退出的cgroup,然后构建执行环境,去执行指定的命令。
|
|
可以看出,release_agent
中指定的命令的执行时,其HOME
目录为/
。另外,这种设计可以让cgroup
退出和执行release_agent
中指定的命令异步进行。
cgroup.procs 和tasks
cgroup.procs和tasks的区别,请参考这篇博客。
想这两个文件中写入一个进程号或者线程号时,内核中最终调用的函数为:attach_task_by_pid
,其原型如下:
|
|
根据threadgroup 是否为true,来决定写入的pid代表的是进程还是线程。即该函数是通过写cgroup.procs进入的时,threadgroup为ture,通过写tasks进入的时,threadgroup为false。
读取这两个文件的内容时,执行的函数分别为cgroup_tasks_open
和cgroup_procs_open
,最终都调用函数cgroup_pidlist_open
,只是其中的第二个参数不同,内核中的实现如下:
|
|
在cgroup_pidlist_open
中,关键的获取进程/线程 ID的函数为pidlist_array_load
:
|
|
- 第20行通过cgroup_task_count获取该cgroup中的进程个数
- 第21行分配存放结果的数组array
- 第25-37行代码填充数组array
- 第40-42行代码对array进行排序,并当时cgroup.procs时进行去重
cgroup.clone_children
这个文件只对cpuset(subsystem)
有影响,当该文件的内容为1
时,新创建的cgroup
将会继承父cgroup
的配置,即从父cgroup
里面拷贝配置文件来初始化新cgroup
其内核代码实现也比较简单,对其读写本质上是修改该cgroup->flags
的CGRP_CPUSET_CLONE_CHILDREN
位。
More: 按理说,该配置只对
cpuset(subsystem)
有用,应该放到cpuset的subsystem中,但是由于历史原因,其放到了全局cgroup文件中。
在 centos 7.5
中,cgroup.clone_children
的值默认为0.
cgroup.event_control
该文件是用于eventfd的接口。
具体用法,请参考: 文章引用
TODO: 其内核实现分析,稍后补充。
cgroup.sane_behavior
这个文件只会存在于root cgroup下面,其他cgroup里面不会有这个文件。该文件也是控制了cgroup->flags
的一个叫做CGRP_ROOT_SANE_BEHAVIOR
的位。
由于cgroup一直再发展,很多子系统有很多不同的特性,内核用CGRP_ROOT_SANE_BEHAVIOR
来控制使能某些特性和关闭某些特性。
注意: 该文件是只读的,也就是说不能随便修改该值,只有在mount各个子系统时,指定mount选项
__DEVEL__sane_behavior
是,该位的值才会置位1。
|
|
在centos 7.5 上,该flags默认都没有打开:
|
|