[CRIU] [PATCH 1/5] mount: save the result of mnt_is_overmounted

Andrey Vagin avagin at virtuozzo.com
Wed Sep 26 23:35:53 MSK 2018


On Mon, Sep 17, 2018 at 02:47:53PM +0300, Pavel Tikhomirov wrote:
> On restore we change mounts tree topology and paths in find_remap_mounts
> thus mns_is_overmounted does not account remaped overmounts. So to know
> which mounts will be actually overmounted after restore we need two much
> effort, better prepare these info in advance.
> 
> That also should improve performance of mnt_is_overmounted on dump,
> as we reuse calculations from previous calls.
> 
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
>  criu/include/mount.h |  2 ++
>  criu/mount.c         | 36 ++++++++++++++++++++++++++++++------
>  2 files changed, 32 insertions(+), 6 deletions(-)
> 
> diff --git a/criu/include/mount.h b/criu/include/mount.h
> index ca17b059a..e7d026264 100644
> --- a/criu/include/mount.h
> +++ b/criu/include/mount.h
> @@ -70,6 +70,8 @@ struct mount_info {
>  
>  	struct list_head	postpone;
>  
> +	int			is_overmounted;
> +
>  	void			*private;	/* associated filesystem data */
>  };
>  
> diff --git a/criu/mount.c b/criu/mount.c
> index bdc39b530..ba202f0c9 100644
> --- a/criu/mount.c
> +++ b/criu/mount.c
> @@ -1152,17 +1152,29 @@ static int get_clean_fd(struct mount_info *mi)
>   * root of our mount namespace as it is covered by other mount.
>   * mnt_is_overmounted() checks if mount is not visible.
>   */
> -static bool mnt_is_overmounted(struct mount_info *mi)
> +static int mnt_is_overmounted(struct mount_info *mi)

Why do you change a type?

>  {
>  	struct mount_info *t, *c, *m = mi;
>  
> +	if (mi->is_overmounted != -1)
> +		goto exit;
> +
> +	mi->is_overmounted = 0;
> +
>  	while (m->parent) {
> +		if (mi->parent->is_overmounted == 1) {
> +			mi->is_overmounted = 1;
> +			goto exit;
> +		}
> +
>  		/* Check there is no sibling-overmount */
>  		list_for_each_entry(t, &m->parent->children, siblings) {
>  			if (m == t)
>  				continue;
> -			if (issubpath(m->mountpoint, t->mountpoint))
> -				return true;
> +			if (issubpath(m->mountpoint, t->mountpoint)) {
> +				mi->is_overmounted = 1;
> +				goto exit;
> +			}
>  		}
>  
>  		/*
> @@ -1175,10 +1187,19 @@ static bool mnt_is_overmounted(struct mount_info *mi)
>  
>  	/* Check there is no children-overmount */
>  	list_for_each_entry(c, &mi->children, siblings)
> -		if (!strcmp(c->mountpoint, mi->mountpoint))
> -			return true;
> +		if (!strcmp(c->mountpoint, mi->mountpoint)) {
> +			mi->is_overmounted = 1;
> +			goto exit;
> +		}
>  
> -	return false;
> +exit:
> +	return mi->is_overmounted;
> +}
> +
> +static int set_is_overmounted(struct mount_info *mi)
> +{
> +	mnt_is_overmounted(mi);
> +	return 0;
>  }
>  
>  /*
> @@ -2723,6 +2744,7 @@ struct mount_info *mnt_entry_alloc()
>  	new = xzalloc(sizeof(struct mount_info));
>  	if (new) {
>  		new->fd = -1;
> +		new->is_overmounted = -1;
>  		INIT_LIST_HEAD(&new->children);
>  		INIT_LIST_HEAD(&new->siblings);
>  		INIT_LIST_HEAD(&new->mnt_slave_list);
> @@ -3160,6 +3182,8 @@ static int populate_mnt_ns(void)
>  	if (validate_mounts(mntinfo, false))
>  		return -1;
>  
> +	mnt_tree_for_each(pms, set_is_overmounted);
> +
>  	if (find_remap_mounts(pms))
>  		return -1;
>  
> -- 
> 2.17.1
> 



More information about the CRIU mailing list