diff --git a/criu/cr-check.c b/criu/cr-check.c index f67b3445f..f57e8eb4e 100644 --- a/criu/cr-check.c +++ b/criu/cr-check.c @@ -1073,6 +1073,17 @@ static int check_sk_netns(void) return 0; } +static int check_ns_pid(void) +{ + if (kerndat_has_nspid() < 0) + return -1; + + if (!kdat.has_nspid) + return -1; + + return 0; +} + static int (*chk_feature)(void); /* @@ -1180,6 +1191,7 @@ int cr_check(void) ret |= check_uffd(); ret |= check_uffd_noncoop(); ret |= check_sk_netns(); + ret |= check_ns_pid(); } /* @@ -1261,6 +1273,7 @@ static struct feature_list feature_list[] = { { "sk_ns", check_sk_netns }, { "nsid", check_nsid }, { "link_nsid", check_link_nsid}, + { "ns_pid", check_ns_pid}, { NULL, NULL }, }; diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 785b13679..c00c6d220 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -66,6 +66,7 @@ struct kerndat_s { #endif bool has_nsid; bool has_link_nsid; + bool has_nspid; }; extern struct kerndat_s kdat; @@ -88,5 +89,6 @@ extern int kerndat_fs_virtualized(unsigned int which, u32 kdev); extern int kerndat_tcp_repair(); extern int kerndat_uffd(void); +extern int kerndat_has_nspid(void); #endif /* __CR_KERNDAT_H__ */ diff --git a/criu/kerndat.c b/criu/kerndat.c index 1870721de..700a5a5e4 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -848,6 +848,32 @@ out_unmap: return ret; } +int kerndat_has_nspid(void) +{ + struct bfd f; + int ret = -1; + char *str; + + f.fd = open("/proc/self/status", O_RDONLY); + if (f.fd < 0) { + pr_perror("Can't open /proc/self/status"); + return -1; + } + if (bfdopenr(&f)) + return -1; + while ((str = breadline(&f)) != NULL) { + if (IS_ERR(str)) + goto close; + if (!strncmp(str, "NSpid:", 6)) { + kdat.has_nspid = true; + break; + } + } + ret = 0; +close: + bclose(&f); + return ret; +} int kerndat_init(void) { int ret; @@ -904,6 +930,8 @@ int kerndat_init(void) ret = kerndat_socket_netns(); if (!ret) ret = kerndat_nsid(); + if (!ret) + ret = kerndat_has_nspid(); kerndat_lsm(); kerndat_mmap_min_addr(); diff --git a/criu/namespaces.c b/criu/namespaces.c index 50911898a..8aa680649 100644 --- a/criu/namespaces.c +++ b/criu/namespaces.c @@ -26,6 +26,7 @@ #include "namespaces.h" #include "net.h" #include "cgroup.h" +#include "kerndat.h" #include "protobuf.h" #include "util.h" @@ -803,6 +804,10 @@ static int set_ns_hookups(struct ns_id *ns) pr_err("Wrong determined NS_ROOT, or root_item has NS_OTHER user_ns\n"); goto out; } + if (nd == &pid_ns_desc && !kdat.has_nspid) { + pr_err("Can't dump nested pid ns\n"); + goto out; + } list_add(&ns->siblings, &ns->parent->children); }