[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