[CRIU] [PATCH] mount: handle mnt_flags and sb_flags separatly (v4)
Tycho Andersen
tycho.andersen at canonical.com
Mon Sep 21 12:16:40 PDT 2015
Hi Andrey,
I'm seeing a regression with this, something like:
(00.498962) 1: mnt: Mounting tmpfs @./sys/fs/cgroup (0)
tar: ./cgmanager: Cannot mkdir: Read-only file system
tar: ./blkio: Cannot mkdir: Read-only file system
tar: ./cpu,cpuacct: Cannot mkdir: Read-only file system
tar: ./cpuset: Cannot mkdir: Read-only file system
tar: ./devices: Cannot mkdir: Read-only file system
tar: ./freezer: Cannot mkdir: Read-only file system
tar: ./hugetlb: Cannot mkdir: Read-only file system
tar: ./memory: Cannot mkdir: Read-only file system
tar: ./systemd: Cannot mkdir: Read-only file system
tar: ./net_cls,net_prio: Cannot mkdir: Read-only file system
tar: ./perf_event: Cannot mkdir: Read-only file system
tar: .: Cannot utime: Read-only file system
tar: .: Cannot change ownership to uid 0, gid 0: Read-only file system
tar: Exiting with failure status due to previous errors
(00.503409) 1: Error (util.c:593): exited, status=2
(00.503439) 1: Error (cr-restore.c:1234): 12 exited, status=2
(00.503450) 1: Error (mount.c:1254): mnt: Can't restore tmpfs content
(00.521198) Error (cr-restore.c:1933): Restoring FAILED.
(I wonder if there is some way we can avoid checkpointing this tmpfs since all
that's mounted there is cgroups, but that's a different issue.)
On Fri, Sep 11, 2015 at 04:55:55PM +0300, Andrey Vagin wrote:
> +/*
> + * 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;
> +
> + /* 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,
> - mi->flags & ~mflags, mi->options) < 0) {
> + if (mount(src, mi->mountpoint, tp->name, sflags, mi->options) < 0) {
If sflags has MS_RDONLY here, doesn't that prevent us from doing the restore?
Tycho
> 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))
> @@ -1960,12 +1990,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;
> }
>
> @@ -1988,6 +2012,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) {
> /*
> @@ -2041,6 +2066,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)) {
> @@ -2364,6 +2396,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 3feaa44..82ce102 100644
> --- a/proc_parse.c
> +++ b/proc_parse.c
> @@ -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;
> diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto
> index f79ae46..12582e9 100644
> --- a/protobuf/mnt.proto
> +++ b/protobuf/mnt.proto
> @@ -43,4 +43,5 @@ message mnt_entry {
> optional bool internal_sharing = 15;
>
> optional bool deleted = 16;
> + optional uint32 sb_flags = 17 [(criu).hex = true];
> }
> --
> 2.4.3
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list