[03/28] pid_ns: Make add_child_task() working with last_level_pid()

Submitted by Kirill Tkhai on June 5, 2017, 5:23 p.m.

Details

Message ID 149668343284.25229.14733714363889934249.stgit@localhost.localdomain
State Accepted
Series "Support sockets leaked to child user_ns task"
Commit 4111b43dfd1a0a5158d9e9e75bd7a81d07998a56
Headers show

Commit Message

Kirill Tkhai June 5, 2017, 5:23 p.m.
The original idea was to sort children and to keep child
reapers at the beginning of the list. But there a mistake
happened: we must look for last_level_pid() as it is
an indicator of a child_reaper.

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

Patch hide | download patch | download mbox

diff --git a/criu/pstree.c b/criu/pstree.c
index dec77b81a..908e070d1 100644
--- a/criu/pstree.c
+++ b/criu/pstree.c
@@ -256,15 +256,21 @@  struct pstree_item *__alloc_pstree_item(bool rst, int level)
 	return item;
 }
 
+/*
+ * Link child task to parent and try to keep parent's children sorted:
+ * child reapers at the beginning of list, the less pid->level is first.
+ * This gives basic protection against deadlock, when a tasks is waiting
+ * for pid_ns child reaper creation, while it's in the end of the list.
+ */
 void add_child_task(struct pstree_item *child, struct pstree_item *parent)
 {
 	struct pstree_item *item;
 
-	if (vpid(child) != INIT_PID)
+	if (last_level_pid(child->pid) != INIT_PID)
 		list_add_tail(&child->sibling, &parent->children);
 	else {
 		list_for_each_entry(item, &parent->children, sibling)
-			if (vpid(item) != INIT_PID ||
+			if (last_level_pid(item->pid) != INIT_PID ||
 			    item->pid->level >= child->pid->level)
 				break;
 		/* Add child before item */

Comments

Andrey Vagin June 6, 2017, 5:52 p.m.
Applied

On Mon, Jun 05, 2017 at 08:23:52PM +0300, Kirill Tkhai wrote:
> The original idea was to sort children and to keep child
> reapers at the beginning of the list. But there a mistake
> happened: we must look for last_level_pid() as it is
> an indicator of a child_reaper.
> 
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  criu/pstree.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/criu/pstree.c b/criu/pstree.c
> index dec77b81a..908e070d1 100644
> --- a/criu/pstree.c
> +++ b/criu/pstree.c
> @@ -256,15 +256,21 @@ struct pstree_item *__alloc_pstree_item(bool rst, int level)
>  	return item;
>  }
>  
> +/*
> + * Link child task to parent and try to keep parent's children sorted:
> + * child reapers at the beginning of list, the less pid->level is first.
> + * This gives basic protection against deadlock, when a tasks is waiting
> + * for pid_ns child reaper creation, while it's in the end of the list.
> + */
>  void add_child_task(struct pstree_item *child, struct pstree_item *parent)
>  {
>  	struct pstree_item *item;
>  
> -	if (vpid(child) != INIT_PID)
> +	if (last_level_pid(child->pid) != INIT_PID)
>  		list_add_tail(&child->sibling, &parent->children);
>  	else {
>  		list_for_each_entry(item, &parent->children, sibling)
> -			if (vpid(item) != INIT_PID ||
> +			if (last_level_pid(item->pid) != INIT_PID ||
>  			    item->pid->level >= child->pid->level)
>  				break;
>  		/* Add child before item */
>