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

Submitted by Kirill Tkhai on May 31, 2017, 5:51 p.m.

Details

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

Commit Message

Kirill Tkhai May 31, 2017, 5:51 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",

Comments

Andrey Vagin June 2, 2017, 8:59 p.m.
On Wed, May 31, 2017 at 08:51:58PM +0300, Kirill Tkhai wrote:
> 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(-)
> 
> 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;
>  }
> 

Pls, write commets before these function to explain what they do and why
we need them.
 
> +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",
>