From patchwork Fri Oct 28 17:41:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [05/10] net: bind and listen a parasite socket for each network namespace From: Andrei Vagin X-Patchwork-Id: 2298 Message-Id: <1477676516-28669-6-git-send-email-avagin@openvz.org> To: xemul@virtuozzo.com Cc: criu@openvz.org, Andrei Vagin Date: Fri, 28 Oct 2016 20:41:51 +0300 From: Andrei Vagin CRIU uses an unix socket to comunicate with a parasite code, but an unix socket created from one netns is invisible from another netns. Signed-off-by: Andrei Vagin --- criu/include/parasite.h | 2 ++ criu/net.c | 29 +++++++++++++++++++++++------ criu/parasite-syscall.c | 22 +++------------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/criu/include/parasite.h b/criu/include/parasite.h index d248bbc..fcbfda4 100644 --- a/criu/include/parasite.h +++ b/criu/include/parasite.h @@ -276,6 +276,8 @@ struct parasite_dump_cgroup_args { #define parasite_sym(pblob, ptype, symbol) \ ((void *)(pblob) + __pblob_offset(ptype, symbol)) +extern int gen_parasite_saddr(struct sockaddr_un *saddr, int key); + #endif /* !__ASSEMBLY__ */ #include "parasite-compat.h" diff --git a/criu/net.c b/criu/net.c index 761e8a4..2fe9ffb 100644 --- a/criu/net.c +++ b/criu/net.c @@ -15,6 +15,7 @@ #include #include +#include "types.h" #include "imgset.h" #include "namespaces.h" #include "net.h" @@ -32,6 +33,8 @@ #include "kerndat.h" #include "external.h" #include "util.h" +#include "parasite.h" + #include "protobuf.h" #include "images/netdev.pb-c.h" @@ -1868,7 +1871,9 @@ int macvlan_ext_add(struct external *ext) static int prep_ns_sockets(struct ns_id *ns, bool for_dump) { - int nsret = -1, ret; + int nsret = -1, ret, sk; + struct sockaddr_un addr; + s32 addr_len; if (ns->type != NS_CRIU) { pr_info("Switching to %d's net for collecting sockets\n", ns->ns_pid); @@ -1885,12 +1890,24 @@ static int prep_ns_sockets(struct ns_id *ns, bool for_dump) } else ns->net.nlsk = -1; - ret = ns->net.seqsk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0); - if (ret < 0) { + sk = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0); + if (sk < 0) { pr_perror("Can't create seqsk for parasite"); goto err_sq; } + addr_len = gen_parasite_saddr(&addr, getpid()); + if (bind(sk, (struct sockaddr *)&addr, addr_len) < 0) { + pr_perror("Can't bind socket"); + goto err_ret; + } + + if (listen(sk, 1)) { + pr_perror("Can't listen on transport socket"); + goto err_ret; + } + + ns->net.seqsk = sk; ret = 0; out: if (nsret >= 0 && restore_ns(nsret, &net_ns_desc) < 0) { @@ -1902,11 +1919,11 @@ out: return ret; err_ret: - close(ns->net.seqsk); + close_safe(&sk); err_sq: - if (ns->net.nlsk >= 0) - close(ns->net.nlsk); + close_safe(&ns->net.nlsk); err_nl: + ret = -1; goto out; } diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index e5b1ba3..748697a 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -356,7 +356,7 @@ int parasite_execute_daemon(unsigned int cmd, struct parasite_ctl *ctl) return ret; } -static int gen_parasite_saddr(struct sockaddr_un *saddr, int key) +int gen_parasite_saddr(struct sockaddr_un *saddr, int key) { int sun_len; @@ -447,25 +447,12 @@ static int restore_child_handler() static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid, struct parasite_init_args *args, struct ns_id *net) { - static int ssock = -1; + int ssock; pr_info("Putting tsock into pid %d\n", pid); args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid()); - if (ssock == -1) { - ssock = net->net.seqsk; - net->net.seqsk = -1; - - if (bind(ssock, (struct sockaddr *)&args->h_addr, args->h_addr_len) < 0) { - pr_perror("Can't bind socket"); - goto err; - } - - if (listen(ssock, 1)) { - pr_perror("Can't listen on transport socket"); - goto err; - } - } + ssock = net->net.seqsk; /* Check a case when parasite can't initialize a command socket */ if (fault_injected(FI_PARASITE_CONNECT)) @@ -477,9 +464,6 @@ static int prepare_tsock(struct parasite_ctl *ctl, pid_t pid, */ ctl->tsock = -ssock; return 0; -err: - close_safe(&ssock); - return -1; } static int accept_tsock(struct parasite_ctl *ctl)