Linux PID namespace
一直对linux内核的namespace感到困惑,今天看了一下代码才知道,原来所谓的namespace其实就是给虚拟化用的,PID namespace其实就是建立一个新的PID空间,这样内部可以使用一套新的PID,而且不会和外部冲突。这也就是说某个进程其实会有两个PID,一个空间一个。
我写了段C代码来展示这个问题。
[c]
include
include
include
include
include
include
static int fork_child(void *arg)
{
int a = (int)arg;
int i;
pid_t pid;
printf("In the container, my pid is: %dn", getpid());
for (i = 0; i < a; i++) {
pid = fork();
if (pid < 0)
return pid;
else if (pid)
printf("pid of my child is %dn", pid);
else if (pid == 0) {
sleep(3);
exit(0);
}
}
return 0;
}
int main(int argc, char argv[])
{
int cpid;
void childstack, stack;
int flags;
int ret = 0;
int stacksize = getpagesize() 4;
if (argc != 2) {
fprintf(stderr, "Wrong usage.n");
return -1;
}
stack = malloc(stacksize);
if (!stack) {
perror("malloc");
return -1;
}
printf("Out of the container, my pid is: %dn", getpid());
childstack = stack + stacksize;
flags = CLONE_NEWPID | CLONE_NEWNS;
cpid = clone(fork_child, childstack, flags, (void *)atoi(argv[1]));
printf("cpid: %dn", cpid);
if (cpid < 0) {
perror("clone");
ret = -1;
goto out;
}
fprintf(stderr, "Parent sleeping 20 secondsn");
sleep(20);
ret = 0;
out:
free(stack);
return ret;
}
[/c]
运行结果:
$ sudo ./pid_container 3
Out of the container, my pid is: 7061
cpid: 7062
In the container, my pid is: 1
Parent sleeping 20 seconds
pid of my child is 2
pid of my child is 3
pid of my child is 4
其实被namespace化的不只是PID,还有很多东西,貌似它们合起来被称为container。可以看 include/linux/nsproxy.h:
struct nsproxy {
atomic_t count;
struct uts_namespace uts_ns;
struct ipc_namespace ipc_ns;
struct mnt_namespace mnt_ns;
struct pid_namespace pid_ns;
struct net *net_ns;
};
虚拟化的东西是越来越让人摸不清头脑了。。。。