mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-08-01 22:33:30 +00:00
mount: handle mnt_flags and sb_flags separatly (v4)
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. v2: set mnt and sb for one call of mount() when it's posiable v3: return a comment which was deleted by mistake v4: Fix the sentense about restoring mnt flags Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
b7d393ff63
commit
1174a2ad0f
4 changed files with 47 additions and 12 deletions
|
|
@ -47,6 +47,7 @@ struct mount_info {
|
|||
char *mountpoint;
|
||||
char *ns_mountpoint;
|
||||
unsigned flags;
|
||||
unsigned sb_flags;
|
||||
int master_id;
|
||||
int shared_id;
|
||||
struct fstype *fstype;
|
||||
|
|
|
|||
55
mount.c
55
mount.c
|
|
@ -31,6 +31,7 @@
|
|||
#include "protobuf/mnt.pb-c.h"
|
||||
|
||||
#define AUTODETECTED_MOUNT "CRIU:AUTOGENERATED"
|
||||
#define MS_PROPAGATE (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE | MS_SLAVE)
|
||||
|
||||
#undef LOG_PREFIX
|
||||
#define LOG_PREFIX "mnt: "
|
||||
|
|
@ -1596,6 +1597,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;
|
||||
|
|
@ -1936,26 +1939,53 @@ skip_parent:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here are a set of flags which we know how to handle for the one mount call.
|
||||
* All of them except MS_RDONLY are set only as mnt flags.
|
||||
* MS_RDONLY is set for both mnt ans sb flags, so we can restore it for one
|
||||
* mount call only if it set for both masks.
|
||||
*/
|
||||
#define MS_MNT_KNOWN_FLAGS (MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME | \
|
||||
MS_NODIRATIME | MS_RELATIME | MS_RDONLY)
|
||||
static int do_new_mount(struct mount_info *mi)
|
||||
{
|
||||
unsigned long mflags = MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE;
|
||||
unsigned long sflags = mi->sb_flags;
|
||||
unsigned long mflags = mi->flags & (~MS_PROPAGATE);
|
||||
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)
|
||||
return -1;
|
||||
|
||||
if (remount_ro)
|
||||
mflags |= MS_RDONLY;
|
||||
sflags &= ~MS_RDONLY;
|
||||
|
||||
if (mount(src, mi->mountpoint, tp->name,
|
||||
mi->flags & ~mflags, mi->options) < 0) {
|
||||
/* Merge superblock and mount flags if it's posiable */
|
||||
if (!(mflags & ~MS_MNT_KNOWN_FLAGS) && ((sflags ^ mflags) & MS_RDONLY)) {
|
||||
sflags |= mflags;
|
||||
mflags = 0;
|
||||
}
|
||||
|
||||
if (mount(src, mi->mountpoint, tp->name, sflags, mi->options) < 0) {
|
||||
pr_perror("Can't mount at %s", mi->mountpoint);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tp->restore && tp->restore(mi))
|
||||
return -1;
|
||||
|
||||
if (remount_ro)
|
||||
return mount(NULL, mi->mountpoint, tp->name,
|
||||
MS_REMOUNT | MS_RDONLY, NULL);
|
||||
|
||||
if (mflags && mount(NULL, mi->mountpoint, NULL,
|
||||
MS_REMOUNT | MS_BIND | mflags, NULL)) {
|
||||
pr_perror("Unable to apply bind-mount options\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (restore_shared_options(mi, !mi->shared_id && !mi->master_id,
|
||||
mi->shared_id,
|
||||
mi->master_id))
|
||||
|
|
@ -1963,12 +1993,6 @@ static int do_new_mount(struct mount_info *mi)
|
|||
|
||||
mi->mounted = true;
|
||||
|
||||
if (tp->restore && tp->restore(mi))
|
||||
return -1;
|
||||
|
||||
if (remount_ro)
|
||||
return mount(NULL, mi->mountpoint, tp->name,
|
||||
MS_REMOUNT | MS_RDONLY, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1991,6 +2015,7 @@ static int do_bind_mount(struct mount_info *mi)
|
|||
|
||||
if (!mi->need_plugin) {
|
||||
char *root, *cut_root, rpath[PATH_MAX];
|
||||
unsigned long mflags;
|
||||
|
||||
if (mi->external) {
|
||||
/*
|
||||
|
|
@ -2044,6 +2069,13 @@ do_bind:
|
|||
return -1;
|
||||
}
|
||||
|
||||
mflags = mi->flags & (~MS_PROPAGATE);
|
||||
if (!mi->bind || mflags != (mi->bind->flags & (~MS_PROPAGATE)))
|
||||
if (mount(NULL, mi->mountpoint, NULL, MS_BIND | MS_REMOUNT | mflags, NULL)) {
|
||||
pr_perror("Can't mount at %s", mi->mountpoint);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(mi->deleted)) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (rmdir(root)) {
|
||||
|
|
@ -2367,6 +2399,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;
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,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;
|
||||
|
|
|
|||
|
|
@ -43,4 +43,5 @@ message mnt_entry {
|
|||
optional bool internal_sharing = 15;
|
||||
|
||||
optional bool deleted = 16;
|
||||
optional uint32 sb_flags = 17 [(criu).hex = true];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue