[CRIU] [PATCH v7 1/9] restore: Use pstree_pid_cmp helper in pid_rst_prio

Andrey Vagin avagin at virtuozzo.com
Mon Jun 4 21:45:51 MSK 2018


On Wed, May 23, 2018 at 07:06:07PM +0300, Cyrill Gorcunov wrote:
> The pid number is absolutely not a guarantee to
> introduce order relationship into pid set because
> they might be reused. Instead we should consider
> parent->child relationship.

I don't understand this. Could you elaborate with more details?

> 
> Otherwise we might get
> 
>  |  31964  31964  31964       epoll
>  |    585  31964  31964           epoll
>  |    586  31964  31964           epoll
>  |...
>  | (04.797121)    585: Error (criu/eventpoll.c:180): epoll: Unexpected state for tfd (id 0 fd 8)
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
> ---
>  criu/include/pid.h | 12 +++++++++++-
>  criu/pstree.c      | 36 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 47 insertions(+), 1 deletion(-)
> 
> diff --git a/criu/include/pid.h b/criu/include/pid.h
> index 37e39428e0d6..d8869fde0a09 100644
> --- a/criu/include/pid.h
> +++ b/criu/include/pid.h
> @@ -69,13 +69,23 @@ static inline pid_t last_level_pid(struct pid *pid)
>  	return pid->ns[pid->level-1].virt;
>  }
>  
> +extern int pstree_pid_cmp(pid_t a, pid_t b);
> +
>  /*
>   * When we have to restore a shared resource, we mush select which
>   * task should do it, and make other(s) wait for it. In order to
>   * avoid deadlocks, always make task with lower pid be the restorer.
>   */
> -static inline bool pid_rst_prio(unsigned pid_a, unsigned pid_b)
> +static inline bool pid_rst_prio(pid_t pid_a, pid_t pid_b)
>  {
> +	int ret = pstree_pid_cmp(pid_a, pid_b);
> +
> +	if (ret == 1)
> +		return true;
> +	else if (ret == 2)
> +		return false;
> +
> +	/* Fallback into plain pid comparision */
>  	return pid_a < pid_b;
>  }
>  
> diff --git a/criu/pstree.c b/criu/pstree.c
> index 6047d29ccc97..f180b9b221ed 100644
> --- a/criu/pstree.c
> +++ b/criu/pstree.c
> @@ -655,6 +655,42 @@ int fixup_pid_for_children_ns(TaskKobjIdsEntry *ids)
>  	return 0;
>  }
>  
> +/*
> + *  0 -- pids are the same
> + *  1 -- @a is a parent of @b
> + *  2 -- @b is a parent of @a
> + *  3 -- pids are not connected
> + *  -1 -- pid not found
> + */
> +int pstree_pid_cmp(pid_t a, pid_t b)
> +{
> +	struct pstree_item *pstree_a, *pstree_b, *t;
> +	struct pid *pid_a, *pid_b;
> +
> +	if (a == b)
> +		return 0;
> +
> +	pid_a = pstree_pid_by_virt(a);
> +	pid_b = pstree_pid_by_virt(b);
> +	if (!pid_a || !pid_b)
> +		return -1;
> +
> +	pstree_a = pid_a->item;
> +	pstree_b = pid_b->item;
> +
> +	for (t = pstree_b; t->parent; t = t->parent) {
> +		if (t == pstree_a)
> +			return 1;
> +	}
> +
> +	for (t = pstree_a; t->parent; t = t->parent) {
> +		if (t == pstree_b)
> +			return 2;
> +	}
> +
> +	return 3;
> +}
> +
>  static int read_pstree_ids(pid_t pid, TaskKobjIdsEntry **ids)
>  {
>  	struct cr_img *img;
> -- 
> 2.14.3
> 


More information about the CRIU mailing list