Linux Cgroups详解(七)
ns子系统
ns子系统是一个比较特殊的子系统。特殊在哪儿呢,首先ns子系统没有自己的控制文件,其次ns子系统没有属于自己的状态信息,这点从ns子系统的ns_cgroup的定义可以看出:
struct ns_cgroup {
struct cgroup_subsys_state css;
};
它只有一个cgroup_subsys_state成员。
最后ns子系统的实现也比较简单,只是提供了一个ns_cgroup_clone函数,在copy_process和unshare_nsproxy_namespaces被调用。而ns_cgroup_clone函数本身的实现也很简单,只是在当前的cgroup下创建了一个子cgroup,该子cgroup完全clone了当前cgroup的信息,然后将当前的进程移到新建立的cgroup中。
这样看来,好像ns子系统没什么意义,其实不然。要想了解ns子系统的意义,就要分析一下ns_cgroup_clone被调用的时机了。我们来看copy_process中的代码:
if (current->nsproxy != p->nsproxy) {
retval = ns_cgroup_clone(p, pid);
if (retval)
goto bad_fork_free_pid;
}
copy_process是在do_fork中被调用的,作用在于为子进程复制父进程的相关信息。这段意思就是当前进程(即父进程)和子进程的命名空间不同时,调用ns_cgroup_clone。这样以来,ns子系统的作用就清楚了,ns子系统实际上是提供了一种同命名空间的进程聚类的机制。具有相同命名空间的进程会在相同cgroup中。
那什么时候,父进程fork出的子进程会拥有不同的命名空间呢,这就设计到了Linux的命名空间的机制了,在这里就不详细讲了。简单说来就是,在调用fork时,加入了特殊flag(比如NEWPID,NEWNS)时,内核会为子进程创建不同的命令空间。
除了这种情况外,ns_cgroup_clone在unshare_nsproxy_namespaces用到了。unshare_nsproxy_namespaces函数被sys_unshare调用,实际上是对unshare系统调用的实现。当指定相应标记时,unshare系统调用会为调用的进程创建不同的命名空间,因此调用ns_cgroup_clone为其创建新的cgroup。
作者曰:要深入了解ns子系统,linux namespace机制是绕不过的,等写完cgroup子系统后,我会专门写一篇文章分析linux namespace机制。