[CRIU] [PATCH 7/9] kerndat: check the SIOCGSKNS ioctl
Andrei Vagin
avagin at openvz.org
Tue Feb 14 15:59:30 PST 2017
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 04c2cd1..c826125 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1079,6 +1079,17 @@ static int check_uffd(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..162ac28 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,8 @@ int kerndat_init(void)
ret = kerndat_tcp_repair();
if (!ret)
ret = kerndat_compat_restore();
+ if (!ret)
+ ret = kerndat_socket_netns();
kerndat_lsm();
kerndat_mmap_min_addr();
@@ -670,6 +673,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;
--
2.7.4
More information about the CRIU
mailing list