[08/10] kerndat: check the SIOCGSKNS ioctl

Submitted by Andrei Vagin on Feb. 13, 2017, 5:49 a.m.

Details

Message ID 1486964960-4872-9-git-send-email-avagin@openvz.org
State New
Series "Dump and restore nested network namespaces"
Headers show

Commit Message

Andrei Vagin Feb. 13, 2017, 5:49 a.m.
From: Andrei Vagin <avagin@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@virtuozzo.com>
---
 criu/cr-check.c        | 13 +++++++++++++
 criu/include/kerndat.h |  1 +
 criu/include/sockets.h |  6 ++++++
 criu/kerndat.c         |  7 +++++++
 criu/net.c             | 24 ++++++++++++++++++++++++
 5 files changed, 51 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 8bfc992..252a1e5 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1079,6 +1079,17 @@  static int check_loginuid(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 check_compat_cr(void)
 {
 	if (kdat_compat_sigreturn_test())
@@ -1190,6 +1201,7 @@  int cr_check(void)
 		ret |= check_tcp_halt_closed();
 		ret |= check_userns();
 		ret |= check_loginuid();
+		ret |= check_sk_netns();
 	}
 
 	/*
@@ -1241,6 +1253,7 @@  static struct feature_list feature_list[] = {
 	{ "tcp_half_closed", check_tcp_halt_closed },
 	{ "lazy_pages", check_uffd },
 	{ "compat_cr", check_compat_cr },
+	{ "sk_ns", check_sk_netns },
 	{ NULL, NULL },
 };
 
diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index 8f8db78..e41768f 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -35,6 +35,7 @@  struct kerndat_s {
 	bool ipv6;
 	bool has_loginuid;
 	bool has_compat_sigreturn;
+	bool sk_ns;
 	enum pagemap_func pmap;
 	unsigned int has_xtlocks;
 	unsigned long mmap_min_addr;
diff --git a/criu/include/sockets.h b/criu/include/sockets.h
index 28bf91e..93f9ca3 100644
--- a/criu/include/sockets.h
+++ b/criu/include/sockets.h
@@ -84,4 +84,10 @@  static inline int sk_decode_shutdown(int val)
 
 extern int set_netns(uint32_t ns_id);
 
+#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 88feac3..ff0b1c2 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -27,6 +27,7 @@ 
 #include "proc_parse.h"
 #include "config.h"
 #include "sk-inet.h"
+#include "sockets.h"
 #include <compel/plugins/std/syscall-codes.h>
 #include <compel/compel.h>
 #include "linux/userfaultfd.h"
@@ -634,6 +635,10 @@  int kerndat_init(void)
 		ret = kerndat_tcp_repair();
 	if (!ret)
 		ret = kerndat_compat_restore();
+	if (!ret)
+		ret = kerndat_tcp_repair();
+	if (!ret)
+		ret = kerndat_socket_netns();
 
 	kerndat_lsm();
 	kerndat_mmap_min_addr();
@@ -670,6 +675,8 @@  int kerndat_init_rst(void)
 		ret = kerndat_compat_restore();
 	if (!ret)
 		ret = kerndat_uffd(opts.lazy_pages);
+	if (!ret)
+		ret = kerndat_socket_netns();
 
 	kerndat_lsm();
 	kerndat_mmap_min_addr();
diff --git a/criu/net.c b/criu/net.c
index 25abd6f..7000923 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -2061,6 +2061,30 @@  struct ns_id *get_socket_ns(int lfd)
 	return NULL;
 }
 
+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;
+}
+
 static int move_to_bridge(struct external *ext, void *arg)
 {
 	int s = *(int *)arg;

Comments

Pavel Emelianov Feb. 13, 2017, 1:16 p.m.
> @@ -634,6 +635,10 @@ int kerndat_init(void)
>  		ret = kerndat_tcp_repair();
>  	if (!ret)
>  		ret = kerndat_compat_restore();
> +	if (!ret)
> +		ret = kerndat_tcp_repair();

O_o

> +	if (!ret)
> +		ret = kerndat_socket_netns();
>  
>  	kerndat_lsm();
>  	kerndat_mmap_min_addr();