If lxc-init receives a SIGALRM, a timeout, it kills all the processes
of the container with SIGKILL. That will prevent the container to be
stuck when one process ignore the SIGTERM signal.

Each time a process exits, the timeout is resetted.

Signed-off-by: Daniel Lezcano <dlezc...@fr.ibm.com>
---
 src/lxc/lxc_init.c |   36 +++++++++++++++++++++++++++++++-----
 1 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c
index d91a3a1..5c264c6 100644
--- a/src/lxc/lxc_init.c
+++ b/src/lxc/lxc_init.c
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
        int err = -1;
        char **aargv;
        sigset_t mask, omask;
-       int i;
+       int i, shutdown = 0;
 
        while (1) {
                int ret = getopt_long_only(argc, argv, "", options, NULL);
@@ -106,6 +106,10 @@ int main(int argc, char *argv[])
        aargv = &argv[optind];
        argc -= nbargs;
 
+        /*
+        * mask all the signals so we are safe to install a
+        * signal handler and to fork
+        */
        sigfillset(&mask);
        sigprocmask(SIG_SETMASK, &mask, &omask);
 
@@ -113,6 +117,9 @@ int main(int argc, char *argv[])
                struct sigaction act;
 
                sigfillset(&act.sa_mask);
+               sigdelset(&mask, SIGILL);
+               sigdelset(&mask, SIGSEGV);
+               sigdelset(&mask, SIGBUS);
                act.sa_flags = 0;
                act.sa_handler = interrupt_handler;
                sigaction(i, &act, NULL);
@@ -131,8 +138,10 @@ int main(int argc, char *argv[])
 
        if (!pid) {
 
+               /* restore default signal handlers */
                for (i = 1; i < NSIG; i++)
                        signal(i, SIG_DFL);
+
                sigprocmask(SIG_SETMASK, &omask, NULL);
 
                NOTICE("about to exec '%s'", aargv[0]);
@@ -142,6 +151,8 @@ int main(int argc, char *argv[])
                exit(err);
        }
 
+       /* let's process the signals now */
+       sigdelset(&omask, SIGALRM);
        sigprocmask(SIG_SETMASK, &omask, NULL);
 
        /* no need of other inherited fds but stderr */
@@ -160,7 +171,15 @@ int main(int argc, char *argv[])
                        break;
 
                case SIGTERM:
-                       kill(-1, SIGTERM);
+                       if (!shutdown) {
+                               shutdown = 1;
+                               kill(-1, SIGTERM);
+                               alarm(1);
+                       }
+                       break;
+
+               case SIGALRM:
+                       kill(-1, SIGKILL);
                        break;
 
                default:
@@ -175,13 +194,20 @@ int main(int argc, char *argv[])
                                goto out;
                        if (errno == EINTR)
                                continue;
-                       ERROR("failed to wait child : %s", strerror(errno));
+
+                       ERROR("failed to wait child : %s",
+                             strerror(errno));
                        goto out;
                }
 
+               /* reset timer each time a process exited */
+               if (shutdown)
+                       alarm(1);
+
                /*
-                * keep the exit code of started application (not wrapped pid)
-                * and continue to wait for the end of the orphan group.
+                * keep the exit code of started application
+                * (not wrapped pid) and continue to wait for
+                * the end of the orphan group.
                 */
                if ((waited_pid != pid) || (orphan ==1))
                        continue;
-- 
1.7.0.4


------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to