[CRIU] [PATCH 3/3] mnt: Handle external bind mounts according to --ext-mount option

Pavel Emelyanov xemul at parallels.com
Tue Jun 3 09:30:32 PDT 2014


For now only support the "without arguments" case.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>

---
 include/proc_parse.h |  1 +
 mount.c              | 55 +++++++++++++++++++++++++++++++++++++++++++++++-----
 protobuf/mnt.proto   |  1 +
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/include/proc_parse.h b/include/proc_parse.h
index 09c9efd..e1e5c81 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -118,6 +118,7 @@ struct mount_info {
 	char		*options;
 	bool		mounted;
 	bool		need_plugin;
+	bool		ext_mount;
 	int		is_file;
 	bool		is_ns_root;
 	struct mount_info *next;
diff --git a/mount.c b/mount.c
index c407589..de6b810 100644
--- a/mount.c
+++ b/mount.c
@@ -308,6 +308,18 @@ static void mnt_tree_show(struct mount_info *tree, int off)
 	pr_info("%*s<--\n", off, "");
 }
 
+static int try_dump_ext_mount(struct mount_info *info)
+{
+	if (opts.ext_mount_mode == EXT_MOUNT_OK) {
+		pr_info("Mount point %s is allowed to be external\n",
+				info->mountpoint);
+		info->ext_mount = true;
+		return 0;
+	}
+
+	return -ENOTSUP;
+}
+
 static int validate_mounts(struct mount_info *info, bool for_dump)
 {
 	struct mount_info *m, *t;
@@ -369,8 +381,10 @@ static int validate_mounts(struct mount_info *info, bool for_dump)
 					ret = cr_plugin_dump_ext_mount(m->mountpoint + 1, m->mnt_id);
 					if (ret == 0)
 						m->need_plugin = true;
+					else if (ret == -ENOTSUP)
+						ret = try_dump_ext_mount(m);
 				} else {
-					if (m->need_plugin)
+					if (m->need_plugin || m->ext_mount)
 						/*
 						 * plugin should take care of this one 
 						 * in restore_ext_mount
@@ -841,6 +855,10 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd)
 		me.has_with_plugin = true;
 		me.with_plugin = true;
 	}
+	if (pm->ext_mount) {
+		me.has_ext_mount = true;
+		me.ext_mount = true;
+	}
 
 	if (pb_write_one(fd, &me, PB_MNT))
 		return -1;
@@ -1178,12 +1196,38 @@ static int do_new_mount(struct mount_info *mi)
 	return 0;
 }
 
+static int try_ext_bind_mount(struct mount_info *mi)
+{
+	if (opts.ext_mount_mode == EXT_MOUNT_NONE) {
+		pr_err("Restoring external bind mount %s is not enabled\n",
+				mi->mountpoint);
+		return -1;
+	}
+
+	if (opts.ext_mount_mode != EXT_MOUNT_OK)
+		return -1;
+
+	pr_info("Bind-mounting %s to %s\n", mi->root, mi->mountpoint);
+	if (mount(mi->root, mi->mountpoint, NULL, MS_BIND, NULL)) {
+		pr_perror("Can't bind ext mount");
+		return -1;
+	}
+
+	return 0;
+}
+
 static int restore_ext_mount(struct mount_info *mi)
 {
 	int ret;
 
-	pr_debug("Restoring external bind mount %s\n", mi->mountpoint);
-	ret = cr_plugin_restore_ext_mount(mi->mnt_id, mi->mountpoint, "/", NULL);
+	if (mi->ext_mount) {
+		pr_debug("Restoring native external bind-mount %s\n", mi->mountpoint);
+		ret = try_ext_bind_mount(mi);
+	} else {
+		pr_debug("Restoring external bind mount %s\n", mi->mountpoint);
+		ret = cr_plugin_restore_ext_mount(mi->mnt_id, mi->mountpoint, "/", NULL);
+	}
+
 	if (ret)
 		pr_perror("Can't restore ext mount (%d)\n", ret);
 	return ret;
@@ -1193,7 +1237,7 @@ static int do_bind_mount(struct mount_info *mi)
 {
 	bool shared = mi->shared_id && mi->shared_id == mi->bind->shared_id;
 
-	if (!mi->need_plugin) {
+	if (!mi->need_plugin && !mi->ext_mount) {
 		char rpath[PATH_MAX];
 		int tok = 0;
 
@@ -1254,7 +1298,7 @@ static bool can_mount_now(struct mount_info *mi)
 	 * the master mount (see propagate_mount) or if we
 	 * expect a plugin to help us.
 	 */
-	if (mi->bind || mi->need_plugin)
+	if (mi->bind || mi->need_plugin || mi->ext_mount)
 		return true;
 
 	return false;
@@ -1508,6 +1552,7 @@ static int collect_mnt_from_image(struct mount_info **pms, struct ns_id *nsid)
 		pm->shared_id		= me->shared_id;
 		pm->master_id		= me->master_id;
 		pm->need_plugin		= me->with_plugin;
+		pm->ext_mount		= me->ext_mount;
 		pm->is_ns_root		= is_root(me->mountpoint);
 
 		/* FIXME: abort unsupported early */
diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto
index ab85de7..44a6566 100644
--- a/protobuf/mnt.proto
+++ b/protobuf/mnt.proto
@@ -25,4 +25,5 @@ message mnt_entry {
 	optional uint32		master_id		= 11;
 
 	optional bool		with_plugin		= 12;
+	optional bool		ext_mount		= 13;
 }
-- 
1.8.4.2


More information about the CRIU mailing list