[CRIU] [PATCH 2/3] compel: Improve infect

Cyrill Gorcunov gorcunov at openvz.org
Wed Nov 23 07:33:56 PST 2016


 - extend handle_sigchld
 - fix garbage return in compel_prepare
 - handle errors in make_sock_for

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 compel/src/lib/infect.c | 62 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 13 deletions(-)

diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index b88449efd876..de6ffbab7203 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -1019,31 +1019,46 @@ out:
  */
 static int make_sock_for(int pid)
 {
-	int ret = -1;
-	int mfd, fd;
+	int ret, mfd, fd, sk = -1;
 	char p[32];
 
+	pr_debug("Preparing seqsk for %d\n", pid);
+
 	sprintf(p, "/proc/%d/ns/net", pid);
 	fd = open(p, O_RDONLY);
-	if (fd < 0)
+	if (fd < 0) {
+		pr_perror("Can't open %p", p);
 		goto out;
+	}
 
 	mfd = open("/proc/self/ns/net", O_RDONLY);
-	if (mfd < 0)
+	if (mfd < 0) {
+		pr_perror("Can't open self netns");
 		goto out_c;
+	}
 
-	if (setns(fd, CLONE_NEWNET))
+	if (setns(fd, CLONE_NEWNET)) {
+		pr_perror("Can't setup target netns");
 		goto out_cm;
+	}
 
-	ret = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
+	sk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0);
+	if (sk < 0)
+		pr_perror("Can't create seqsk");
 
-	setns(mfd, CLONE_NEWNET);
+	ret = setns(mfd, CLONE_NEWNET);
+	if (ret) {
+		pr_perror("Can't restore former netns");
+		if (sk >= 0)
+			close(sk);
+		sk = -1;
+	}
 out_cm:
 	close(mfd);
 out_c:
 	close(fd);
 out:
-	return ret;
+	return sk;
 }
 
 static int simple_open_proc(int pid, int mode, const char *fmt, ...)
@@ -1063,10 +1078,25 @@ static int simple_open_proc(int pid, int mode, const char *fmt, ...)
 
 static void handle_sigchld(int signal, siginfo_t *siginfo, void *data)
 {
-	int status;
+	int pid, status;
+
+	pid = waitpid(-1, &status, WNOHANG);
+	if (pid <= 0)
+		return;
+
+	pr_err("si_code=%d si_pid=%d si_status=%d\n",
+		siginfo->si_code, siginfo->si_pid, siginfo->si_status);
 
-	waitpid(-1, &status, WNOHANG);
-	/* FIXME -- what to do here? */
+	if (WIFEXITED(status))
+		pr_err("%d exited with %d unexpectedly\n", pid, WEXITSTATUS(status));
+	else if (WIFSIGNALED(status))
+		pr_err("%d was killed by %d unexpectedly: %s\n",
+			pid, WTERMSIG(status), strsignal(WTERMSIG(status)));
+	else if (WIFSTOPPED(status))
+		pr_err("%d was stopped by %d unexpectedly\n", pid, WSTOPSIG(status));
+
+	/* FIXME Should we exit? */
+	/* exit(1); */
 }
 
 struct plain_regs_struct {
@@ -1135,6 +1165,10 @@ struct parasite_ctl *compel_prepare(int pid)
 	ictx->open_proc = simple_open_proc;
 	ictx->syscall_ip = find_executable_area(pid);
 	ictx->child_handler = handle_sigchld;
+	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);
 	sigaction(SIGCHLD, NULL, &ictx->orig_handler);
 
 	ictx->save_regs = save_regs_plain;
@@ -1145,6 +1179,7 @@ struct parasite_ctl *compel_prepare(int pid)
 
 	if (ictx->syscall_ip == (unsigned long)MAP_FAILED)
 		goto err;
+	pr_debug("Parasite syscall_ip at %#lx\n", ictx->syscall_ip);
 	ictx->sock = make_sock_for(pid);
 	if (ictx->sock < 0)
 		goto err;
@@ -1153,8 +1188,9 @@ out:
 	return ctl;
 
 err:
-	free(ictx->regs_arg);
-	free(ctl);
+	xfree(ictx->regs_arg);
+	xfree(ctl);
+	ctl = NULL;
 	goto out;
 }
 
-- 
2.7.4



More information about the CRIU mailing list