[CRIU] [PATCH] restore: fix race in calculation of a number of zombies

Tycho Andersen tycho.andersen at canonical.com
Mon Aug 3 06:32:04 PDT 2015


On Mon, Aug 03, 2015 at 02:37:55PM +0300, Andrew Vagin wrote:
> Currently each task subtracts number of zombies from
> task_entries->nr_threads without locks, so if two tasks will do this
> operation concurrently, the result may be unpredictable.
> 
> https://github.com/xemul/criu/issues/13
> 
> Cc: Tycho Andersen <tycho.andersen at canonical.com>

Whoops, sorry about that,

Acked-by: Tycho Andersen <tycho.andersen at canonical.com>

> Signed-off-by: Andrew Vagin <avagin at openvz.org>
> ---
>  cr-restore.c       | 3 +++
>  include/rst_info.h | 1 +
>  pie/restorer.c     | 3 +--
>  3 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/cr-restore.c b/cr-restore.c
> index f7c13a8..cece908 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -1838,6 +1838,8 @@ static int restore_root_task(struct pstree_item *init)
>  	if (ret < 0)
>  		goto out_kill;
>  
> +	task_entries->nr_threads -= atomic_read(&task_entries->nr_zombies);
> +
>  	ret = stop_usernsd();
>  	if (ret < 0)
>  		goto out_kill;
> @@ -1940,6 +1942,7 @@ static int prepare_task_entries(void)
>  	task_entries->nr_threads = 0;
>  	task_entries->nr_tasks = 0;
>  	task_entries->nr_helpers = 0;
> +	atomic_set(&task_entries->nr_zombies, 0);
>  	futex_set(&task_entries->start, CR_STATE_RESTORE_NS);
>  	mutex_init(&task_entries->userns_sync_lock);
>  
> diff --git a/include/rst_info.h b/include/rst_info.h
> index 0e8dc97..b72e5d0 100644
> --- a/include/rst_info.h
> +++ b/include/rst_info.h
> @@ -7,6 +7,7 @@
>  
>  struct task_entries {
>  	int nr_threads, nr_tasks, nr_helpers;
> +	atomic_t nr_zombies;
>  	futex_t nr_in_progress;
>  	futex_t start;
>  	atomic_t cr_err;
> diff --git a/pie/restorer.c b/pie/restorer.c
> index 3bdb5a3..d84a5c0 100644
> --- a/pie/restorer.c
> +++ b/pie/restorer.c
> @@ -803,8 +803,7 @@ static int wait_zombies(struct task_restore_args *task_args)
>  {
>  	int i;
>  
> -	task_entries->nr_threads -= task_args->zombies_n;
> -	task_entries->nr_tasks -= task_args->zombies_n;
> +	atomic_add(task_args->zombies_n, &task_entries->nr_zombies);
>  
>  	for (i = 0; i < task_args->zombies_n; i++) {
>  		if (sys_waitid(P_PID, task_args->zombies[i], NULL, WNOWAIT | WEXITED, NULL) < 0) {
> -- 
> 2.4.3
> 


More information about the CRIU mailing list