mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
mount: rework can_mount_now() to support bind-mounts of shared mounts
Fedora bind-mounts a part of the root mount to itself. Currently we don't allow to mount children of a shared mount, if other mount from this shared group are not mounted. This patch adds an exclusion for cases, when a child has the same group. We allow to mount a child, if wider mounts are mounted. Signed-off-by: Andrey Vagin <avagin@openvz.org> Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
committed by
Pavel Emelyanov
parent
beeabc3b2b
commit
104d3b84d5
55
mount.c
55
mount.c
@@ -1468,28 +1468,11 @@ static int do_new_mount(struct mount_info *mi)
|
||||
{
|
||||
char *src;
|
||||
struct fstype *tp = mi->fstype;
|
||||
struct mount_info *t;
|
||||
|
||||
src = resolve_source(mi);
|
||||
if (!src)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Wait while all parent are not mounted
|
||||
*
|
||||
* FIXME a child is shared only between parents,
|
||||
* who was present in a moment of birth
|
||||
*/
|
||||
if (mi->parent->flags & MS_SHARED) {
|
||||
list_for_each_entry(t, &mi->parent->mnt_share, mnt_share) {
|
||||
if (!t->mounted) {
|
||||
pr_debug("\t\tPostpone %s due to %s\n",
|
||||
mi->mountpoint, t->mountpoint);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mount(src, mi->mountpoint, tp->name,
|
||||
mi->flags & (~MS_SHARED), mi->options) < 0) {
|
||||
pr_perror("Can't mount at %s", mi->mountpoint);
|
||||
@@ -1585,22 +1568,34 @@ static bool can_mount_now(struct mount_info *mi)
|
||||
/* The root mount */
|
||||
if (!mi->parent)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Private root mounts can be mounted at any time
|
||||
*/
|
||||
if (!mi->master_id && fsroot_mounted(mi))
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Other mounts can be mounted only if they have
|
||||
* the master mount (see propagate_mount) or if we
|
||||
* expect a plugin/ext-mount-map to help us.
|
||||
*/
|
||||
if (mi->bind || mi->need_plugin || mi->external)
|
||||
if (mi->is_ns_root)
|
||||
return true;
|
||||
|
||||
if (mi->master_id && mi->bind == NULL)
|
||||
return false;
|
||||
|
||||
if (!fsroot_mounted(mi) && (mi->bind == NULL && !mi->need_plugin && !mi->external))
|
||||
return false;
|
||||
|
||||
if (mi->parent->shared_id) {
|
||||
struct mount_info *p = mi->parent, *n;
|
||||
|
||||
if (mi->parent->shared_id == mi->shared_id) {
|
||||
int rlen = strlen(mi->root);
|
||||
list_for_each_entry(n, &p->mnt_share, mnt_share)
|
||||
if (strlen(n->root) < rlen && !n->mounted)
|
||||
return false;
|
||||
} else {
|
||||
list_for_each_entry(n, &p->mnt_share, mnt_share)
|
||||
if (!n->mounted)
|
||||
return false;
|
||||
list_for_each_entry(n, &p->mnt_slave_list, mnt_slave)
|
||||
if (!n->mounted)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int do_mount_root(struct mount_info *mi)
|
||||
|
Reference in New Issue
Block a user