[CRIU] [PATCH 03/10] kerndat: check the SIOCGSKNS ioctl

Andrei Vagin avagin at openvz.org
Wed Aug 31 15:55:26 PDT 2016


From: Andrei Vagin <avagin at virtuozzo.com>

This ioctl is called for a socket and returns a file descriptor
for network namespace where a socket has been created.

Signed-off-by: Andrei Vagin <avagin at virtuozzo.com>
---
 criu/cr-check.c        | 13 +++++++++++++
 criu/include/kerndat.h |  1 +
 criu/include/sockets.h |  6 ++++++
 criu/kerndat.c         |  5 +++++
 criu/net.c             | 24 ++++++++++++++++++++++++
 5 files changed, 49 insertions(+)

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 2bee096..f054374 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -933,6 +933,17 @@ static int check_tcp_window(void)
 	return 0;
 }
 
+static int check_sk_netns(void)
+{
+	if (kerndat_socket_netns() < 0)
+		return -1;
+
+	if (!kdat.sk_ns)
+		return -1;
+
+	return 0;
+}
+
 static int (*chk_feature)(void);
 
 /*
@@ -1031,6 +1042,7 @@ int cr_check(void)
 		ret |= check_clone_parent_vs_pid();
 		ret |= check_cgroupns();
 		ret |= check_tcp_window();
+		ret |= check_sk_netns();
 	}
 
 	/*
@@ -1110,6 +1122,7 @@ static struct feature_list feature_list[] = {
 	{ "loginuid", check_loginuid },
 	{ "cgroupns", check_cgroupns },
 	{ "autofs", check_autofs },
+	{ "sk_ns", check_sk_netns },
 	{ NULL, NULL },
 };
 
diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index 860e32d..2018a0d 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -36,6 +36,7 @@ struct kerndat_s {
 	bool ipv6;
 	bool has_loginuid;
 	bool has_compat_sigreturn;
+	bool sk_ns;
 	enum pagemap_func pmap;
 	unsigned int has_xtlocks;
 };
diff --git a/criu/include/sockets.h b/criu/include/sockets.h
index cbecd80..40295bb 100644
--- a/criu/include/sockets.h
+++ b/criu/include/sockets.h
@@ -84,4 +84,10 @@ static inline int sk_decode_shutdown(int val)
 #define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
 #endif
 
+#ifndef SIOCGSKNS
+#define SIOCGSKNS      0x894C          /* get socket network namespace */
+#endif
+
+extern int kerndat_socket_netns(void);
+
 #endif /* __CR_SOCKETS_H__ */
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 8a639fd..3aa1529 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -23,6 +23,7 @@
 #include "proc_parse.h"
 #include "config.h"
 #include "syscall-codes.h"
+#include "sockets.h"
 
 struct kerndat_s kdat = {
 };
@@ -487,6 +488,8 @@ int kerndat_init(void)
 		ret = kerndat_tcp_repair_window();
 	if (!ret)
 		ret = kerndat_compat_restore();
+	if (!ret)
+		ret = kerndat_socket_netns();
 
 	kerndat_lsm();
 
@@ -520,6 +523,8 @@ int kerndat_init_rst(void)
 		ret = kerndat_tcp_repair_window();
 	if (!ret)
 		ret = kerndat_compat_restore();
+	if (!ret)
+		ret = kerndat_socket_netns();
 
 	kerndat_lsm();
 
diff --git a/criu/net.c b/criu/net.c
index 080c617..d0b71c4 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1727,6 +1727,30 @@ int collect_net_namespaces(bool for_dump)
 
 struct ns_desc net_ns_desc = NS_DESC_ENTRY(CLONE_NEWNET, "net");
 
+int kerndat_socket_netns(void)
+{
+	int sk, ns_fd;
+
+	sk = socket(AF_UNIX, SOCK_DGRAM, 0);
+	if (sk < 0) {
+		pr_perror("Unable to create socket");
+		return -1;
+	}
+	ns_fd = ioctl(sk, SIOCGSKNS);
+	if (ns_fd < 0) {
+		pr_warn("Unable to get a socket network namespace\n");
+		kdat.sk_ns = false;
+		close(sk);
+		return 0;
+	}
+	close(sk);
+	close(ns_fd);
+
+	kdat.sk_ns = true;
+
+	return 0;
+}
+
 int move_veth_to_bridge(void)
 {
 	int s;
-- 
2.7.4



More information about the CRIU mailing list