[RESEND,v1,19/55] pid: Add top_pid_ns

Submitted by Kirill Tkhai on March 24, 2017, 3:12 p.m.

Details

Message ID 149036832490.23093.12172100379968086566.stgit@localhost.localdomain
State New
Series "Nested pid namespaces support"
Headers show

Commit Message

Kirill Tkhai March 24, 2017, 3:12 p.m.
It's the most parent pid namespace, which is seen by dumpees.
It's NS_ROOT if root_ns_mask has CLONE_NEWPID, and NS_CRIU
otherwise.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/include/namespaces.h |    1 +
 criu/namespaces.c         |   18 +++++++++++++++---
 criu/pstree.c             |    8 ++++++++
 3 files changed, 24 insertions(+), 3 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/namespaces.h b/criu/include/namespaces.h
index fb39ce9c..f638d12c 100644
--- a/criu/include/namespaces.h
+++ b/criu/include/namespaces.h
@@ -122,6 +122,7 @@  struct ns_id {
 	};
 };
 extern struct ns_id *ns_ids;
+extern struct ns_id *top_pid_ns;
 extern struct ns_id *root_user_ns;
 
 #define NS_DESC_ENTRY(_cflag, _str)			\
diff --git a/criu/namespaces.c b/criu/namespaces.c
index e78e7fe5..925805ca 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -430,6 +430,10 @@  static unsigned int generate_ns_id(int pid, unsigned int kid, struct ns_desc *nd
 	INIT_LIST_HEAD(&nsid->siblings);
 	nsid_add(nsid, nd, ns_next_id++, pid);
 
+	if (nd == &pid_ns_desc) {
+		if (type == NS_ROOT || (type == NS_CRIU && !top_pid_ns))
+			top_pid_ns = nsid;
+	}
 found:
 	if (ns_ret)
 		*ns_ret = nsid;
@@ -827,6 +831,7 @@  static int set_ns_hookups(struct ns_id *ns)
 	return ret;
 }
 
+struct ns_id *top_pid_ns = NULL;
 struct ns_id *root_user_ns = NULL;
 /* Mapping NS_ROOT to NS_CRIU */
 UsernsEntry *userns_entry;
@@ -1935,6 +1940,13 @@  int read_ns_with_hookups(void)
 			ns->type = NS_ROOT;
 			root_user_ns = ns;
 			userns_entry = ns->user.e;
+		} else if (e->ns_cflag == CLONE_NEWPID) {
+			if (top_pid_ns) {
+				pr_err("top_pid_ns already set\n");
+				goto close;
+			}
+			ns->type = NS_ROOT;
+			top_pid_ns = ns;
 		}
 
 		ns_entry__free_unpacked(e, NULL);
@@ -1989,9 +2001,9 @@  static int mark_root_ns(uint32_t id, struct ns_desc *desc)
 int set_ns_roots(void)
 {
 	TaskKobjIdsEntry *ids = root_item->ids;
-	/* Set root for all namespaces except user_ns, which is set in read_ns_with_hookups() */
-	if (MARK_ROOT_NS(ids, pid) || MARK_ROOT_NS(ids, net) || MARK_ROOT_NS(ids, ipc) ||
-	    MARK_ROOT_NS(ids, uts) || MARK_ROOT_NS(ids, mnt) || MARK_ROOT_NS(ids, cgroup))
+	/* Set root for all namespaces except user and pid, which are set in read_ns_with_hookups() */
+	if (MARK_ROOT_NS(ids, net) || MARK_ROOT_NS(ids, ipc) || MARK_ROOT_NS(ids, uts) ||
+	    MARK_ROOT_NS(ids, mnt) || MARK_ROOT_NS(ids, cgroup))
 		return -1;
 	return 0;
 }
diff --git a/criu/pstree.c b/criu/pstree.c
index e12b358a..d6d71bb3 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -511,6 +511,14 @@  static int read_pstree_ids(pid_t pid, TaskKobjIdsEntry **ids)
 	if ((*ids)->has_pid_ns_id) {
 		if (rst_add_ns_id((*ids)->pid_ns_id, pid, &pid_ns_desc))
 			return -1;
+		if (!top_pid_ns) {
+			/*
+			 * If top_pid_ns is not set, this means that here is old dump,
+			 * which does not contain ns.img. It can have only one pid_ns,
+			 * so we set it here.
+			 */
+			top_pid_ns = lookup_ns_by_id((*ids)->pid_ns_id, &pid_ns_desc);
+		}
 	}
 	if ((*ids)->has_ipc_ns_id) {
 		if (rst_add_ns_id((*ids)->ipc_ns_id, pid, &ipc_ns_desc))