[02/28] pre_dump: Assign parasite pid only if it hasn't collected yet

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

Details

Message ID 149668342263.25229.422868639721861142.stgit@localhost.localdomain
State New
Series "Support sockets leaked to child user_ns task"
Headers show

Commit Message

Kirill Tkhai June 5, 2017, 5:23 p.m.
Parasite returns last level pid (pid in task's pid namespace),
so we mustn't rewrite already collected from /proc/[pid]/status
vpid.

We handle that correctly on dump, do the same on pre-dump.

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

Patch hide | download patch | download mbox

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index ccd651970..913273743 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1194,6 +1194,24 @@  static int dump_zombies(void)
 	return ret;
 }
 
+static int assign_parasite_pids(struct pstree_item *item, struct parasite_dump_misc *misc)
+{
+	if (vpid(item) == -1) {
+		vpid(item) = misc->pid;
+		vsid(item) = misc->sid;
+		vpgid(item) = misc->pgid;
+	} else {
+		/* They were collected in parse_pid_status() */
+		if (last_level_pid(item->pid) != misc->pid ||
+		    last_level_pid(item->sid) != misc->sid ||
+		    last_level_pid(item->pgid) != misc->pgid) {
+			pr_err("Parasite and /proc/[pid]/status gave different pids\n");
+			return -1;
+		}
+	}
+	return 0;
+}
+
 static int pre_dump_one_task(struct pstree_item *item)
 {
 	pid_t pid = item->pid->real;
@@ -1249,7 +1267,8 @@  static int pre_dump_one_task(struct pstree_item *item)
 		goto err_cure;
 	}
 
-	vpid(item) = misc.pid;
+	if (assign_parasite_pids(item, &misc))
+		goto err;
 
 	mdc.pre_dump = true;
 	mdc.lazy = false;
@@ -1379,19 +1398,8 @@  static int dump_one_task(struct pstree_item *item)
 		goto err_cure_imgset;
 	}
 
-	if (vpid(item) == -1) {
-		vpid(item) = misc.pid;
-		vsid(item) = misc.sid;
-		vpgid(item) = misc.pgid;
-	} else {
-		/* They were collected in parse_pid_status() */
-		if (last_level_pid(item->pid) != misc.pid ||
-		    last_level_pid(item->sid) != misc.sid ||
-		    last_level_pid(item->pgid) != misc.pgid) {
-			pr_err("Parasite and /proc/[pid]/status gave different pids\n");
-			goto err;
-		}
-	}
+	if (assign_parasite_pids(item, &misc))
+		goto err;
 
 	pstree_insert_pid(item->pid, item->ids->pid_ns_id);
 

Comments

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

On Mon, Jun 05, 2017 at 08:23:42PM +0300, Kirill Tkhai wrote:
> Parasite returns last level pid (pid in task's pid namespace),
> so we mustn't rewrite already collected from /proc/[pid]/status
> vpid.
> 
> We handle that correctly on dump, do the same on pre-dump.
> 
> Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
> ---
>  criu/cr-dump.c |   36 ++++++++++++++++++++++--------------
>  1 file changed, 22 insertions(+), 14 deletions(-)
> 
> diff --git a/criu/cr-dump.c b/criu/cr-dump.c
> index ccd651970..913273743 100644
> --- a/criu/cr-dump.c
> +++ b/criu/cr-dump.c
> @@ -1194,6 +1194,24 @@ static int dump_zombies(void)
>  	return ret;
>  }
>  
> +static int assign_parasite_pids(struct pstree_item *item, struct parasite_dump_misc *misc)
> +{
> +	if (vpid(item) == -1) {
> +		vpid(item) = misc->pid;
> +		vsid(item) = misc->sid;
> +		vpgid(item) = misc->pgid;
> +	} else {
> +		/* They were collected in parse_pid_status() */
> +		if (last_level_pid(item->pid) != misc->pid ||
> +		    last_level_pid(item->sid) != misc->sid ||
> +		    last_level_pid(item->pgid) != misc->pgid) {
> +			pr_err("Parasite and /proc/[pid]/status gave different pids\n");
> +			return -1;
> +		}
> +	}
> +	return 0;
> +}
> +
>  static int pre_dump_one_task(struct pstree_item *item)
>  {
>  	pid_t pid = item->pid->real;
> @@ -1249,7 +1267,8 @@ static int pre_dump_one_task(struct pstree_item *item)
>  		goto err_cure;
>  	}
>  
> -	vpid(item) = misc.pid;
> +	if (assign_parasite_pids(item, &misc))
> +		goto err;
>  
>  	mdc.pre_dump = true;
>  	mdc.lazy = false;
> @@ -1379,19 +1398,8 @@ static int dump_one_task(struct pstree_item *item)
>  		goto err_cure_imgset;
>  	}
>  
> -	if (vpid(item) == -1) {
> -		vpid(item) = misc.pid;
> -		vsid(item) = misc.sid;
> -		vpgid(item) = misc.pgid;
> -	} else {
> -		/* They were collected in parse_pid_status() */
> -		if (last_level_pid(item->pid) != misc.pid ||
> -		    last_level_pid(item->sid) != misc.sid ||
> -		    last_level_pid(item->pgid) != misc.pgid) {
> -			pr_err("Parasite and /proc/[pid]/status gave different pids\n");
> -			goto err;
> -		}
> -	}
> +	if (assign_parasite_pids(item, &misc))
> +		goto err;
>  
>  	pstree_insert_pid(item->pid, item->ids->pid_ns_id);
>  
>