restore: handle errors of restore_wait_other_tasks

Submitted by Andrei Vagin on June 20, 2017, 8:49 p.m.

Details

Message ID 20170620204903.6153-1-avagin@openvz.org
State Accepted
Series "restore: handle errors of restore_wait_other_tasks"
Headers show

Commit Message

Andrei Vagin June 20, 2017, 8:49 p.m.
From: Andrei Vagin <avagin@virtuozzo.com>

In a error case, task_entries->nr_in_progress is set to -1
and we have to handle this case.

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 criu/cr-restore.c | 38 ++++++++++++++++++++++----------------
 1 file changed, 22 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 298fb69..ed02474 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -164,12 +164,12 @@  static inline int stage_current_participants(int next_stage)
 	return -1;
 }
 
-static int restore_wait_inprogress_tasks()
+static int __restore_wait_inprogress_tasks(int participants)
 {
 	int ret;
 	futex_t *np = &task_entries->nr_in_progress;
 
-	futex_wait_while_gt(np, 0);
+	futex_wait_while_gt(np, participants);
 	ret = (int)futex_get(np);
 	if (ret < 0) {
 		set_cr_errno(get_task_cr_err());
@@ -179,6 +179,22 @@  static int restore_wait_inprogress_tasks()
 	return 0;
 }
 
+static int restore_wait_inprogress_tasks()
+{
+	return __restore_wait_inprogress_tasks(0);
+}
+
+/* Wait all tasks except the current one */
+static int restore_wait_other_tasks()
+{
+	int participants, stage;
+
+	stage = futex_get(&task_entries->start);
+	participants = stage_current_participants(stage);
+
+	return __restore_wait_inprogress_tasks(participants);
+}
+
 static inline void __restore_switch_stage_nw(int next_stage)
 {
 	futex_set(&task_entries->nr_in_progress,
@@ -200,18 +216,6 @@  static int restore_switch_stage(int next_stage)
 	return restore_wait_inprogress_tasks();
 }
 
-/* Wait all tasks except the current one */
-static void restore_wait_other_tasks()
-{
-	int participants, stage;
-
-	stage = futex_get(&task_entries->start);
-	participants = stage_current_participants(stage);
-
-	futex_wait_while_gt(&task_entries->nr_in_progress,
-				participants);
-}
-
 static int restore_finish_ns_stage(int from, int to)
 {
 	if (root_ns_mask)
@@ -1826,7 +1830,8 @@  static int restore_task_with_children(void *_arg)
 		 *
 		 * It means that all tasks entered into their namespaces.
 		 */
-		restore_wait_other_tasks();
+		if (restore_wait_other_tasks())
+			goto err;
 		fini_restore_mntns();
 		__restore_switch_stage(CR_STATE_RESTORE);
 	} else {
@@ -3333,7 +3338,8 @@  static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
 
 	if (current->parent == NULL) {
 		/* Wait when all tasks restored all files */
-		restore_wait_other_tasks();
+		if (restore_wait_other_tasks())
+			goto err;
 	}
 
 	/*

Comments

Andrey Vagin June 27, 2017, 7:01 p.m.
Applied
On Tue, Jun 20, 2017 at 11:49:03PM +0300, Andrei Vagin wrote:
> From: Andrei Vagin <avagin@virtuozzo.com>
> 
> In a error case, task_entries->nr_in_progress is set to -1
> and we have to handle this case.
> 
> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
> ---
>  criu/cr-restore.c | 38 ++++++++++++++++++++++----------------
>  1 file changed, 22 insertions(+), 16 deletions(-)
> 
> diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> index 298fb69..ed02474 100644
> --- a/criu/cr-restore.c
> +++ b/criu/cr-restore.c
> @@ -164,12 +164,12 @@ static inline int stage_current_participants(int next_stage)
>  	return -1;
>  }
>  
> -static int restore_wait_inprogress_tasks()
> +static int __restore_wait_inprogress_tasks(int participants)
>  {
>  	int ret;
>  	futex_t *np = &task_entries->nr_in_progress;
>  
> -	futex_wait_while_gt(np, 0);
> +	futex_wait_while_gt(np, participants);
>  	ret = (int)futex_get(np);
>  	if (ret < 0) {
>  		set_cr_errno(get_task_cr_err());
> @@ -179,6 +179,22 @@ static int restore_wait_inprogress_tasks()
>  	return 0;
>  }
>  
> +static int restore_wait_inprogress_tasks()
> +{
> +	return __restore_wait_inprogress_tasks(0);
> +}
> +
> +/* Wait all tasks except the current one */
> +static int restore_wait_other_tasks()
> +{
> +	int participants, stage;
> +
> +	stage = futex_get(&task_entries->start);
> +	participants = stage_current_participants(stage);
> +
> +	return __restore_wait_inprogress_tasks(participants);
> +}
> +
>  static inline void __restore_switch_stage_nw(int next_stage)
>  {
>  	futex_set(&task_entries->nr_in_progress,
> @@ -200,18 +216,6 @@ static int restore_switch_stage(int next_stage)
>  	return restore_wait_inprogress_tasks();
>  }
>  
> -/* Wait all tasks except the current one */
> -static void restore_wait_other_tasks()
> -{
> -	int participants, stage;
> -
> -	stage = futex_get(&task_entries->start);
> -	participants = stage_current_participants(stage);
> -
> -	futex_wait_while_gt(&task_entries->nr_in_progress,
> -				participants);
> -}
> -
>  static int restore_finish_ns_stage(int from, int to)
>  {
>  	if (root_ns_mask)
> @@ -1826,7 +1830,8 @@ static int restore_task_with_children(void *_arg)
>  		 *
>  		 * It means that all tasks entered into their namespaces.
>  		 */
> -		restore_wait_other_tasks();
> +		if (restore_wait_other_tasks())
> +			goto err;
>  		fini_restore_mntns();
>  		__restore_switch_stage(CR_STATE_RESTORE);
>  	} else {
> @@ -3333,7 +3338,8 @@ static int sigreturn_restore(pid_t pid, struct task_restore_args *task_args, uns
>  
>  	if (current->parent == NULL) {
>  		/* Wait when all tasks restored all files */
> -		restore_wait_other_tasks();
> +		if (restore_wait_other_tasks())
> +			goto err;
>  	}
>  
>  	/*
> -- 
> 2.9.4
>