]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
remember the exit code from the init process
authorTycho Andersen <tycho@tycho.ws>
Fri, 19 Jan 2018 03:24:59 +0000 (03:24 +0000)
committerTycho Andersen <tycho@tycho.ws>
Fri, 19 Jan 2018 03:44:24 +0000 (03:44 +0000)
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>
src/lxc/lxccontainer.c
src/lxc/start.c
src/lxc/start.h

index 2a4bb51f34466a42bd8b5c0c18a1201d6ce71f62..f6f07bac13cded3ee068aa908facf083759b0cde 100644 (file)
@@ -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");
index 8b41442394f04a7f267550eea7946f80cf11544e..00e255a691f3bab113dd3f07d5f288a450496316 100644 (file)
@@ -323,6 +323,27 @@ 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);
+               }
+       }
+
        /* More robustness, protect ourself from a SIGCHLD sent
         * by a process different from the container init.
         */
index 50315404560ed8c00b3aa419ab0a9fb26919a7de..f2a2630e39eab506ab4a98a45fbc8e6051f9a381 100644 (file)
@@ -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 {