Unverified Commit 2c3a005d by Serge Hallyn Committed by GitHub

Merge pull request #2094 from tych0/propagate-exit-code

Propagate exit code for app containers
parents dc4f8fb1 55e1311e
...@@ -52,6 +52,7 @@ extern int lxc_error_set_and_log(int pid, int status) ...@@ -52,6 +52,7 @@ extern int lxc_error_set_and_log(int pid, int status)
if (WIFSIGNALED(status)) { if (WIFSIGNALED(status)) {
int signal = WTERMSIG(status); int signal = WTERMSIG(status);
INFO("Child <%d> ended on signal (%d)", pid, signal); INFO("Child <%d> ended on signal (%d)", pid, signal);
ret = 128 + signal;
} }
return ret; return ret;
......
...@@ -202,7 +202,7 @@ int main(int argc, char *argv[]) ...@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
struct sigaction act; struct sigaction act;
struct lxc_log log; struct lxc_log log;
sigset_t mask, omask; sigset_t mask, omask;
int have_status = 0, shutdown = 0; int have_status = 0, exit_with = 1, shutdown = 0;
if (arguments_parse(&my_args, argc, argv)) if (arguments_parse(&my_args, argc, argv))
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -420,14 +420,14 @@ int main(int argc, char *argv[]) ...@@ -420,14 +420,14 @@ int main(int argc, char *argv[])
* pid) and continue to wait for the end of the orphan group. * pid) and continue to wait for the end of the orphan group.
*/ */
if (waited_pid == pid && !have_status) { if (waited_pid == pid && !have_status) {
ret = lxc_error_set_and_log(waited_pid, status); exit_with = lxc_error_set_and_log(waited_pid, status);
have_status = 1; have_status = 1;
} }
} }
out: out:
if (ret < 0) if (ret < 0)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
exit(ret); exit(exit_with);
} }
static void print_usage(const struct option longopts[]) static void print_usage(const struct option longopts[])
......
...@@ -1027,7 +1027,7 @@ reboot: ...@@ -1027,7 +1027,7 @@ reboot:
ret = lxc_execute(c->name, argv, 1, handler, c->config_path, daemonize); ret = lxc_execute(c->name, argv, 1, handler, c->config_path, daemonize);
else else
ret = lxc_start(c->name, argv, handler, c->config_path, daemonize); ret = lxc_start(c->name, argv, handler, c->config_path, daemonize);
c->error_num = ret; c->error_num = handler->exit_status;
if (conf->reboot == 1) { if (conf->reboot == 1) {
INFO("Container requested reboot"); INFO("Container requested reboot");
......
...@@ -323,6 +323,36 @@ static int signal_handler(int fd, uint32_t events, void *data, ...@@ -323,6 +323,36 @@ static int signal_handler(int fd, uint32_t events, void *data,
if (ret == 0 && info.si_pid == hdlr->pid) if (ret == 0 && info.si_pid == hdlr->pid)
hdlr->init_died = true; hdlr->init_died = true;
/* Try to figure out a reasonable exit status to report. */
if (hdlr->init_died) {
switch (info.si_code) {
case CLD_EXITED:
hdlr->exit_status = info.si_status << 8;
break;
case CLD_KILLED:
case CLD_DUMPED:
case CLD_STOPPED:
hdlr->exit_status = info.si_status << 8 | 0x7f;
break;
case CLD_CONTINUED:
/* Huh? The waitid() told us it's dead *and* continued? */
WARN("Init %d dead and continued?", hdlr->pid);
hdlr->exit_status = 1;
break;
default:
ERROR("Unknown si_code: %d", hdlr->init_died);
hdlr->exit_status = 1;
}
}
/* More robustness, protect ourself from a SIGCHLD sent
* by a process different from the container init.
*/
if (siginfo.ssi_pid != hdlr->pid) {
NOTICE("Received %d from pid %d instead of container init %d.", siginfo.ssi_signo, siginfo.ssi_pid, hdlr->pid);
return hdlr->init_died ? LXC_MAINLOOP_CLOSE : 0;
}
if (siginfo.ssi_signo != SIGCHLD) { if (siginfo.ssi_signo != SIGCHLD) {
kill(hdlr->pid, siginfo.ssi_signo); kill(hdlr->pid, siginfo.ssi_signo);
INFO("Forwarded signal %d to pid %d.", siginfo.ssi_signo, hdlr->pid); INFO("Forwarded signal %d to pid %d.", siginfo.ssi_signo, hdlr->pid);
...@@ -337,14 +367,6 @@ static int signal_handler(int fd, uint32_t events, void *data, ...@@ -337,14 +367,6 @@ static int signal_handler(int fd, uint32_t events, void *data,
return hdlr->init_died ? LXC_MAINLOOP_CLOSE : 0; return hdlr->init_died ? LXC_MAINLOOP_CLOSE : 0;
} }
/* More robustness, protect ourself from a SIGCHLD sent
* by a process different from the container init.
*/
if (siginfo.ssi_pid != hdlr->pid) {
NOTICE("Received SIGCHLD from pid %d instead of container init %d.", siginfo.ssi_pid, hdlr->pid);
return hdlr->init_died ? LXC_MAINLOOP_CLOSE : 0;
}
DEBUG("Container init process %d exited.", hdlr->pid); DEBUG("Container init process %d exited.", hdlr->pid);
return LXC_MAINLOOP_CLOSE; return LXC_MAINLOOP_CLOSE;
} }
...@@ -1802,7 +1824,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler, ...@@ -1802,7 +1824,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
} }
lxc_monitor_send_exit_code(name, status, handler->lxcpath); lxc_monitor_send_exit_code(name, status, handler->lxcpath);
err = lxc_error_set_and_log(handler->pid, status); lxc_error_set_and_log(handler->pid, status);
out_fini: out_fini:
lxc_delete_network(handler); lxc_delete_network(handler);
......
...@@ -109,6 +109,11 @@ struct lxc_handler { ...@@ -109,6 +109,11 @@ struct lxc_handler {
/* Current state of the container. */ /* Current state of the container. */
lxc_state_t state; lxc_state_t state;
/* The exit status of the container; not defined unless ->init_died ==
* true.
*/
int exit_status;
}; };
struct lxc_operations { struct lxc_operations {
......
...@@ -213,14 +213,20 @@ int main(int argc, char *argv[]) ...@@ -213,14 +213,20 @@ int main(int argc, char *argv[])
c->daemonize = my_args.daemonize == 1; c->daemonize = my_args.daemonize == 1;
bret = c->start(c, 1, my_args.argv); bret = c->start(c, 1, my_args.argv);
if (c->daemonize)
ret = EXIT_SUCCESS;
else
ret = c->error_num;
lxc_container_put(c); lxc_container_put(c);
if (!bret) { if (!bret) {
fprintf(stderr, "Failed run an application inside container\n"); fprintf(stderr, "Failed run an application inside container\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
exit(ret); if (c->daemonize)
exit(EXIT_SUCCESS);
else {
if (WIFEXITED(c->error_num)) {
exit(WEXITSTATUS(c->error_num));
} else {
/* Try to die with the same signal the task did. */
kill(0, WTERMSIG(c->error_num));
exit(EXIT_FAILURE);
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment