[CRIU] [PATCH 5/8] compel: Handle sigchilds in compel

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 21 10:26:17 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

CRIU sets up a child hander to get errors from tasks it
infects. For compel we'd have the same problem, so there's
a way to request for custom child handler, but compel
should provide some default by himself. And it's not clear
atm how this should look like, so here's a plain stub to
move forward.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 compel/include/uapi/infect.h |  1 +
 compel/src/lib/infect.c      | 24 ++++++++++++++----------
 criu/parasite-syscall.c      |  4 ++++
 3 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index a17fd2efc6b8..8f49ae12b3ac 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -111,6 +111,7 @@ struct infect_ctx {
 	unsigned long		flags;			/* fine-tune (e.g. faults) */
 
 	void (*child_handler)(int, siginfo_t *, void *);	/* hander for SIGCHLD deaths */
+	struct sigaction	orig_handler;
 
 	open_proc_fn open_proc;
 
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index 20688af265ba..a8d3158c34c6 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -386,16 +386,9 @@ static int setup_child_handler(struct parasite_ctl *ctl)
 	return 0;
 }
 
-static int restore_child_handler()
+static int restore_child_handler(struct parasite_ctl *ctl)
 {
-	struct sigaction sa = {
-		.sa_handler	= SIG_DFL, /* XXX -- should be original? */
-		.sa_flags	= SA_SIGINFO | SA_RESTART,
-	};
-
-	sigemptyset(&sa.sa_mask);
-	sigaddset(&sa.sa_mask, SIGCHLD);
-	if (sigaction(SIGCHLD, &sa, NULL)) {
+	if (sigaction(SIGCHLD, &ctl->ictx.orig_handler, NULL)) {
 		pr_perror("Unable to setup SIGCHLD handler");
 		return -1;
 	}
@@ -1009,6 +1002,14 @@ static int simple_open_proc(int pid, int mode, const char *fmt, ...)
 	return open(path, mode);
 }
 
+static void handle_sigchld(int signal, siginfo_t *siginfo, void *data)
+{
+	int status;
+
+	waitpid(-1, &status, WNOHANG);
+	/* FIXME -- what to do here? */
+}
+
 struct parasite_ctl *compel_prepare(int pid)
 {
 	struct parasite_ctl *ctl;
@@ -1022,6 +1023,9 @@ struct parasite_ctl *compel_prepare(int pid)
 	ictx->task_size = task_size();
 	ictx->open_proc = simple_open_proc;
 	ictx->syscall_ip = find_executable_area(pid);
+	ictx->child_handler = handle_sigchld;
+	sigaction(SIGCHLD, NULL, &ictx->orig_handler);
+
 	if (ictx->syscall_ip == (unsigned long)MAP_FAILED)
 		goto err;
 	ictx->sock = make_sock_for(pid);
@@ -1051,7 +1055,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
 	enum trace_flags flag;
 
 	/* stop getting chld from parasite -- we're about to step-by-step it */
-	if (restore_child_handler())
+	if (restore_child_handler(ctl))
 		return -1;
 
 	/* Start to trace syscalls for each thread */
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index f4312ed45f6a..8984d7054890 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -581,6 +581,10 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 
 	ictx->open_proc = do_open_proc;
 	ictx->child_handler = sigchld_handler;
+	ictx->orig_handler.sa_handler = SIG_DFL;
+	ictx->orig_handler.sa_flags = SA_SIGINFO | SA_RESTART;
+	sigemptyset(&ictx->orig_handler.sa_mask);
+	sigaddset(&ictx->orig_handler.sa_mask, SIGCHLD);
 	ictx->sock = dmpi(item)->netns->net.seqsk;
 	ictx->save_regs = save_task_regs;
 	ictx->make_sigframe = make_sigframe;
-- 
2.7.4



More information about the CRIU mailing list