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)
if (WIFSIGNALED(status)) {
int signal = WTERMSIG(status);
INFO("Child <%d> ended on signal (%d)", pid, signal);
ret = 128 + signal;
}
return ret;
......
......@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
struct sigaction act;
struct lxc_log log;
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))
exit(EXIT_FAILURE);
......@@ -420,14 +420,14 @@ int main(int argc, char *argv[])
* pid) and continue to wait for the end of the orphan group.
*/
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;
}
}
out:
if (ret < 0)
exit(EXIT_FAILURE);
exit(ret);
exit(exit_with);
}
static void print_usage(const struct option longopts[])
......
......@@ -1027,7 +1027,7 @@ reboot:
ret = lxc_execute(c->name, argv, 1, handler, c->config_path, daemonize);
else
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) {
INFO("Container requested reboot");
......
......@@ -323,6 +323,36 @@ static int signal_handler(int fd, uint32_t events, void *data,
if (ret == 0 && info.si_pid == hdlr->pid)
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) {
kill(hdlr->pid, siginfo.ssi_signo);
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,
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);
return LXC_MAINLOOP_CLOSE;
}
......@@ -1802,7 +1824,7 @@ int __lxc_start(const char *name, struct lxc_handler *handler,
}
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:
lxc_delete_network(handler);
......
......@@ -109,6 +109,11 @@ struct lxc_handler {
/* Current state of the container. */
lxc_state_t state;
/* The exit status of the container; not defined unless ->init_died ==
* true.
*/
int exit_status;
};
struct lxc_operations {
......
......@@ -213,14 +213,20 @@ int main(int argc, char *argv[])
c->daemonize = my_args.daemonize == 1;
bret = c->start(c, 1, my_args.argv);
if (c->daemonize)
ret = EXIT_SUCCESS;
else
ret = c->error_num;
lxc_container_put(c);
if (!bret) {
fprintf(stderr, "Failed run an application inside container\n");
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