diff --git a/criu/cr-check.c b/criu/cr-check.c index 21d241f68..8f3a965a6 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -1062,6 +1062,17 @@ static int check_can_map_vdso(void) return -1; } +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); /* @@ -1168,6 +1179,7 @@ int cr_check(void) ret |= check_can_map_vdso(); ret |= check_uffd(); ret |= check_uffd_noncoop(); + ret |= check_sk_netns(); } /* @@ -1220,6 +1232,7 @@ static struct feature_list feature_list[] = { { "uffd", check_uffd }, { "uffd-noncoop", check_uffd_noncoop }, { "can_map_vdso", check_can_map_vdso}, + { "sk_ns", check_sk_netns }, { NULL, NULL }, }; diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 6ad77e369..a4922f174 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -46,6 +46,7 @@ struct kerndat_s { bool ipv6; enum loginuid_func luid; bool compat_cr; + 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 a0f6101ba..381244077 100644 --- a/criu/include/sockets.h +++ b/criu/include/sockets.h @@ -87,4 +87,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 164f6cc4b..156b1c617 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -27,6 +27,7 @@ #include "lsm.h" #include "proc_parse.h" #include "sk-inet.h" +#include "sockets.h" #include #include #include "netfilter.h" @@ -873,6 +874,8 @@ int kerndat_init(void) /* Depends on kerndat_vdso_fill_symtable() */ if (!ret) ret = kerndat_vdso_preserves_hint(); + if (!ret) + ret = kerndat_socket_netns(); kerndat_lsm(); kerndat_mmap_min_addr(); diff --git a/criu/net.c b/criu/net.c index 8834dab24..d1723ec05 100644 --- a/criu/net.c +++ b/criu/net.c @@ -2297,6 +2297,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;