[CRIU] [PATCH 3/4] mount: handle mnt_flags and sb_flags separatly

Andrew Vagin avagin at gmail.com
Thu Aug 13 11:05:26 PDT 2015


On Thu, Aug 13, 2015 at 06:34:40PM +0300, Pavel Emelyanov wrote:
> 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?

No, it will not. We use MS_REMOUNT.

do_mount:
...
        if (flags & MS_REMOUNT)
                retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
                                    data_page);
        else if (flags & MS_BIND)
                retval = do_loopback(&path, dev_name, flags & MS_REC);
...

do_remount
...
        if (flags & MS_BIND)
                err = change_mount_flags(path->mnt, flags);
        else if (!capable(CAP_SYS_ADMIN))
                err = -EPERM;
        else
                err = do_remount_sb(sb, flags, data, 0);
....
> 
> >  	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?

I will try.



More information about the CRIU mailing list