[CRIU] [PATCH RESEND v1 09/55] kerndat: Check that "/proc/[pid]/status" file has NS{pid, ..} lines

Kirill Tkhai ktkhai at virtuozzo.com
Fri Mar 24 08:10:22 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.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/include/kerndat.h |    1 +
 criu/kerndat.c         |   28 ++++++++++++++++++++++++++++
 criu/namespaces.c      |    5 +++++
 3 files changed, 34 insertions(+)

diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index e41768fa..75363f4a 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -41,6 +41,7 @@ struct kerndat_s {
 	unsigned long mmap_min_addr;
 	bool has_tcp_half_closed;
 	unsigned long uffd_features;
+	bool has_nspid;
 };
 
 extern struct kerndat_s kdat;
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 162ac28b..b9b214c5 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -608,6 +608,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;
@@ -637,6 +663,8 @@ int kerndat_init(void)
 		ret = kerndat_compat_restore();
 	if (!ret)
 		ret = kerndat_socket_netns();
+	if (!ret)
+		ret = kerndat_has_nspid();
 
 	kerndat_lsm();
 	kerndat_mmap_min_addr();
diff --git a/criu/namespaces.c b/criu/namespaces.c
index ee309045..e78e7fe5 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"
@@ -781,6 +782,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