From c862b89079810a6f7f10ed4ed60fe5914ad70e0e Mon Sep 17 00:00:00 2001 From: Gao feng Date: Wed, 16 Sep 2015 18:54:56 +0800 Subject: [PATCH] running contianers in the pid ns of pod init manpage of setns says: >CLONE_NEWPID behaves somewhat differently from the other nstype values: reassociating the calling thread with a PID namespace changes only the PID namespace that child processes of the caller will >be created in; it does not change the PID namespace of the caller itself. Reassociating with a PID namespace is allowed only if the PID namespace specified by fd is a descendant (child, grandchild, >etc.) of the PID namespace of the caller. For further details on PID namespaces, see pid_namespaces(7). so clone a temporary process to enter pid ns, and then create containers. and join them to the other nss of pod init. Signed-off-by: Gao feng --- src/container.c | 9 +---- src/container.h | 3 +- src/init.c | 93 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/src/container.c b/src/container.c index 8721033..1c26c5f 100644 --- a/src/container.c +++ b/src/container.c @@ -276,7 +276,6 @@ static int hyper_rescan_scsi(void) struct hyper_container_arg { struct hyper_container *c; - int pidns; int ipcns; int utsns; int pipe[2]; @@ -294,11 +293,6 @@ static int hyper_container_init(void *data) goto fail; } - if (setns(arg->pidns, CLONE_NEWPID) < 0) { - perror("setns to pidns of pod init faild"); - goto fail; - } - if (setns(arg->ipcns, CLONE_NEWIPC) < 0) { perror("setns to ipcns of pod init faild"); goto fail; @@ -449,12 +443,11 @@ static int hyper_setup_pty(struct hyper_container *c) } int hyper_start_container(struct hyper_container *container, - int pidns, int utsns, int ipcns) + int utsns, int ipcns) { int stacksize = getpagesize() * 4; struct hyper_container_arg arg = { .c = container, - .pidns = pidns, .utsns = utsns, .ipcns = ipcns, }; diff --git a/src/container.h b/src/container.h index db969d9..8ab04fd 100644 --- a/src/container.h +++ b/src/container.h @@ -40,9 +40,8 @@ struct hyper_container { struct hyper_pod; int hyper_start_container(struct hyper_container *container, - int pidns, int utsns, int ipcns); + int utsns, int ipcns); struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id); -//int hyper_restart_containers(struct hyper_pod *pod); void hyper_cleanup_container(struct hyper_pod *pod); #endif diff --git a/src/init.c b/src/init.c index cb787ac..b2a6462 100644 --- a/src/init.c +++ b/src/init.c @@ -110,18 +110,6 @@ static int pod_ctl_pipe_handle(struct hyper_event *de, uint32_t len) case STOPPOD: fprintf(stdout, "get type STOPPOD, exit\n"); hyper_cleanup_pod(pod); - /* - case RESTARTCONTAINER: - fprintf(stdout, "%s get type RESTARTCONTAINER\n", __func__); - if (hyper_restart_containers(pod) < 0) - return -1; - break; - - case EXECCMD: - if (hyper_container_execcmd(pod) < 0) - return -1; - break; - */ default: break; } @@ -147,17 +135,7 @@ static int hyper_handle_exit(struct hyper_pod *pod) fprintf(stdout, "pid %d exit by signal, status %d\n", pid, WTERMSIG(status)); } -/* - if (container) { - hyper_set_be32(data, pid); - if (hyper_send_msg(to, FINISHCMD, 5, data) < 0) { - fprintf(stderr, "pod signal_loop send finishcmd failed\n"); - return -1; - } - continue; - } -*/ if (hyper_send_exec_eof(ctl.tty.fd, pod, pid, data[4]) < 0) fprintf(stderr, "signal_loop send eof failed\n"); } @@ -387,15 +365,19 @@ static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len) return 0; } -int hyper_start_containers(struct hyper_pod *pod) +static int hyper_enter_container_pidns(void *data) { int i, pidns, ipcns, utsns, ret; struct hyper_container *c; + struct hyper_pod_arg *arg; + struct hyper_pod *pod; char path[64]; + arg = data; + pod = arg->pod; + ret = pidns = ipcns = utsns = -1; - fprintf(stdout, "%s\n", __func__); sprintf(path, "/proc/%d/ns/pid", pod->init_pid); pidns = open(path, O_RDONLY| O_CLOEXEC); if (pidns < 0) { @@ -403,6 +385,13 @@ int hyper_start_containers(struct hyper_pod *pod) goto out; } + /* enter pidns of pod init, so the children of this process will run in + * pidns of pod init, see man 2 setns */ + if (setns(pidns, CLONE_NEWPID) < 0) { + perror("enter pidns of pod init failed"); + goto out; + } + sprintf(path, "/proc/%d/ns/uts", pod->init_pid); utsns = open(path, O_RDONLY| O_CLOEXEC); if (utsns < 0) { @@ -420,7 +409,12 @@ int hyper_start_containers(struct hyper_pod *pod) for (i = 0; i < pod->c_num; i++) { c = &pod->c[i]; list_add_tail(&c->exec.list, &pod->exec_head); - hyper_start_container(c, pidns, utsns, ipcns); + hyper_start_container(c, utsns, ipcns); + } + + if (hyper_send_type(arg->ctl_pipe[1], READY) < 0) { + fprintf(stderr, "container init send ready message failed\n"); + goto out; } ret = 0; @@ -428,7 +422,56 @@ out: close(pidns); close(utsns); close(ipcns); + close(arg->ctl_pipe[0]); + close(arg->ctl_pipe[1]); + _exit(ret); +} + +int hyper_start_containers(struct hyper_pod *pod) +{ + int stacksize = getpagesize() * 4; + void *stack = malloc(stacksize); + struct hyper_pod_arg arg = { + .pod = pod, + .ctl_pipe = {-1, -1}, + }; + int ret = -1, pid; + uint32_t type; + + if (stack == NULL) { + perror("fail to allocate stack for container init"); + goto out; + } + + if (socketpair(PF_UNIX, SOCK_STREAM, 0, arg.ctl_pipe) < 0) { + perror("create pipe between hyper init and pod init failed"); + goto out; + } + + pid = clone(hyper_enter_container_pidns, stack + stacksize, CLONE_VM| CLONE_FILES, &arg); + free(stack); + if (pid < 0) { + perror("enter container pid ns failed"); + goto out; + } + + /* Wait for container start */ + if (hyper_get_type_block(arg.ctl_pipe[0], &type) < 0) { + perror("get enter_container_pidns ready message failed"); + goto out; + } + + if (type != READY) { + fprintf(stderr, "get incorrect enter_container_pidns message type %d, expect READY\n", + type); + goto out; + } + + ret = 0; +out: + close(arg.ctl_pipe[0]); + close(arg.ctl_pipe[1]); return ret; }