From 9615c24fcaf14b97c8b557767efeda52461af216 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Tue, 17 May 2016 15:33:01 +0800 Subject: [PATCH 1/2] reagrd exec/start-container success after fork/clone success If fork/clone failed, return ERROR message to outside. otherwise ragard exec/start-container success, add container/exec to exec list, waitpid in init will get the exec status. Signed-off-by: Gao feng --- src/container.c | 28 +++------------------------- src/exec.c | 32 ++++---------------------------- src/exec.h | 2 +- 3 files changed, 8 insertions(+), 54 deletions(-) diff --git a/src/container.c b/src/container.c index a56f969..6a1dd62 100644 --- a/src/container.c +++ b/src/container.c @@ -402,9 +402,9 @@ static int container_setup_workdir(struct hyper_container *container) return 0; } -static int container_setup_tty(int fd, struct hyper_container *container) +static int container_setup_tty(struct hyper_container *container) { - return hyper_dup_exec_tty(fd, &container->exec); + return hyper_dup_exec_tty(&container->exec); } static int hyper_rescan_scsi(void) @@ -457,7 +457,6 @@ struct hyper_container_arg { struct hyper_pod *pod; int ipcns; int utsns; - int pipe[2]; }; static int hyper_container_init(void *data) @@ -617,7 +616,7 @@ static int hyper_container_init(void *data) fflush(stdout); - if (container_setup_tty(arg->pipe[1], container) < 0) { + if (container_setup_tty(container) < 0) { fprintf(stdout, "setup tty failed\n"); goto fail; } @@ -625,10 +624,7 @@ static int hyper_container_init(void *data) execvp(container->exec.argv[0], container->exec.argv); perror("exec container command failed"); - _exit(-1); - fail: - hyper_send_type(arg->pipe[1], ERROR); _exit(-1); } @@ -666,11 +662,9 @@ int hyper_start_container(struct hyper_container *container, .pod = pod, .utsns = utsns, .ipcns = ipcns, - .pipe = {-1, -1}, }; int flags = CLONE_NEWNS | SIGCHLD; char path[128]; - uint32_t type; void *stack; int pid; @@ -685,11 +679,6 @@ int hyper_start_container(struct hyper_container *container, goto fail; } - if (pipe2(arg.pipe, O_CLOEXEC) < 0) { - perror("create pipe between pod init execcmd failed"); - goto fail; - } - if (hyper_watch_exec_pty(&container->exec, pod) < 0) { fprintf(stderr, "faile to watch container pty\n"); goto fail; @@ -715,24 +704,13 @@ int hyper_start_container(struct hyper_container *container, goto fail; } - /* wait for ready message */ - if (hyper_get_type(arg.pipe[0], &type) < 0 || type != READY) { - fprintf(stderr, "wait for container started failed\n"); - goto fail; - } - container->exec.pid = pid; list_add_tail(&container->exec.list, &pod->exec_head); container->exec.ref++; - close(arg.pipe[0]); - close(arg.pipe[1]); - fprintf(stdout, "container %s,init pid %d,ref %d\n", container->id, pid, container->exec.ref); return 0; fail: - close(arg.pipe[0]); - close(arg.pipe[1]); close(container->ns); hyper_reset_event(&container->exec.stdinev); hyper_reset_event(&container->exec.stdoutev); diff --git a/src/exec.c b/src/exec.c index 97cfda4..1ad68e8 100644 --- a/src/exec.c +++ b/src/exec.c @@ -390,7 +390,7 @@ int hyper_setup_exec_tty(struct hyper_exec *e) return 0; } -int hyper_dup_exec_tty(int to, struct hyper_exec *e) +int hyper_dup_exec_tty(struct hyper_exec *e) { int ret = -1; @@ -416,7 +416,6 @@ int hyper_dup_exec_tty(int to, struct hyper_exec *e) } fflush(stdout); - hyper_send_type(to, READY); if (dup2(e->stdinfd, STDIN_FILENO) < 0) { perror("dup tty device to stdin failed"); @@ -535,8 +534,7 @@ static int hyper_do_exec_cmd(void *data) struct hyper_exec_arg *arg = data; struct hyper_exec *exec = arg->exec; struct hyper_pod *pod = arg->pod; - int pipe[2] = {-1, -1}, pid; - int ret = -1; + int pid, ret = -1; if (exec->id) { char path[512]; @@ -558,11 +556,6 @@ static int hyper_do_exec_cmd(void *data) close(pidns); } - if (pipe2(pipe, O_CLOEXEC) < 0) { - perror("create pipe in exec command failed"); - goto out; - } - if (hyper_watch_exec_pty(exec, pod) < 0) { fprintf(stderr, "add pts master event failed\n"); goto out; @@ -573,14 +566,6 @@ static int hyper_do_exec_cmd(void *data) perror("fail to fork"); goto out; } else if (pid > 0) { - uint32_t type; - - if (hyper_get_type(pipe[0], &type) < 0 || type != READY) { - fprintf(stderr, "hyper init doesn't get execcmd ready message\n"); - goto out; - } - - fprintf(stdout, "hyper init get ready message\n"); exec->pid = pid; //TODO combin ref++ and add to list. list_add_tail(&exec->list, &pod->exec_head); @@ -600,25 +585,16 @@ static int hyper_do_exec_cmd(void *data) goto exit; } - if (hyper_dup_exec_tty(pipe[1], exec) < 0) { + if (hyper_dup_exec_tty(exec) < 0) { fprintf(stderr, "dup pts to exec stdio failed\n"); goto exit; } - if (execvp(exec->argv[0], exec->argv) < 0) { + if (execvp(exec->argv[0], exec->argv) < 0) perror("exec failed"); - goto exit; - } - - ret = 0; exit: - close(pipe[0]); - close(pipe[1]); - hyper_send_type(pipe[1], ERROR); _exit(ret); out: - close(pipe[0]); - close(pipe[1]); hyper_send_type(arg->pipe[1], ret ? ERROR : READY); _exit(ret); } diff --git a/src/exec.h b/src/exec.h index 3bb7b08..589668a 100644 --- a/src/exec.h +++ b/src/exec.h @@ -48,7 +48,7 @@ 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(int fd, struct hyper_exec *e); +int hyper_dup_exec_tty(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); From d74aaa326dc4ff0f3f99d74421653fdfb10a31a2 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 May 2016 19:14:47 +0800 Subject: [PATCH 2/2] make exit code of exec/container consist with docker The exit code from `docker run` gives information about why the container failed to run or why it exited. When `docker run` exits with a non-zero code, the exit codes follow the `chroot` standard, see below: **_125_** if the error is with Docker daemon **_itself_** $ docker run --foo busybox; echo $? # flag provided but not defined: --foo See 'docker run --help'. 125 **_126_** if the **_contained command_** cannot be invoked $ docker run busybox /etc; echo $? # docker: Error response from daemon: Container command '/etc' could not be invoked. 126 **_127_** if the **_contained command_** cannot be found $ docker run busybox foo; echo $? # docker: Error response from daemon: Container command 'foo' not found or does not exist. 127 **_Exit code_** of **_contained command_** otherwise $ docker run busybox /bin/sh -c 'exit 3'; echo $? # 3 Signed-off-by: Gao feng --- src/container.c | 9 ++++++++- src/exec.c | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/container.c b/src/container.c index 6a1dd62..99b671c 100644 --- a/src/container.c +++ b/src/container.c @@ -624,8 +624,15 @@ static int hyper_container_init(void *data) execvp(container->exec.argv[0], container->exec.argv); perror("exec container command failed"); + /* the exit codes follow the `chroot` standard, + see docker/docs/reference/run.md#exit-status */ + if (errno == ENOENT) + _exit(127); + else if (errno == EACCES) + _exit(126); + fail: - _exit(-1); + _exit(125); } static int hyper_setup_pty(struct hyper_container *c) diff --git a/src/exec.c b/src/exec.c index 1ad68e8..2c0f121 100644 --- a/src/exec.c +++ b/src/exec.c @@ -590,10 +590,20 @@ static int hyper_do_exec_cmd(void *data) goto exit; } - if (execvp(exec->argv[0], exec->argv) < 0) + if (execvp(exec->argv[0], exec->argv) < 0) { perror("exec failed"); + + /* the exit codes follow the `chroot` standard, + see docker/docs/reference/run.md#exit-status */ + if (errno == ENOENT) + exit(127); + else if (errno == EACCES) + exit(126); + + } + exit: - _exit(ret); + _exit(125); out: hyper_send_type(arg->pipe[1], ret ? ERROR : READY); _exit(ret);