diff --git a/crtools.c b/crtools.c index 376fd6e6d..7e04655e6 100644 --- a/crtools.c +++ b/crtools.c @@ -205,6 +205,7 @@ int main(int argc, char *argv[], char *envp[]) { "feature", required_argument, 0, 1063 }, { "skip-mnt", required_argument, 0, 1064}, { "enable-fs", required_argument, 0, 1065}, + { "enable-external-sharing", no_argument, 0, 1066 }, { }, }; @@ -426,6 +427,9 @@ int main(int argc, char *argv[], char *envp[]) if (!add_fsname_auto(optarg)) return 1; break; + case 1066: + opts.enable_external_sharing = true; + break; case 'M': { char *aux; @@ -654,6 +658,8 @@ usage: " add external mount mapping\n" " -M|--ext-mount-map auto\n" " attempt to autodetect external mount mapings\n" +" --enable-external-sharing\n" +" allow autoresolving mounts with external sharing\n" " --manage-cgroups dump or restore cgroups the process is in\n" " --cgroup-root [controller:]/newroot\n" " change the root cgroup the controller will be\n" diff --git a/include/cr_options.h b/include/cr_options.h index f1cfc848d..29be2c804 100644 --- a/include/cr_options.h +++ b/include/cr_options.h @@ -63,6 +63,7 @@ struct cr_options { char *new_global_cg_root; struct list_head new_cgroup_roots; bool autodetect_ext_mounts; + bool enable_external_sharing; bool aufs; /* auto-deteced, not via cli */ }; diff --git a/include/proc_parse.h b/include/proc_parse.h index a0fee1f46..e5d59d2bd 100644 --- a/include/proc_parse.h +++ b/include/proc_parse.h @@ -130,6 +130,7 @@ struct mount_info { struct ns_id *nsid; struct ext_mount *external; + bool internal_sharing; /* tree linkage */ struct mount_info *parent; diff --git a/mount.c b/mount.c index 8d6c18722..24868f19b 100644 --- a/mount.c +++ b/mount.c @@ -731,6 +731,14 @@ static int resolve_external_mounts(struct mount_info *info) if (!match) continue; + if (m->flags & MS_SHARED) { + if (!opts.enable_external_sharing) + continue; + + if (m->shared_id != match->shared_id) + m->internal_sharing = true; + } + size = strlen(match->mountpoint + 1) + strlen(m->root) + 1; p = xmalloc(sizeof(char) * size); if (!p) @@ -1437,6 +1445,11 @@ static int dump_one_mountpoint(struct mount_info *pm, struct cr_img *img) me.with_plugin = true; } + if (pm->internal_sharing) { + me.has_internal_sharing = true; + me.internal_sharing = true; + } + if (pm->external) { /* * For external mount points dump the mapping's @@ -1778,6 +1791,7 @@ static int restore_ext_mount(struct mount_info *mi) static int do_bind_mount(struct mount_info *mi) { bool shared = 0; + bool force_private_remount = false; if (!mi->need_plugin) { char *root, rpath[PATH_MAX]; @@ -1791,6 +1805,7 @@ static int do_bind_mount(struct mount_info *mi) * to proper location in the namespace we restore. */ root = mi->root; + force_private_remount = mi->internal_sharing; goto do_bind; } @@ -1827,7 +1842,7 @@ do_bind: * shared - the mount is in the same shared group with mi->bind * mi->shared_id && !shared - create a new shared group */ - if (restore_shared_options(mi, !shared && !mi->master_id, + if (restore_shared_options(mi, force_private_remount || (!shared && !mi->master_id), mi->shared_id && !shared, mi->master_id)) return -1; @@ -2139,6 +2154,9 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid) if (!pm->source) goto err; + if (me->has_internal_sharing) + pm->internal_sharing = me->internal_sharing; + /* FIXME: abort unsupported early */ pm->fstype = decode_fstype(me->fstype, me->fsname); diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto index 313610eaf..6f8e7d1e6 100644 --- a/protobuf/mnt.proto +++ b/protobuf/mnt.proto @@ -39,4 +39,5 @@ message mnt_entry { optional bool ext_mount = 13; optional string fsname = 14; + optional bool internal_sharing = 15; }