2015年(100)
分类: LINUX
2015-06-03 10:18:26
这一章里,我们先整体介绍一个cgroup的框架结构,以及cgroup文件系统的相应文件定义。这里我们先看一下cgroup的主要结构关系:
图2 主要数据结构关系
该图包含了cgroup的所有主要数据结构及它们的关系。其中cgroupfs_root相当于我们mount操作指定的dir;cgroup表示在mount目录下的mkdir cg_test;而cgroup_subsys则是所有subsys的基类(-o选项),它定义了所有subsys的相应方法,及属性;cgroup_subsys_state是cgroup管理的subsys的group控制体的抽象类(这个名字有点别扭,看了后面可能就会明白),每个子系统有自己实现类如cpuset,task_group,mem_cgroup等,即cgroup_subsys_state实现C语言的多态,cgroup只管理cgroup_subsys_state这个结构,而不同的子系统根据这个结构,通过container_of来还原出自己的真正控制体;cg_cgroup_link则定义着cgroup与css_set的多对多关系(一个css_set为什么会有多个cgroup?——其根本的原因在于一个task会被attach到多个hierarchy,并且在每个hierarchy下的必有一个cgroup管理着该task(一个task只有一个css_set),所以有几个hierarchy该css_set就有几个cgroup。一个cgroup为什么会有多个css_set?——因为一个cgroup可以attach多个进程,而这些进程它们的css_set可能不一样,这个由该task所属的cgroups决定,只有所属的cgroups完全一样,它们才会共享一个css_set,否则的话,它们的css_set就不一样),css_set->cg_links指向所有管理了该css_set的cgroup(这些cgroup由cg_cgroup_link->cg_link_list链接起来的cg_cgroup_link),同理cgroup->css_sets指向所有该cgroup管理的css_set(这些css_set由cg_cgroup_link->cgrp_link_list链接起来的cg_cgroup_link),加入一个这样的中间结构其原因主要是解除css_set与cgroup之间的耦合关系(考虑在两者直接连接的情况下,如果我们要删除cgroup的操作,及多加了这个结构的相应操作?)。所有的css_set保存在css_set_table的全局哈希表里,它们的hash函数及key为css_set_hash(css_set->subsys);css_set则建立task与它的一对多关系,不一样的进程可能指向同一个css_set(如刚fork的父子进程),而css_set->tasks则是所有引用该css_set的tasks的list的head,task之间用task->cg_list进行链接;同样的,一个cgroupfs_root的所有cgroup_subsys由cgroupfs_root->subsys_list组织;所有的cgroupfs_root通过它的root_list连接到roots这个全局变量头里。
通过该图我们可以知道cgroup内并没有保存task的list,那么我们查看tasks文件的时候(cat tasks)是怎么获得它的所有tasks?——cgroup->css_sets保存了所有它管理的css_set(通过cg_cgroup_link连接),另外css_set->tasks保存了所有引用它的tasks(该过程对应于cgroup_tasks_open);同样的,当我们cat /proc//cgroup的时候可以查看到一个task被哪些cgroup管理,这个过程是通过task->cgroups获得它的css_set,然后再从css_set->cg_links(通过cg_cgroup_link连接)获得它所属的cgroup(该过程相对应于cgroup_open->proc_cgroup_show->task_cgroup_from_root,实际的代码过程跟分析有点不一样,是由于输出要求按root区分,但依据的关系是一样的)。
注:我们mount之后其实已经产生了一个top cgroup,即它本身既是cgroupfs_root也是一个cgroup。