[CRIU] [PATCH v3 06/55] kerndat: Check that "/proc/[pid]/status" file has NS{pid, ..} lines
Kirill Tkhai
ktkhai at virtuozzo.com
Mon Apr 10 01:16:03 PDT 2017
If there is nested pid_ns, we need to be able to get pid in
the whole pid hierarhy. This may be taken from "/proc/[pid]/status"
file only. Check, that kernel has support for it.
v3: Add criu feature check
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-check.c | 13 +++++++++++++
criu/include/kerndat.h | 2 ++
criu/kerndat.c | 28 ++++++++++++++++++++++++++++
criu/namespaces.c | 5 +++++
4 files changed, 48 insertions(+)
diff --git a/criu/cr-check.c b/criu/cr-check.c
index 28e8db15a..7415de39e 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1094,6 +1094,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);
/*
@@ -1198,6 +1209,7 @@ int cr_check(void)
ret |= check_userns();
ret |= check_loginuid();
ret |= check_sk_netns();
+ ret |= check_ns_pid();
}
/*
@@ -1278,6 +1290,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 60c69c3e1..eacd4c73d 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -43,6 +43,7 @@ struct kerndat_s {
unsigned long uffd_features;
bool has_nsid;
bool has_link_nsid;
+ bool has_nspid;
};
extern struct kerndat_s kdat;
@@ -65,5 +66,6 @@ extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
extern int kerndat_tcp_repair();
extern int kerndat_uffd(bool need_uffd);
+extern int kerndat_has_nspid(void);
#endif /* __CR_KERNDAT_H__ */
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 22dd1e8c4..a10247930 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -627,6 +627,32 @@ int kerndat_uffd(bool need_uffd)
return 0;
}
+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;
@@ -658,6 +684,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 910fc0e0a..a1088e426 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"
@@ -789,6 +790,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);
}
More information about the CRIU
mailing list