[08/21] kerndat: Check for /proc/[pid]/ns/pid_for_children_ns

Submitted by Kirill Tkhai on May 23, 2017, 12:39 p.m.

Details

Message ID 149554316307.12386.542495067486040737.stgit@localhost.localdomain
State New
Series "Add /proc/[pid]/ns/pid_for_children ns support (and fixes)"
Headers show

Commit Message

Kirill Tkhai May 23, 2017, 12:39 p.m.
Introduce new extra feature "pid_for_children_ns" to show
setns'ed pid namespaces.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=eaa0d190bfe1ed891b814a52712dcd852554cb08

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/cr-check.c        |   12 ++++++++++++
 criu/include/kerndat.h |    2 ++
 criu/kerndat.c         |   16 ++++++++++++++++
 3 files changed, 30 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 0118dcceb..de81ec37f 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1135,6 +1135,16 @@  static int check_ns_get_parent(void)
 	return 0;
 }
 
+static int check_pid_for_children_ns(void)
+{
+	if (kerndat_has_pid_for_children_ns() < 0)
+		return -1;
+
+	if (!kdat.has_pid_for_children_ns)
+		return -1;
+
+	return 0;
+}
 
 static int (*chk_feature)(void);
 
@@ -1243,6 +1253,7 @@  int cr_check(void)
 		ret |= check_ns_pid();
 		ret |= check_ns_get_userns();
 		ret |= check_ns_get_parent();
+		ret |= check_pid_for_children_ns();
 	}
 
 	/*
@@ -1326,6 +1337,7 @@  static struct feature_list feature_list[] = {
 	{ "ns_pid", check_ns_pid},
 	{ "ns_get_userns", check_ns_get_userns },
 	{ "ns_get_parent", check_ns_get_parent },
+	{ "pid_for_children_ns", check_pid_for_children_ns},
 	{ NULL, NULL },
 };
 
diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
index da184c054..208f24cc7 100644
--- a/criu/include/kerndat.h
+++ b/criu/include/kerndat.h
@@ -52,6 +52,7 @@  struct kerndat_s {
 	bool has_nspid;
 	bool has_ns_get_userns;
 	bool has_ns_get_parent;
+	bool has_pid_for_children_ns;
 };
 
 extern struct kerndat_s kdat;
@@ -77,5 +78,6 @@  extern int kerndat_uffd(void);
 extern int kerndat_has_nspid(void);
 extern int kerndat_has_ns_get_userns(void);
 extern int kerndat_has_ns_get_parent(void);
+extern int kerndat_has_pid_for_children_ns(void);
 
 #endif /* __CR_KERNDAT_H__ */
diff --git a/criu/kerndat.c b/criu/kerndat.c
index 3204d4bc1..757281ca2 100644
--- a/criu/kerndat.c
+++ b/criu/kerndat.c
@@ -694,6 +694,20 @@  int kerndat_has_ns_get_parent(void)
 	return 0;
 }
 
+int kerndat_has_pid_for_children_ns(void)
+{
+	if (access("/proc/self/ns/pid_for_children", F_OK) < 0) {
+		if (errno == ENOENT) {
+			pr_debug("No /proc/self/ns/pid_for_children\n");
+			kdat.has_pid_for_children_ns = false;
+			return 0;
+		}
+		pr_perror("Unable to access /proc/self/ns/pid_for_children");
+		return -1;
+	}
+	kdat.has_pid_for_children_ns = true;
+	return 0;
+}
 
 #define KERNDAT_CACHE_FILE	KDAT_RUNDIR"/criu.kdat"
 #define KERNDAT_CACHE_FILE_TMP	KDAT_RUNDIR"/.criu.kdat"
@@ -813,6 +827,8 @@  int kerndat_init(void)
 	if (!ret)
 		ret = kerndat_has_nspid();
 	if (!ret)
+		ret = kerndat_has_pid_for_children_ns();
+	if (!ret)
 		ret = kerndat_has_memfd_create();
 	if (!ret)
 		ret = kerndat_uffd();