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機制。