error_num seems to be trying to remember the exit code of the init process,
except that nothing actually keeps track of it anywhere. So, let's add a
field to the handler, so that we can keep track of the process' exit
status, and the propagate it to error_num in struct lxc_container so that
people can use it.
Note that this is a slight behavior change, essentially instead of making
error_num always == the return code from start, now it contains slightly
more useful information (the actual exit status). But, there is only one
internal user of error_num which I'll fix in later in the series, so IMO
this is ok.
Signed-off-by: Tycho Andersen <tycho@tycho.ws>
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");
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);
+ }
+ }
+
/* More robustness, protect ourself from a SIGCHLD sent
* by a process different from the container init.
*/
/* 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 {