[lxc-devel] [patch -lxc 4/4] lxc-init finishes the remaining processes with SIGKILL
Daniel Lezcano
dlezcano at fr.ibm.com
Thu Jul 15 21:08:18 UTC 2010
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 <dlezcano at 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
More information about the lxc-devel
mailing list