From 6f0a42008dab87e1c97bc71319c793315f87a328 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Tue, 13 Jul 2010 14:51:45 +0200 Subject: [PATCH] lxc-init finishes the remaining processes with SIGKILL 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 --- src/lxc/lxc_init.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/lxc/lxc_init.c b/src/lxc/lxc_init.c index d91a3a10d..5c264c65d 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; -- 2.39.5