[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