[CRIU] [PATCH 7/9] mounts: if a mount can't be mounted, it is queued in postpone list
Pavel Emelyanov
xemul at parallels.com
Tue Jul 9 12:44:07 EDT 2013
On 07/09/2013 03:05 PM, Andrey Vagin wrote:
> Try to restore mounts while a postpone list isn't empty and check
> that each iteration has some progress, otherwice it will fails for
> preventing infinite loops
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> include/proc_parse.h | 2 ++
> mount.c | 40 ++++++++++++++++++++++++++++++++++++----
> 2 files changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/include/proc_parse.h b/include/proc_parse.h
> index 1325424..85bde36 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -123,6 +123,8 @@ struct mount_info {
> struct list_head mnt_slave_list;/* list of slave mounts */
> struct list_head mnt_slave; /* slave list entry */
> struct mount_info *mnt_master; /* slave is on master->mnt_slave_list */
> +
> + struct list_head postpone;
> };
>
> struct proc_posix_timer {
> diff --git a/mount.c b/mount.c
> index 0609ded..fae9513 100644
> --- a/mount.c
> +++ b/mount.c
> @@ -533,12 +533,25 @@ int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset)
> return 0;
> }
>
> -#define MNT_TREE_WALK(_r, _el, _fn_f, _fn_r) do { \
> +static int mount_progress;
> +
> +#define MNT_TREE_WALK(_r, _el, _fn_f, _fn_r, _plist) do { \
> struct mount_info *_mi = _r; \
> \
> while (1) { \
> - if (_fn_f(_mi)) \
> + int ret; \
> + \
> + ret = _fn_f(_mi); \
> + if (ret < 0) \
> return -1; \
> + else if (ret > 0) { \
> + list_add_tail(&_mi->postpone, _plist); \
_plist can be NULL here, can't it?
> + goto up; \
> + } \
> + \
> + list_del(&_mi->postpone); \
> + mount_progress++; \
> + \
> if (!list_empty(&_mi->children)) { \
> _mi = list_entry(_mi->children._el, \
> struct mount_info, siblings); \
> @@ -564,13 +577,32 @@ int dump_mnt_ns(int ns_pid, struct cr_fdset *fdset)
> static int mnt_tree_for_each(struct mount_info *m,
> int (*fn)(struct mount_info *))
> {
> - MNT_TREE_WALK(m, next, fn, MNT_WALK_NONE);
> + static LIST_HEAD(postpone);
> +
> + list_add(&m->postpone, &postpone);
> +
> + while (!list_empty(&postpone)) {
> + int old = mount_progress;
> + list_for_each_entry(m, &postpone, postpone)
> + MNT_TREE_WALK(m, next, fn, MNT_WALK_NONE, &postpone);
Can you please rewrite this using either do { } while (!list_empty) or
use backwards goto for easier reading.
> + if (old == mount_progress) {
> + 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;
> + }
> + }
> +
> + return 0;
> }
>
> static int mnt_tree_for_each_reverse(struct mount_info *m,
> int (*fn)(struct mount_info *))
> {
> - MNT_TREE_WALK(m, prev, MNT_WALK_NONE, fn);
> + MNT_TREE_WALK(m, prev, MNT_WALK_NONE, fn, (struct list_head *) NULL);
> }
>
> static char *resolve_source(struct mount_info *mi)
>
More information about the CRIU
mailing list