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