[CRIU] [PATCH] ensure SIGCHLD isn't inherited as blocked

Tycho Andersen tycho.andersen at canonical.com
Fri Jun 5 06:48:13 PDT 2015


Use SIG_SETMASK instead of SIG_BLOCKMASK here in case the parent had SIGCHLD
blocked. In this case if one of the criu threads has a problem, since the
SIGCHLD is blocked, the restore simply hangs.

Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
 cr-restore.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/cr-restore.c b/cr-restore.c
index aa00dc2..5a6347a 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1255,7 +1255,15 @@ static int criu_signals_setup(void)
 	 */
 	sigfillset(&blockmask);
 	sigdelset(&blockmask, SIGCHLD);
-	ret = sigprocmask(SIG_BLOCK, &blockmask, NULL);
+
+	/*
+	 * Here we use SIG_SETMASK instead of SIG_BLOCK to avoid the case where
+	 * we've been forked from a parent who had blocked SIGCHLD. If SIGCHLD
+	 * is blocked when a task dies (e.g. if the task fails to restore
+	 * somehow), we hang because our SIGCHLD handler is never run. Since we
+	 * depend on SIGCHLD being unblocked, let's set the mask explicitly.
+	 */
+	ret = sigprocmask(SIG_SETMASK, &blockmask, NULL);
 	if (ret < 0) {
 		pr_perror("Can't block signals");
 		return -1;
-- 
2.1.4



More information about the CRIU mailing list