From 97099eb46ed9fd5210a0e6a7c79b6258df29d07b Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Wed, 20 Jul 2016 20:36:10 +0800 Subject: [PATCH 1/4] declare functions to static Signed-off-by: Lai Jiangshan --- src/exec.c | 17 ++++++++++------- src/exec.h | 8 -------- src/hyper.h | 1 - src/init.c | 2 +- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/exec.c b/src/exec.c index 15db093..03cc4d6 100644 --- a/src/exec.c +++ b/src/exec.c @@ -24,6 +24,9 @@ #include "parse.h" #include "syscall.h" +static int hyper_release_exec(struct hyper_exec *, struct hyper_pod *); +static void hyper_exec_process(struct hyper_exec *exec); + static int send_exec_finishing(uint64_t seq, int len, int code, int block) { struct hyper_buf *buf = &ctl.tty.wbuf; @@ -202,7 +205,7 @@ struct hyper_event_ops err_ops = { /* don't need write buff, the stderr data is one way */ }; -int hyper_setup_exec_user(struct hyper_exec *exec) +static int hyper_setup_exec_user(struct hyper_exec *exec) { char *user = exec->user == NULL || strlen(exec->user) == 0 ? NULL : exec->user; char *group = exec->group == NULL || strlen(exec->group) == 0 ? NULL : exec->group; @@ -333,7 +336,7 @@ static int hyper_setup_exec_notty(struct hyper_exec *e) return 0; } -int hyper_setup_exec_tty(struct hyper_exec *e) +static int hyper_setup_exec_tty(struct hyper_exec *e) { int unlock = 0; int ptymaster; @@ -410,7 +413,7 @@ int hyper_setup_exec_tty(struct hyper_exec *e) return 0; } -int hyper_dup_exec_tty(struct hyper_exec *e) +static int hyper_dup_exec_tty(struct hyper_exec *e) { int ret = -1; @@ -457,7 +460,7 @@ out: return ret; } -int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod) +static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod) { fprintf(stdout, "hyper_init_event container pts event %p, ops %p, fd %d\n", &exec->stdinev, &in_ops, exec->stdinev.fd); @@ -607,7 +610,7 @@ out: } // do the exec, no return -void hyper_exec_process(struct hyper_exec *exec) +static void hyper_exec_process(struct hyper_exec *exec) { if (sigprocmask(SIG_SETMASK, &orig_mask, NULL) < 0) { perror("sigprocmask restore mask failed"); @@ -773,8 +776,8 @@ out: return ret; } -int hyper_release_exec(struct hyper_exec *exec, - struct hyper_pod *pod) +static int hyper_release_exec(struct hyper_exec *exec, + struct hyper_pod *pod) { if (--exec->ref != 0) { fprintf(stdout, "still have %d user of exec\n", exec->ref); diff --git a/src/exec.h b/src/exec.h index 54e35cf..cd500ce 100644 --- a/src/exec.h +++ b/src/exec.h @@ -45,18 +45,10 @@ struct hyper_exec { struct hyper_pod; int hyper_exec_cmd(char *json, int length); -int hyper_release_exec(struct hyper_exec *, struct hyper_pod *); -int hyper_container_execcmd(struct hyper_pod *pod); -int hyper_setup_exec_tty(struct hyper_exec *e); -int hyper_dup_exec_tty(struct hyper_exec *e); int hyper_run_process(struct hyper_exec *e); -void hyper_exec_process(struct hyper_exec *e); struct hyper_exec *hyper_find_exec_by_pid(struct list_head *head, int pid); struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq); -int hyper_setup_exec_user(struct hyper_exec *e); int hyper_handle_exec_exit(struct hyper_pod *pod, int pid, uint8_t code); -int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod); void hyper_cleanup_exec(struct hyper_pod *pod); -extern struct hyper_event_ops pts_ops; #endif diff --git a/src/hyper.h b/src/hyper.h index f083db2..64bbbca 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -119,7 +119,6 @@ static inline int hyper_create(char *hyper_path) } int hyper_open_serial(char *tty); -int hyper_start_containers(struct hyper_pod *pod); void hyper_cleanup_pod(struct hyper_pod *pod); extern struct hyper_pod global_pod; diff --git a/src/init.c b/src/init.c index 954f3c9..60d5c93 100644 --- a/src/init.c +++ b/src/init.c @@ -275,7 +275,7 @@ fail: goto out; } -int hyper_start_containers(struct hyper_pod *pod) +static int hyper_start_containers(struct hyper_pod *pod) { struct hyper_container *c; From 0c05c999e370ed3ffd1bba9b2efed9c191dbb396 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Fri, 29 Jul 2016 13:07:42 +0800 Subject: [PATCH 2/4] remove tty from struct hyper_win_size Signed-off-by: Lai Jiangshan --- src/hyper.h | 1 - src/init.c | 37 +++++++------------------------------ src/parse.c | 20 ++++++-------------- 3 files changed, 13 insertions(+), 45 deletions(-) diff --git a/src/hyper.h b/src/hyper.h index 64bbbca..eb7b547 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -74,7 +74,6 @@ struct portmapping_white_list { }; struct hyper_win_size { - char *tty; int row; int column; uint64_t seq; diff --git a/src/init.c b/src/init.c index 60d5c93..f1c59f4 100644 --- a/src/init.c +++ b/src/init.c @@ -44,13 +44,10 @@ static int hyper_stop_pod(struct hyper_pod *pod); static int hyper_set_win_size(char *json, int length) { - struct hyper_win_size ws = { - .tty = NULL, - }; + struct hyper_win_size ws; struct winsize size; struct hyper_exec *exec; - char path[128]; - int fd, ret; + int ret; fprintf(stdout, "call hyper_win_size, json %s, len %d\n", json, length); if (hyper_parse_winsize(&ws, json, length) < 0) { @@ -58,39 +55,19 @@ static int hyper_set_win_size(char *json, int length) return -1; } - if (!ws.tty) { - exec = hyper_find_exec_by_seq(&global_pod, ws.seq); - if (exec == NULL) { - fprintf(stdout, "can not find exec whose seq is %" PRIu64"\n", ws.seq); - return 0; - } - - fprintf(stdout, "find exec %s, pid is %d, seq is %" PRIu64"\n", - exec->id ? exec->id : "pod", exec->pid, ws.seq); - fd = dup(exec->ptyfd); - } else { - if (sprintf(path, "/dev/%s", ws.tty) < 0) { - fprintf(stderr, "get tty device failed\n"); - return -1; - } - fd = hyper_open_serial_dev(path); - } - - if (fd < 0) { - perror("cannot open pty device to set term size"); - goto out; + exec = hyper_find_exec_by_seq(&global_pod, ws.seq); + if (exec == NULL) { + fprintf(stdout, "can not find exec whose seq is %" PRIu64"\n", ws.seq); + return 0; } size.ws_row = ws.row; size.ws_col = ws.column; - ret = ioctl(fd, TIOCSWINSZ, &size); + ret = ioctl(exec->ptyfd, TIOCSWINSZ, &size); if (ret < 0) perror("cannot ioctl to set pty device term size"); - close(fd); -out: - free(ws.tty); return ret; } diff --git a/src/parse.c b/src/parse.c index 0ea2b7e..379be60 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1292,28 +1292,24 @@ realloc: continue; if (i++ == n) - goto fail; + goto out; - if (json_token_streq(json, t, "tty")) { - if (toks[i].type != JSMN_STRING) - goto fail; - ws->tty = (json_token_str(json, &toks[i])); - } else if (json_token_streq(json, t, "seq")) { + if (json_token_streq(json, t, "seq")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->seq = json_token_ll(json, &toks[i]); } else if (json_token_streq(json, t, "row")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->row = json_token_int(json, &toks[i]); } else if (json_token_streq(json, t, "column")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->column = json_token_int(json, &toks[i]); } else { fprintf(stderr, "get unknown section %s in winsize\n", json_token_str(json, t)); - goto fail; + goto out; } } @@ -1321,10 +1317,6 @@ realloc: out: free(toks); return ret; -fail: - free(ws->tty); - ws->tty = NULL; - goto out; } struct hyper_exec *hyper_parse_execcmd(char *json, int length) From 74f6930073fe18272e6adf77a7967f9580fe1d0c Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 2 Aug 2016 11:06:47 +0800 Subject: [PATCH 3/4] add hyper_enter_sandbox() Signed-off-by: Lai Jiangshan --- src/exec.c | 90 ++++++----------------------------------------------- src/hyper.h | 1 + src/init.c | 57 +++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 80 deletions(-) diff --git a/src/exec.c b/src/exec.c index 03cc4d6..d2213a2 100644 --- a/src/exec.c +++ b/src/exec.c @@ -491,47 +491,27 @@ static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod) return 0; } -static int hyper_enter_container(struct hyper_pod *pod, - struct hyper_exec *exec) +static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe) { - int ipcns, utsns, mntns, ret; struct hyper_container *c; - char path[512]; - ret = ipcns = utsns = mntns = -1; + if (hyper_enter_sandbox(pod, pipe) < 0) { + perror("enter pidns of pod init failed"); + hyper_send_type(pipe, -1); + goto out; + } c = hyper_find_container(pod, exec->id); if (c == NULL) { fprintf(stderr, "can not find container %s\n", exec->id); - return -1; - } - - sprintf(path, "/proc/%d/ns/uts", pod->init_pid); - utsns = open(path, O_RDONLY| O_CLOEXEC); - if (utsns < 0) { - perror("fail to open utsns of pod init"); goto out; } - sprintf(path, "/proc/%d/ns/ipc", pod->init_pid); - ipcns = open(path, O_RDONLY| O_CLOEXEC); - if (ipcns < 0) { - perror("fail to open ipcns of pod init"); - goto out; - } - - mntns = c->ns; - if (mntns < 0) { - perror("fail to open mntns of pod init"); - goto out; - } - - if (setns(utsns, CLONE_NEWUTS) < 0 || - setns(ipcns, CLONE_NEWIPC) <0 || - setns(mntns, CLONE_NEWNS) < 0) { + if (setns(c->ns, CLONE_NEWNS) < 0) { perror("fail to enter container ns"); goto out; } + chdir("/"); /* TODO: merge container env to exec env in hyperd */ if (hyper_setup_env(c->exec.envs, c->exec.envs_num) < 0) { @@ -539,59 +519,12 @@ static int hyper_enter_container(struct hyper_pod *pod, goto out; } - /* TODO: wait for container finishing setup root */ - chdir("/"); - /* already in pidns & mntns of container, mount proc filesystem */ if (exec->init && mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0) { perror("fail to mount proc filesystem for container"); goto out; } - ret = 0; -out: - close(ipcns); - close(utsns); - - return ret; -} - -static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe) -{ - int pid = -1, ret = -1; - char path[512]; - int pidns; - - sprintf(path, "/proc/%d/ns/pid", pod->init_pid); - pidns = open(path, O_RDONLY| O_CLOEXEC); - if (pidns < 0) { - perror("fail to open pidns of pod init"); - 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; - } - close(pidns); - - pid = fork(); - if (pid < 0) { - perror("fail to fork"); - goto out; - } else if (pid > 0) { - fprintf(stdout, "create exec cmd %s pid %d,ref %d\n", exec->argv[0], pid, exec->ref); - ret = 0; - goto out; - } - - if (hyper_enter_container(pod, exec) < 0) { - fprintf(stderr, "enter container ns failed\n"); - goto exit; - } - // set early env. the container env config can overwrite it setenv("HOME", "/root", 1); setenv("HOSTNAME", pod->hostname, 1); @@ -602,11 +535,8 @@ static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int hyper_exec_process(exec); -exit: - _exit(125); out: - hyper_send_type(pipe, pid); - _exit(ret); + _exit(125); } // do the exec, no return @@ -627,7 +557,7 @@ static void hyper_exec_process(struct hyper_exec *exec) goto exit; } - // set the container env + // set the process env if (hyper_setup_env(exec->envs, exec->envs_num) < 0) { fprintf(stderr, "setup env failed\n"); goto exit; diff --git a/src/hyper.h b/src/hyper.h index eb7b547..2e09966 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -119,6 +119,7 @@ static inline int hyper_create(char *hyper_path) int hyper_open_serial(char *tty); void hyper_cleanup_pod(struct hyper_pod *pod); +int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe); extern struct hyper_pod global_pod; extern struct hyper_ctl ctl; diff --git a/src/init.c b/src/init.c index f1c59f4..61bfe5c 100644 --- a/src/init.c +++ b/src/init.c @@ -326,6 +326,63 @@ out: return ret; } +// enter the sanbox and pass to the child, shouldn't call from the init process +int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe) +{ + int ret = -1, pidns = -1, utsns = -1, ipcns = -1; + char path[512]; + + sprintf(path, "/proc/%d/ns/pid", pod->init_pid); + pidns = open(path, O_RDONLY| O_CLOEXEC); + if (pidns < 0) { + perror("fail to open pidns of pod init"); + goto out; + } + + sprintf(path, "/proc/%d/ns/uts", pod->init_pid); + utsns = open(path, O_RDONLY| O_CLOEXEC); + if (utsns < 0) { + perror("fail to open utsns of pod init"); + goto out; + } + + sprintf(path, "/proc/%d/ns/ipc", pod->init_pid); + ipcns = open(path, O_RDONLY| O_CLOEXEC); + if (ipcns < 0) { + perror("fail to open ipcns of pod init"); + goto out; + } + + if (setns(pidns, CLONE_NEWPID) < 0 || + setns(utsns, CLONE_NEWUTS) < 0 || + setns(ipcns, CLONE_NEWIPC) < 0) { + perror("fail to enter the sandbox"); + goto out; + } + + /* current process isn't in the pidns even setns(pidns, CLONE_NEWPID) + * was called. fork() is needed, so that the child process will run in + * the pidns, see man 2 setns */ + ret = fork(); + if (ret < 0) { + perror("fail to fork"); + goto out; + } else if (ret > 0) { + fprintf(stdout, "create child process pid=%d in the sandbox\n", ret); + if (pidpipe > 0) { + hyper_send_type(pidpipe, ret); + } + _exit(0); + } + +out: + close(pidns); + close(ipcns); + close(utsns); + + return ret; +} + #ifdef WITH_VBOX #define MAX_HOST_NAME 256 From bf61d6306eba8d6e011961a0e3eb927d193d72b8 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Tue, 2 Aug 2016 11:15:26 +0800 Subject: [PATCH 4/4] enter the sandbox when hyper_setup_container_rootfs() Signed-off-by: Lai Jiangshan --- src/container.c | 9 +++++++-- src/exec.c | 7 ------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/container.c b/src/container.c index d66dc9c..02e6283 100644 --- a/src/container.c +++ b/src/container.c @@ -269,8 +269,8 @@ static int container_setup_mount(struct hyper_container *container) hyper_mkdir("./dev", 0755); hyper_mkdir("./lib/modules", 0755); - // mount proc filesystem when the container init process running in the pidns of podinit - if (mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 || + if (mount("proc", "./proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 || + mount("sysfs", "./sys", "sysfs", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0 || mount("devtmpfs", "./dev", "devtmpfs", MS_NOSUID, NULL) < 0) { perror("mount basic filesystem for container failed"); return -1; @@ -512,6 +512,11 @@ static int hyper_setup_container_rootfs(void *data) int setup_dns; uint32_t type; + if (hyper_enter_sandbox(arg->pod, -1) < 0) { + perror("enter sandbox failed"); + goto fail; + } + if (hyper_rescan_scsi() < 0) { fprintf(stdout, "rescan scsi failed\n"); goto fail; diff --git a/src/exec.c b/src/exec.c index d2213a2..0f13e0b 100644 --- a/src/exec.c +++ b/src/exec.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -519,12 +518,6 @@ static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int goto out; } - /* already in pidns & mntns of container, mount proc filesystem */ - if (exec->init && mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0) { - perror("fail to mount proc filesystem for container"); - goto out; - } - // set early env. the container env config can overwrite it setenv("HOME", "/root", 1); setenv("HOSTNAME", pod->hostname, 1);