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

Pavel Emelyanov xemul at parallels.com
Fri Aug 14 03:06:32 PDT 2015


On 08/13/2015 09:05 PM, Andrew Vagin wrote:
> 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);
> ....

So after the patch the whole mount tree will be restored differently as compared
as it used to. Right?

>>
>>>  	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.

Thanks!



More information about the CRIU mailing list