From: Michel Normand Date: Mon, 18 May 2009 20:27:34 +0000 (+0200) Subject: lxc-start to report exit code of started application X-Git-Tag: lxc_0_6_3~85 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e043236e2a35948aeeb3cf85feab7c2f1e2b1fd1;p=thirdparty%2Flxc.git lxc-start to report exit code of started application The exit code of the application as reported by lxc-start is: 0-126 exit code of the application itself 128+n signal n received by the application 255 lxc error Signed-off-by: Michel Normand Signed-off-by: Daniel Lezcano --- diff --git a/src/lxc/error.c b/src/lxc/error.c index 153d89fcf..9a6634472 100644 --- a/src/lxc/error.c +++ b/src/lxc/error.c @@ -23,7 +23,11 @@ #include #include +#include #include "error.h" +#include "log.h" + +lxc_log_define(lxc_error, lxc); static const char *const catalogue[] = { @@ -67,3 +71,32 @@ const char *const lxc_strerror(int error) return catalogue[error]; } + +/*---------------------------------------------------------------------------*/ +/* lxc_error_set_and_log + * function is here to convert + * the reported status to an exit code as detailed here: + * + * 0-126 exit code of the application + * 128+n signal n received by the application + * 255 lxc error + */ +extern int lxc_error_set_and_log(int pid, int status) +{ + int ret = 0; + + if (WIFEXITED(status)) { + ret = WEXITSTATUS(status); + if (ret) + INFO("child <%d> ended on error (%d)", pid, ret); + } + + if (WIFSIGNALED(status)) { + int signal = WTERMSIG(status); + ret = ret + 128 + signal; + + INFO("child <%d> ended on signal (%d)", pid, signal); + } + + return ret; +} diff --git a/src/lxc/error.h b/src/lxc/error.h index 94c8071d2..3cbbb20ed 100644 --- a/src/lxc/error.h +++ b/src/lxc/error.h @@ -59,4 +59,5 @@ typedef enum { LXC_LAST_ERROR, } lxc_error_t; +extern int lxc_error_set_and_log(int pid, int status); #endif diff --git a/src/lxc/lxc_start.c b/src/lxc/lxc_start.c index 3f8741f56..cfdb17a37 100644 --- a/src/lxc/lxc_start.c +++ b/src/lxc/lxc_start.c @@ -61,7 +61,7 @@ Options :\n\ int main(int argc, char *argv[]) { char *const *args; - int err; + int err = -1; struct termios tios; char *const default_args[] = { @@ -69,9 +69,8 @@ int main(int argc, char *argv[]) '\0', }; - err = lxc_arguments_parse(&my_args, argc, argv); - if (err) - return 1; + if (lxc_arguments_parse(&my_args, argc, argv)) + return err; if (!my_args.argc) args = default_args; @@ -80,19 +79,15 @@ int main(int argc, char *argv[]) if (lxc_log_init(my_args.log_file, my_args.log_priority, my_args.progname, my_args.quiet)) - return 1; + return err; if (tcgetattr(0, &tios)) { ERROR("failed to get current terminal settings : %s", strerror(errno)); - return 1; + return err; } err = lxc_start(my_args.name, args); - if (err) { - ERROR("failed to start '%s'", my_args.name); - err = 1; - } if (tcsetattr(0, TCSAFLUSH, &tios)) ERROR("failed to restore terminal settings : %s", diff --git a/src/lxc/start.c b/src/lxc/start.c index 83aff9aba..392cdd1b2 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -439,7 +439,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { SYSERROR("failed to set sigprocmask"); - return -1; + goto out_child; } close(sv[1]); @@ -460,12 +460,9 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) } /* Setup the container, ip, names, utsname, ... */ - err = lxc_setup(name, handler->tty, &handler->tty_info); - if (err) { + if (lxc_setup(name, handler->tty, &handler->tty_info)) { ERROR("failed to setup the container"); - if (write(sv[0], &err, sizeof(err)) < 0) - SYSERROR("failed to write the socket"); - goto out_child; + goto out_warn_father; } if (prctl(PR_CAPBSET_DROP, CAP_SYS_BOOT, 0, 0, 0)) { @@ -476,11 +473,10 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) execvp(argv[0], argv); SYSERROR("failed to exec %s", argv[0]); - err = LXC_ERROR_WRONG_COMMAND; + out_warn_father: /* If the exec fails, tell that to our father */ if (write(sv[0], &err, sizeof(err)) < 0) SYSERROR("failed to write the socket"); - out_child: exit(err); } @@ -509,8 +505,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) } /* Wait for the child to exec or returning an error */ - err = read(sv[1], &sync, sizeof(sync)); - if (err < 0) { + if (read(sv[1], &sync, sizeof(sync)) < 0) { ERROR("failed to read the socket"); goto out_abort; } @@ -542,7 +537,7 @@ out_abort: int lxc_start(const char *name, char *const argv[]) { struct lxc_handler handler = { 0 }; - int err = -LXC_ERROR_INTERNAL; + int err = -1; int status; if (lxc_init(name, &handler)) { @@ -556,14 +551,16 @@ int lxc_start(const char *name, char *const argv[]) goto out; } - if (lxc_poll(name, &handler)) { + err = lxc_poll(name, &handler); + if (err) { ERROR("mainloop exited with an error"); goto out_abort; } while (waitpid(handler.pid, &status, 0) < 0 && errno == EINTR) continue; - err = 0; + + err = lxc_error_set_and_log(handler.pid, status); out: lxc_fini(name, &handler); return err;