]> 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)
committerChristian Brauner <christian.brauner@ubuntu.com>
Fri, 19 Jan 2018 14:19:56 +0000 (15:19 +0100)
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 dd442a8167e3880ef255f658127382c6f621597a..de996acb5b2e68ca3eba3241fea5058c1b98d1d9 100644 (file)
@@ -994,7 +994,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 e23467f486a2be6554fc63e89bcde31bfe8cbf1e..3426351587e67a0edd13a9fc97bdf77ff1836ccf 100644 (file)
@@ -314,6 +314,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 8658d26e41dbdc61bcfc6950fc5fbff69d34dd41..cbcdf2f2ac24a97375ec8a1951deae8c3ade3ca4 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 {