[02/21] pstree: Add helpers for ordered linking child task to parent

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

Details

Message ID 149554310023.12386.16446967823382027374.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:38 p.m.
Place child reapers of pid namespaces at the beginning
of pstree_item::children list and sort them by nesting
level.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/pstree.c |   35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/pstree.c b/criu/pstree.c
index 85fec6d36..f33da75a9 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -256,6 +256,28 @@  struct pstree_item *__alloc_pstree_item(bool rst, int level)
 	return item;
 }
 
+void add_child_task(struct pstree_item *child, struct pstree_item *parent)
+{
+	struct pstree_item *item;
+
+	if (vpid(child) != INIT_PID)
+		list_add_tail(&child->sibling, &parent->children);
+	else {
+		list_for_each_entry(item, &parent->children, sibling)
+			if (vpid(item) != INIT_PID ||
+			    item->pid->level >= child->pid->level)
+				break;
+		/* Add child before item */
+		list_add_tail(&child->sibling, &item->sibling);
+	}
+}
+
+void move_child_task(struct pstree_item *child, struct pstree_item *new_parent)
+{
+	list_del(&child->sibling);
+	add_child_task(child, new_parent);
+}
+
 int init_pstree_helper(struct pstree_item *ret)
 {
 	BUG_ON(!ret->parent);
@@ -789,7 +811,7 @@  static int read_pstree_image(pid_t *pid_max)
 			pi->parent = NULL;
 		} else {
 			pi->parent = parent;
-			list_add(&pi->sibling, &parent->children);
+			add_child_task(pi, parent);
 		}
 
 		pi->nr_threads = e->n_tids;
@@ -907,7 +929,7 @@  static int prepare_pstree_ids(void)
 			vpgid(helper) = vpgid(leader);
 			helper->ids = leader->ids;
 			helper->parent = leader;
-			list_add(&helper->sibling, &leader->children);
+			add_child_task(helper, leader);
 
 			pr_info("Attach %d to the task %d\n",
 					vpid(helper), vpid(leader));
@@ -943,7 +965,7 @@  static int prepare_pstree_ids(void)
 					vpid(child), vpid(helper));
 
 			child->parent = helper;
-			list_move(&child->sibling, &helper->children);
+			move_child_task(child, helper);
 		}
 	}
 
@@ -985,7 +1007,10 @@  static int prepare_pstree_ids(void)
 	}
 
 	/* All other helpers are session leaders for own sessions */
-	list_splice(&helpers, &root_item->children);
+	while (!list_empty(&helpers)) {
+		item = list_first_entry(&helpers, struct pstree_item, sibling);
+		move_child_task(item, root_item);
+	}
 
 	/* Add a process group leader if it is absent  */
 	for_each_pstree_item(item) {
@@ -1020,7 +1045,7 @@  static int prepare_pstree_ids(void)
 			pr_err("Can't init helper\n");
 			return -1;
 		}
-		list_add(&helper->sibling, &item->children);
+		add_child_task(helper, item);
 		rsti(item)->pgrp_leader = helper;
 
 		pr_info("Add a helper %d for restoring PGID %d\n",