[CRIU] [PATCH 05/10] net: bind and listen a parasite socket for each network namespace
Andrei Vagin
avagin at openvz.org
Fri Oct 28 10:41:51 PDT 2016
From: Andrei Vagin <avagin at virtuozzo.com>
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 <avagin at virtuozzo.com>
---
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 <linux/sockios.h>
#include <libnl3/netlink/msg.h>
+#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)
--
2.7.4
More information about the CRIU
mailing list