[CRIU] [PATCH] [v2] compel: check whether a parasite socket is prepared each time

Andrei Vagin avagin at openvz.org
Thu Nov 17 17:23:41 PST 2016


From: Andrei Vagin <avagin at virtuozzo.com>

Currently we prepare a parasite socket only once and
save it in a static variable.

It's bad idea to use a static variable in a library.

In addition, it doesn't work if we have processes in
different network namespaces. In this case, we have to have
a separate socket for each namespace.

v2: fix compilation on Alpine
    convert *p_sock into sock

Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 compel/include/uapi/infect.h |  2 +-
 compel/src/lib/infect.c      | 21 ++++++++++++++-------
 criu/parasite-syscall.c      |  2 +-
 3 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index 75fc4a7..adc40f2 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -96,7 +96,7 @@ typedef int (*open_proc_fn)(int pid, int mode, const char *fmt, ...)
 	__attribute__ ((__format__ (__printf__, 3, 4)));
 
 struct infect_ctx {
-	int	*p_sock;
+	int	sock;
 
 	/*
 	 * Regs manipulation context.
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index 0d462d8..f0119de 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -322,20 +322,27 @@ static int gen_parasite_saddr(struct sockaddr_un *saddr, int key)
 static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid,
 		struct parasite_init_args *args)
 {
-	static int ssock = -1;
+	int ssock = -1;
+	socklen_t sk_len;
+	struct sockaddr_un addr;
 
 	pr_info("Putting tsock into pid %d\n", pid);
 	args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid());
 
+	ssock = ctl->ictx.sock;
+	sk_len = sizeof(addr);
+
 	if (ssock == -1) {
-		ssock = *ctl->ictx.p_sock;
-		if (ssock == -1) {
-			pr_err("No socket in ictx\n");
-			goto err;
-		}
+		pr_err("No socket in ictx\n");
+		goto err;
+	}
 
-		*ctl->ictx.p_sock = -1;
+	if (getsockname(ssock, (struct sockaddr *) &addr, &sk_len) < 0) {
+		pr_perror("Unable to get name for a socket");
+		return -1;
+	}
 
+	if (sk_len == sizeof(addr.sun_family)) {
 		if (bind(ssock, (struct sockaddr *)&args->h_addr, args->h_addr_len) < 0) {
 			pr_perror("Can't bind socket");
 			goto err;
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 37c0e16..d44eced 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -581,7 +581,7 @@ 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->p_sock = &dmpi(item)->netns->net.seqsk;
+	ictx->sock = dmpi(item)->netns->net.seqsk;
 	ictx->save_regs = save_task_regs;
 	ictx->make_sigframe = make_sigframe;
 	ictx->regs_arg = item->core[0];
-- 
2.7.4



More information about the CRIU mailing list