[CRIU] [PATCH 5/7] mount: Dump external bind-mounts with plugins

Pavel Emelyanov xemul at parallels.com
Wed Dec 25 04:54:36 PST 2013


External bind mounts are those with source sitting outside of the
current FS view. Such are detected in validate_mounts(), so we
just go ahead and call plugins.

The plugin is provided with the mountpoint to decide whether it's
his or not (what else does the guy need?) and an ID with this it
can identify the mountpoint in /proc. The same ID will be used at
restore time to find the needed restore info.

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 include/criu-plugin.h |  2 ++
 include/plugin.h      |  2 ++
 include/proc_parse.h  |  1 +
 mount.c               | 29 ++++++++++++++++++++++-------
 plugin.c              |  9 +++++++++
 protobuf/mnt.proto    |  2 ++
 6 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/include/criu-plugin.h b/include/criu-plugin.h
index cf6a2c5..a760730 100644
--- a/include/criu-plugin.h
+++ b/include/criu-plugin.h
@@ -32,6 +32,8 @@ typedef int (cr_plugin_restore_unix_sk_t)(int id);
 typedef int (cr_plugin_dump_file_t)(int fd, int id);
 typedef int (cr_plugin_restore_file_t)(int id);
 
+typedef int (cr_plugin_dump_ext_mount_t)(char *mountpoint, int id);
+
 /* Public API */
 extern int criu_get_image_dir(void);
 
diff --git a/include/plugin.h b/include/plugin.h
index 6c8ab82..9a077d9 100644
--- a/include/plugin.h
+++ b/include/plugin.h
@@ -14,4 +14,6 @@ int cr_plugin_restore_unix_sk(int id);
 int cr_plugin_dump_file(int fd, int id);
 int cr_plugin_restore_file(int id);
 
+int cr_plugin_dump_ext_mount(char *mountpoint, int id);
+
 #endif
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 9af46f6..ef20315 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -112,6 +112,7 @@ struct mount_info {
 	char		*source;
 	char		*options;
 	bool		mounted;
+	bool		need_plugin;
 	struct mount_info *next;
 
 	/* tree linkage */
diff --git a/mount.c b/mount.c
index f07206a..340f69a 100644
--- a/mount.c
+++ b/mount.c
@@ -17,6 +17,7 @@
 #include "util.h"
 #include "util-pie.h"
 #include "log.h"
+#include "plugin.h"
 #include "mount.h"
 #include "pstree.h"
 #include "proc_parse.h"
@@ -42,7 +43,7 @@ static DIR *open_mountpoint(struct mount_info *pm);
 static int close_mountpoint(DIR *dfd);
 
 static struct mount_info *mnt_build_tree(struct mount_info *list);
-static int validate_mounts(struct mount_info *info);
+static int validate_mounts(struct mount_info *info, bool call_plugins);
 
 static inline int is_root(char *p)
 {
@@ -294,7 +295,7 @@ static void mnt_tree_show(struct mount_info *tree, int off)
 	pr_info("%*s<--\n", off, "");
 }
 
-static int validate_mounts(struct mount_info *info)
+static int validate_mounts(struct mount_info *info, bool call_plugins)
 {
 	struct mount_info *m, *t;
 
@@ -325,9 +326,19 @@ static int validate_mounts(struct mount_info *info)
 					break;
 			}
 			if (&t->mnt_bind == &m->mnt_bind) {
-				pr_err("%d:%s doesn't have a proper root mount\n",
-					m->mnt_id, m->mountpoint);
-				return -1;
+				int ret = -ENOTSUP;
+
+				if (call_plugins) {
+					ret = cr_plugin_dump_ext_mount(m->mountpoint, m->mnt_id);
+					if (ret == 0)
+						m->need_plugin = true;
+				}
+				if (ret < 0) {
+					if (ret == -ENOTSUP)
+						pr_err("%d:%s doesn't have a proper root mount\n",
+								m->mnt_id, m->mountpoint);
+					return -1;
+				}
 			}
 		}
 
@@ -727,7 +730,7 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd)
 		return -1;
 	}
 
-	if (pm->fstype->dump && pm->fstype->dump(pm))
+	if (!pm->need_plugin && pm->fstype->dump && pm->fstype->dump(pm))
 		return -1;
 
 	me.mnt_id		= pm->mnt_id;
@@ -731,6 +742,10 @@ static int dump_one_mountpoint(struct mount_info *pm, int fd)
 	me.has_shared_id	= true;
 	me.master_id		= pm->master_id;
 	me.has_master_id	= true;
+	if (pm->need_plugin) {
+		me.has_with_plugin = true;
+		me.with_plugin = true;
+	}
 
 	if (pb_write_one(fd, &me, PB_MNT))
 		return -1;
@@ -756,7 +771,7 @@ int dump_mnt_ns(int ns_pid, int ns_id)
 	if (mnt_build_tree(pm) == NULL)
 		goto err;
 
-	if (validate_mounts(pm))
+	if (validate_mounts(pm, true))
 		goto err;
 
 	pr_info("Dumping mountpoints\n");
@@ -1297,7 +1312,7 @@ static int populate_mnt_ns(int ns_pid, struct mount_info *mis)
 	if (!pms)
 		return -1;
 
-	if (validate_mounts(pms))
+	if (validate_mounts(pms, false))
 		return -1;
 
 	mntinfo_tree = pms;
diff --git a/plugin.c b/plugin.c
index 222a2f5..4349265 100644
--- a/plugin.c
+++ b/plugin.c
@@ -19,6 +19,7 @@ struct cr_plugin_entry {
 		cr_plugin_restore_unix_sk_t *cr_plugin_restore_unix_sk;
 		cr_plugin_dump_file_t *cr_plugin_dump_file;
 		cr_plugin_restore_file_t *cr_plugin_restore_file;
+		cr_plugin_dump_ext_mount_t *cr_plugin_dump_ext_mount;
 	};
 
 	struct cr_plugin_entry *next;
@@ -31,6 +32,7 @@ struct cr_plugins {
 	struct cr_plugin_entry *cr_plugin_restore_unix_sk;
 	struct cr_plugin_entry *cr_plugin_dump_file;
 	struct cr_plugin_entry *cr_plugin_restore_file;
+	struct cr_plugin_entry *cr_plugin_dump_ext_mount;
 };
 
 struct cr_plugins cr_plugins;
@@ -87,6 +89,11 @@ int cr_plugin_restore_file(int id)
 	return run_plugin_funcs(cr_plugin_restore_file, id);
 }
 
+int cr_plugin_dump_ext_mount(char *mountpoint, int id)
+{
+	return run_plugin_funcs(cr_plugin_dump_ext_mount, mountpoint, id);
+}
+
 static int cr_lib_load(char *path)
 {
 	struct cr_plugin_entry *ce;
@@ -106,6 +113,8 @@ static int cr_lib_load(char *path)
 	add_plugin_func(cr_plugin_dump_file);
 	add_plugin_func(cr_plugin_restore_file);
 
+	add_plugin_func(cr_plugin_dump_ext_mount);
+
 	ce = NULL;
 	f_fini = dlsym(h, "cr_plugin_fini");
 	if (f_fini) {
diff --git a/protobuf/mnt.proto b/protobuf/mnt.proto
index ea1ad3c..ab85de7 100644
--- a/protobuf/mnt.proto
+++ b/protobuf/mnt.proto
@@ -23,4 +23,6 @@ message mnt_entry {
 
 	optional uint32		shared_id		= 10;
 	optional uint32		master_id		= 11;
+
+	optional bool		with_plugin		= 12;
 }
-- 
1.8.3.1


More information about the CRIU mailing list