如果没有进程号命名空间,那么容器中的进程就能够看到容器外的进程,进而可以通过系统调用kill向容器外的进程发送信号。这当然不好。进程号命名空间让容器内的进程不能看到容器外的进程。但是这种隔绝是单向的,容器外的进程可以看到容器内的进程。更有趣的是,同一个进程在容器内有一个进程号,在容器外有另一个进程号。下面看一下进程号命名空间的数据结构:
进程号命名空间不同于前面讲述的几个命名空间,它有层次关系。在子进程号命名空间中创建进程,不仅子进程号命名空间会分配一个进程号,父进程号命名空间也会分配一个进程号如图20-7所示。
图20-7 进程号命名空间举例
进程号到底是什么呢?它的数据结构如下:
在task_struct中存储着一个长度为3、类型为pid_link的数组pids,数组成员分别对应进程的进程号、进程组号和会话号。结构pid_link中的指针成员pid指向实际的pid实例。结构pid中的hlist_head类型成员tasks用于关联pid_link中的hlist_node类型成员node,目的是通过pid_link实例关联到进程的task_struct实例。pid_link作为“中介”,帮助pid和task_struct实现双向关联。
举个例子,假设系统中有4个进程,这4个进程同属于一个会话,其中两个进程同属于一个进程组,另两个进程属于另一个进程组,如图20-8所示。
(www.xing528.com)
图20-8 进程号命名空间例子
在内核中相关的数据结构如图20-9所示。
图20-9 进程号命名空间相关数据结构
结构pid中可以有多个进程号,哪一个进程号有效取决于进程号命名空间。
每一个进程号都关联着一个进程号结构,但是进程号结构中可能有多个进程号,取出哪一个进程号取决于进程号命名空间中的变量level,如图20-10所示。
图20-10 进程号命名空间中的级别
有了进程号命名空间后,结构pid中含有一个数组,数组的大小取决于进程号命名空间的嵌套数目,数组成员的类型upid。upid含有一个整数,表示在某进程号命名空间中的进程号,还含有一个指针指向它所从属的进程号命名空间。
进程号命名空间本身是一个树状结构,有一个数字表示它所处的级别,另有一个指针指向父进程号命名空间。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。