[RESEND,v1,33/55] pid: Use collect_pid_status() to populate item's pids

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

Details

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

Commit Message

Kirill Tkhai March 24, 2017, 3:14 p.m.
If there are several pid namespaces, then collect pids
in all pid hierarhy.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/cr-dump.c |   38 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index cb25c357..0111dcbd 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -586,10 +586,20 @@  static int get_task_personality(pid_t pid, u32 *personality)
 	return ret;
 }
 
+static void add_ns_pid(struct pid *pid, uint32_t *nspid, int nr)
+{
+	pid->level = nr;
+	while (nr-- > 0)
+		pid->ns[nr].virt = nspid[nr];
+}
+
 static int populate_ns_pids(pid_t real_pid, pid_t real_tid,
 			    struct pid **pid, struct pid **sid, struct pid **pgid,
 			    pid_t parasite_pid, pid_t parasite_sid, pid_t parasite_pgid)
 {
+	struct proc_pid_status st;
+	unsigned nr, sz;
+
 	if (list_empty(&top_pid_ns->children)) {
 		(*pid)->ns[0].virt = parasite_pid;
 		if (real_tid < 0) {
@@ -599,7 +609,33 @@  static int populate_ns_pids(pid_t real_pid, pid_t real_tid,
 		return 0;
 	}
 
-	return -1;
+	if (collect_pid_status(real_pid, real_tid, pid_ns_root_off(), &st) < 0) {
+		pr_err("Can't parse /proc/%d/status\n", (*pid)->real);
+		return -1;
+	}
+	nr = st.n_levels;
+	BUG_ON(st.nspid[nr-1] != parasite_pid ||
+	      (real_tid < 0 && (st.nssid[nr-1] != parasite_sid || st.nspgid[nr-1] != parasite_pgid)));
+
+	if (nr > 1) {
+		sz = (sizeof(struct pid) + (nr - 1) * sizeof((*pid)->ns[0]));
+		*pid = xrealloc(*pid, sz);
+		if (real_tid < 0) {
+			*sid = xrealloc(*sid, sz);
+			*pgid = xrealloc(*pgid, sz);
+		}
+		if (!*pid || (real_tid < 0 && (!*sid || !*pgid)))
+			return -1;
+	}
+
+	add_ns_pid(*pid, st.nspid, nr);
+	if (real_tid < 0) {
+		add_ns_pid(*sid, st.nssid, nr);
+		add_ns_pid(*pgid, st.nspgid, nr);
+	}
+	free_pid_status(&st);
+
+	return 0;
 }
 
 static DECLARE_KCMP_TREE(vm_tree, KCMP_VM);