[CRIU] [PATCH 3/4] mount: handle mnt_flags and sb_flags separatly
Pavel Emelyanov
xemul at parallels.com
Thu Aug 13 08:34:40 PDT 2015
On 08/11/2015 06:33 PM, Andrey Vagin wrote:
> They both can container the MS_READONLY flag. And in one case it will be
> read-only bind-mount and in another case it will be read-only
> super-block.
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> include/proc_parse.h | 1 +
> mount.c | 27 +++++++++++++++++++--------
> proc_parse.c | 2 +-
> protobuf/mnt.proto | 2 ++
> 4 files changed, 23 insertions(+), 9 deletions(-)
>
> diff --git a/include/proc_parse.h b/include/proc_parse.h
> index 42f8893..ed68c95 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -118,6 +118,7 @@ struct mount_info {
> char *mountpoint;
> char *ns_mountpoint;
> unsigned flags;
> + unsigned sb_flags;
OK, let's look at random mountinfo entry
37 17 0:13 / /dev/mqueue rw,relatime shared:24 - mqueue mqueue rw
The rw.relatime is mountpoint flags and the trailing rw is sb flags.
In old version of criu wil restore relatime with the single mount()
call. With this patch will mount mqueue with RW flag and then call
remount(MS_REMOUNT | MS_BIND | MS_RELATIME). Will this create the
same mountinfo entry?
> int master_id;
> int shared_id;
> struct fstype *fstype;
> diff --git a/mount.c b/mount.c
> index 344d646..4589399 100644
> --- a/mount.c
> +++ b/mount.c
> @@ -1598,6 +1598,8 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img)
> me.root_dev = pm->s_dev;
> me.parent_mnt_id = pm->parent_mnt_id;
> me.flags = pm->flags;
> + me.sb_flags = pm->sb_flags;
> + me.has_sb_flags = true;
> me.mountpoint = pm->mountpoint + 1;
> me.source = pm->source;
> me.options = pm->options;
> @@ -1806,14 +1808,22 @@ static char *resolve_source(struct mount_info *mi)
>
> static int restore_shared_options(struct mount_info *mi, bool private, bool shared, bool slave)
> {
> + unsigned int mflags = MS_SHARED | MS_SLAVE | MS_PRIVATE;
> +
> pr_debug("%d:%s private %d shared %d slave %d\n",
> mi->mnt_id, mi->mountpoint, private, shared, slave);
>
> - if (mi->flags & MS_UNBINDABLE) {
> - if (shared || slave)
> - pr_warn("%s has both unbindable and sharing, ignoring unbindable\n", mi->mountpoint);
> - else
> - return mount(NULL, mi->mountpoint, NULL, MS_UNBINDABLE, NULL);
> +
> + mflags = mi->flags & (~mflags);
> +
> + if ((mi->flags & MS_UNBINDABLE) && (shared || slave)) {
> + pr_warn("%s has both unbindable and sharing, ignoring unbindable\n", mi->mountpoint);
> + mflags &= ~MS_UNBINDABLE;
> + }
> +
> + if (mount(NULL, mi->mountpoint, NULL, MS_REMOUNT | MS_BIND | mflags, NULL)) {
Can we save an extra mount() call in case plain mountpoint creation
sets mount flags correctly?
> + pr_perror("Unable to restore mount flags: %x\n", mi->flags);
> + return -1;
> }
>
> if (private && mount(NULL, mi->mountpoint, NULL, MS_PRIVATE, NULL)) {
> @@ -1935,10 +1945,10 @@ skip_parent:
>
> static int do_new_mount(struct mount_info *mi)
> {
> - unsigned long mflags = MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE;
> + unsigned long mflags = 0;
> char *src;
> struct fstype *tp = mi->fstype;
> - bool remount_ro = (tp->restore && mi->flags & MS_RDONLY);
> + bool remount_ro = (tp->restore && mi->sb_flags & MS_RDONLY);
>
> src = resolve_source(mi);
> if (!src)
> @@ -1948,7 +1958,7 @@ static int do_new_mount(struct mount_info *mi)
> mflags |= MS_RDONLY;
>
> if (mount(src, mi->mountpoint, tp->name,
> - mi->flags & ~mflags, mi->options) < 0) {
> + mi->sb_flags & ~mflags, mi->options) < 0) {
> pr_perror("Can't mount at %s", mi->mountpoint);
> return -1;
> }
> @@ -2324,6 +2334,7 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
> pm->parent_mnt_id = me->parent_mnt_id;
> pm->s_dev = me->root_dev;
> pm->flags = me->flags;
> + pm->sb_flags = me->sb_flags;
> pm->shared_id = me->shared_id;
> pm->master_id = me->master_id;
> pm->need_plugin = me->with_plugin;
> diff --git a/proc_parse.c b/proc_parse.c
> index 1f58f7f..10fb2df 100644
> --- a/proc_parse.c
> +++ b/proc_parse.c
> @@ -1078,7 +1078,7 @@ static int parse_mountinfo_ent(char *str, struct mount_info *new, char **fsname)
> if (!new->options)
> goto err;
>
> - if (parse_sb_opt(opt, &new->flags, new->options))
> + if (parse_sb_opt(opt, &new->sb_flags, new->options))
> goto err;
>
> ret = 0;
> diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto
> index 6e58e1d..c6a1787 100644
> --- a/protobuf/mnt.proto
> +++ b/protobuf/mnt.proto
> @@ -41,4 +41,6 @@ message mnt_entry {
>
> optional string fsname = 14;
> optional bool internal_sharing = 15;
> +
> + optional uint32 sb_flags = 16 [(criu).hex = true];
> }
>
More information about the CRIU
mailing list