mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +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;
|
char *src;
|
||||||
struct fstype *tp = mi->fstype;
|
struct fstype *tp = mi->fstype;
|
||||||
struct mount_info *t;
|
|
||||||
|
|
||||||
src = resolve_source(mi);
|
src = resolve_source(mi);
|
||||||
if (!src)
|
if (!src)
|
||||||
return -1;
|
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,
|
if (mount(src, mi->mountpoint, tp->name,
|
||||||
mi->flags & (~MS_SHARED), mi->options) < 0) {
|
mi->flags & (~MS_SHARED), mi->options) < 0) {
|
||||||
pr_perror("Can't mount at %s", mi->mountpoint);
|
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 */
|
/* The root mount */
|
||||||
if (!mi->parent)
|
if (!mi->parent)
|
||||||
return true;
|
return true;
|
||||||
|
if (mi->is_ns_root)
|
||||||
/*
|
|
||||||
* Private root mounts can be mounted at any time
|
|
||||||
*/
|
|
||||||
if (!mi->master_id && fsroot_mounted(mi))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/*
|
if (mi->master_id && mi->bind == NULL)
|
||||||
* Other mounts can be mounted only if they have
|
return false;
|
||||||
* 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)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
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)
|
static int do_mount_root(struct mount_info *mi)
|
||||||
|
Reference in New Issue
Block a user