[CRIU] [PATCH 9/9] mounts: handle shared and slave mounts
Andrey Vagin
avagin at openvz.org
Tue Jul 9 07:05:56 EDT 2013
The idea is simple. If a mount can't be mounted now, we will try to
mount it later.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
include/proc_parse.h | 1 +
mount.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 85bde36..845b901 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -110,6 +110,7 @@ struct mount_info {
struct fstype *fstype;
char *source;
char *options;
+ bool mounted;
struct mount_info *next;
/* tree linkage */
diff --git a/mount.c b/mount.c
index 42d37db..219752c 100644
--- a/mount.c
+++ b/mount.c
@@ -666,12 +666,44 @@ static int do_new_mount(struct mount_info *mi)
if (!src)
return -1;
+ if (!fsroot_mounted(mi) || (mi->flags & MS_SLAVE)) {
+ pr_debug("Postpone %s\n", mi->mountpoint);
+ 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("Postpone %s\n", mi->mountpoint);
+ return 1;
+ }
+ list_for_each_entry(t, &mi->parent->mnt_slave_list, mnt_slave)
+ if (!t->mounted) {
+ pr_debug("Postpone %s\n", mi->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;
}
+ if (mi->flags & MS_SHARED) {
+ if (mount(NULL, mi->mountpoint, NULL, MS_SHARED, NULL) < 0) {
+ pr_perror("Can't mark %s as shared", mi->mountpoint);
+ return -1;
+ }
+ }
+
+ mi->mounted = true;
+
if (tp->restore && tp->restore(mi))
return -1;
@@ -685,14 +717,36 @@ static int do_bind_mount(struct mount_info *mi)
{
char rpath[PATH_MAX];
+ if (mi->bind == NULL) {
+ pr_debug("Postpone %s\n", mi->mountpoint);
+ return 1;
+ }
+
snprintf(rpath, sizeof(rpath), "%s%s", mi->bind->mountpoint, mi->root);
+ pr_info("Bind %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;
}
+ if ((!(mi->bind->flags & MS_SHARED)) && (mi->flags & MS_SHARED)) {
+ pr_debug("share %d %d", mi->bind->flags & MS_SHARED, mi->flags & MS_SHARED);
+ if (mount(NULL, mi->mountpoint, NULL, MS_SHARED, NULL) < 0) {
+ pr_perror("Can't mark %s as shared", mi->mountpoint);
+ return -1;
+ }
+ }
+
+ if (mi->flags & MS_SLAVE) {
+ if (mount(NULL, mi->mountpoint, NULL, MS_SLAVE, NULL) < 0) {
+ pr_perror("Can't mark %s as shared", mi->mountpoint);
+ return -1;
+ }
+ }
+
if (propogate_mount(mi))
return -1;
@@ -706,7 +760,7 @@ static int do_mount_one(struct mount_info *mi)
pr_debug("\tMounting %s @%s\n", mi->fstype->name, mi->mountpoint);
- if (fsroot_mounted(mi))
+ if (!mi->bind)
return do_new_mount(mi);
else
return do_bind_mount(mi);
@@ -811,6 +865,7 @@ struct mount_info *mnt_entry_alloc()
INIT_LIST_HEAD(&new->mnt_slave_list);
INIT_LIST_HEAD(&new->mnt_share);
INIT_LIST_HEAD(&new->mnt_bind);
+ INIT_LIST_HEAD(&new->postpone);
new->mnt_master = NULL;
}
return new;
--
1.8.3.1
More information about the CRIU
mailing list