[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