If the process in the new namespace dies very early
we have currently no chance to detect this.
The parent process will just die due to SIGPIPE
if it write to the fd used for synchronisation and
nobody will notice the real cause of the problem.

Install a SIGCHLD handler to detect the death.
Later when the child does execve() to the init within
the new namespace the handler will be disabled automatically.

Signed-off-by: Richard Weinberger <rich...@nod.at>
---
 src/lxc/start.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/src/lxc/start.c b/src/lxc/start.c
index aefccd6..a58737a 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -198,6 +198,7 @@ static int setup_signal_fd(sigset_t *oldmask)
            sigdelset(&mask, SIGILL) ||
            sigdelset(&mask, SIGSEGV) ||
            sigdelset(&mask, SIGBUS) ||
+           sigdelset(&mask, SIGCHLD) ||
            sigprocmask(SIG_BLOCK, &mask, oldmask)) {
                SYSERROR("failed to set signal mask");
                return -1;
@@ -739,10 +740,29 @@ int save_phys_nics(struct lxc_conf *conf)
        return 0;
 }
 
+static void sigchild_handler(int sig)
+{
+       int status;
+       pid_t child;
+
+       child = wait(&status);
+       if (child < 0) {
+               SYSERROR("SIGCHLD caught but wait() failed: %m\n");
+               return;
+       }
+
+       if (WIFSIGNALED(status))
+               ERROR("Process in the new namespace died before execve()"
+                     " due to signal: %i", WTERMSIG(status));
+       else if (WIFEXITED(status))
+               ERROR("Process in the new namespace died before execve()"
+                     " with exit code: %i", WIFEXITED(status));
+}
 
 int lxc_spawn(struct lxc_handler *handler)
 {
        int failed_before_rename = 0;
+       struct sigaction act;
        const char *name = handler->name;
 
        if (lxc_sync_init(handler))
@@ -793,6 +813,14 @@ int lxc_spawn(struct lxc_handler *handler)
                goto out_delete_net;
        }
 
+       /*
+        * Install a SIGCHLD handler to detect the death of the new child 
between
+        * clone() and execve().
+        */
+       memset(&act, 0, sizeof(act));
+       act.sa_handler = sigchild_handler;
+       sigaction(SIGCHLD, &act, NULL);
+
        /* Create a process in a new set of namespaces */
        handler->pid = lxc_clone(do_start, handler, handler->clone_flags);
        if (handler->pid < 0) {
-- 
1.8.1.4


------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to