2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-31 06:15:24 +00:00

mounts: handle shared and slave mounts (v3)

The idea is simple. If a mount can't be mounted now, we will try to
mount it later.

v2: don't wait slaves, they are unmounted anyway
v3: add a comment in do_bind_mount to explain restoring of shared groups
Signed-off-by: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
Andrey Vagin
2013-08-13 17:02:49 +04:00
committed by Pavel Emelyanov
parent 2eedcaabe5
commit f05beddca3

58
mount.c
View File

@@ -730,6 +730,9 @@ static int umount_from_slaves(struct mount_info *mi)
char mpath[PATH_MAX];
list_for_each_entry(t, &mi->parent->mnt_slave_list, mnt_slave) {
if (!t->mounted)
continue;
snprintf(mpath, sizeof(mpath), "%s/%s",
t->mountpoint, basename(mi->mountpoint));
pr_debug("\t\tUmount %s\n", mpath);
@@ -798,13 +801,30 @@ 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, mi->options) < 0) {
mi->flags & (~MS_SHARED), mi->options) < 0) {
pr_perror("Can't mount at %s", mi->mountpoint);
return -1;
}
@@ -812,6 +832,8 @@ static int do_new_mount(struct mount_info *mi)
if (restore_shared_options(mi, 0, mi->shared_id, 0))
return -1;
mi->mounted = true;
if (tp->restore && tp->restore(mi))
return -1;
@@ -820,8 +842,31 @@ static int do_new_mount(struct mount_info *mi)
static int do_bind_mount(struct mount_info *mi)
{
pr_err("No bind mounts at %s\n", mi->mountpoint);
return -1;
char rpath[PATH_MAX];
bool shared = mi->shared_id && mi->shared_id == mi->bind->shared_id;
snprintf(rpath, sizeof(rpath), "%s%s", mi->bind->mountpoint, mi->root);
pr_info("\tBind %s to %s\n", rpath, mi->mountpoint);
if (mount(rpath, mi->mountpoint, NULL,
MS_BIND, NULL) < 0) {
pr_perror("Can't mount at %s", mi->mountpoint);
return -1;
}
/*
* 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->shared_id && !shared,
mi->master_id))
return -1;
mi->mounted = true;
return 0;
}
static int do_mount_one(struct mount_info *mi)
@@ -834,9 +879,14 @@ static int do_mount_one(struct mount_info *mi)
if (mi->mounted)
return 0;
if ((mi->master_id || !fsroot_mounted(mi)) && mi->bind == NULL) {
pr_debug("Postpone slave %s\n", mi->mountpoint);
return 1;
}
pr_debug("\tMounting %s @%s\n", mi->fstype->name, mi->mountpoint);
if (fsroot_mounted(mi))
if (!mi->bind)
ret = do_new_mount(mi);
else
ret = do_bind_mount(mi);