[CRIU] [PATCH 03/10] mounts: if a mount can't be mounted, it is queued in postpone list (v2)

Pavel Emelyanov xemul at parallels.com
Thu Aug 29 08:59:45 EDT 2013


> @@ -597,10 +617,46 @@ int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset)
>  #define MNT_WALK_NONE	0 &&
>  
>  
> -static int mnt_tree_for_each(struct mount_info *m,
> +static int mnt_tree_for_each(struct mount_info *start,
>  		int (*fn)(struct mount_info *))
>  {
> -	MNT_TREE_WALK(m, next, fn, MNT_WALK_NONE);
> +	static LIST_HEAD(postpone);
> +	struct mount_info *first_wo_progress = NULL;
> +	int old_progress = mount_progress;
> +
> +again:
> +	pr_debug("Start with %d:%s\n", start->mnt_id, start->mountpoint);
> +
> +	MNT_TREE_WALK(start, next, fn, MNT_WALK_NONE, &postpone);
> +
> +	if (old_progress == mount_progress) {
> +		if (first_wo_progress == NULL)
> +			first_wo_progress = start;
> +	} else {
> +		first_wo_progress = NULL;
> +		old_progress = mount_progress;
> +	}
> +
> +	if (!list_empty(&postpone)) {
> +		start = list_first_entry(&postpone, struct mount_info, postpone);
> +
> +		/*
> +		 * If we need to start from the same point in a second time
> +		 * w/o intermediate progress, we are in an infinite loop.
> +		 */
> +		if (first_wo_progress == start) {
> +			struct mount_info *m;
> +
> +			pr_err("A few mount points can't be mounted");
> +			list_for_each_entry(m, &postpone, postpone) {
> +				pr_err("%d:%d %s %s %s\n", m->mnt_id,
> +					m->parent_mnt_id, m->root,
> +					m->mountpoint, m->source);
> +			}
> +			return -1;
> +		}
> +		goto again;
> +	}

        LIST_HEAD(pp);
	LIST_HEAD(pp2);
        mounted = 0;

        list_add(&start->list, &pp);
again:
        list_for_each_entry_safe(mnt, &pp, list)
                MNT_TREE_WALK(..., &pp2, &mounted /* ++-ed inside */);

        if (!mounted)
                return -ELOOP;

        list_splice_init(&pp2, &pp);
        goto again;

Hm?


More information about the CRIU mailing list