[CRIU] [PATCH 2/3] crtools: Introduce the --ext-mount-map option (v3)

Pavel Emelyanov xemul at parallels.com
Mon Jun 9 06:26:17 PDT 2014


On dump one uses one or more --ext-mount-map option with A:B arguments.
A denotes a mountpoint (as seen from the target mount namespace) criu
dumps and B is the string that will be written into the image file 
instead of the mountpoint's root.

On restore one uses the same --ext-mount-map option(s) with similar
A:B arguments, but this time criu treats A as string from the image's
root field (foobar in the example above) and B as the path in criu's
mount namespace the should be bind mounted into the mountpoint.

v3:
* Added documentation
* Added RPC bits
* Changed option name into --ext-mount-map
* Use colon as key and value separator

Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
---
 Documentation/criu.txt | 11 +++++++++++
 cr-service.c           |  6 ++++++
 crtools.c              | 20 +++++++++++++++++++-
 include/cr_options.h   |  1 +
 include/mount.h        |  1 +
 include/proc_parse.h   |  3 +++
 mount.c                | 34 ++++++++++++++++++++++++++++++++++
 protobuf/rpc.proto     |  7 +++++++
 8 files changed, 82 insertions(+), 1 deletion(-)

diff --git a/Documentation/criu.txt b/Documentation/criu.txt
index 9c9a9c9..474011c 100644
--- a/Documentation/criu.txt
+++ b/Documentation/criu.txt
@@ -113,6 +113,17 @@ OPTIONS
 *--veth-pair* 'IN'*=*'OUT'::
     Correspondence between outside and inside names of veth devices.
 
+*-M*, *--ext-mount-map* 'KEY'*:*'VAL'::
+    Setup mapping for external mounts.
+
+    On dump, KEY is a mountpoint inside container and correspoding VAL 
+    is a string that will be written into the image as mountpoint's root
+    value
+
+    On restore KEY is the value from the image (VAL from dump) and the
+    VAL is the path on host that will be bind-mounted into container
+    (to the mountpoint path from image)
+
 *--action-script* 'SCRIPT'::
     Add an external action script.
     The environment variable *CRTOOLS_SCRIPT_ACTION* contains one of the
diff --git a/cr-service.c b/cr-service.c
index d147692..dc0ff5a 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -23,6 +23,7 @@
 #include "sd-daemon.h"
 #include "page-xfer.h"
 #include "net.h"
+#include "mount.h"
 
 unsigned int service_sk_ino = -1;
 
@@ -294,6 +295,11 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
 			return -1;
 	}
 
+	for (i = 0; i < req->n_ext_mnt; i++) {
+		if (ext_mount_add(req->ext_mnt[i]->key, req->ext_mnt[i]->val))
+			return -1;
+	}
+
 	if (req->has_cpu_cap)
 		opts.cpu_cap = req->cpu_cap;
 
diff --git a/crtools.c b/crtools.c
index 38b4b0d..5684186 100644
--- a/crtools.c
+++ b/crtools.c
@@ -34,6 +34,7 @@
 #include "file-lock.h"
 #include "cr-service.h"
 #include "plugin.h"
+#include "mount.h"
 
 struct cr_options opts;
 
@@ -45,6 +46,7 @@ void init_opts(void)
 	opts.final_state = TASK_DEAD;
 	INIT_LIST_HEAD(&opts.veth_pairs);
 	INIT_LIST_HEAD(&opts.scripts);
+	INIT_LIST_HEAD(&opts.ext_mounts);
 
 	opts.cpu_cap = CPU_CAP_ALL;
 }
@@ -124,7 +126,7 @@ int main(int argc, char *argv[])
 	int log_level = LOG_UNSET;
 	char *imgs_dir = ".";
 	char *work_dir = NULL;
-	static const char short_opts[] = "dsRf:F:t:p:hcD:o:n:v::xVr:jlW:L:";
+	static const char short_opts[] = "dsRf:F:t:p:hcD:o:n:v::xVr:jlW:L:M:";
 	static struct option long_opts[] = {
 		{ "tree", required_argument, 0, 't' },
 		{ "pid", required_argument, 0, 'p' },
@@ -163,6 +165,7 @@ int main(int argc, char *argv[])
 		{ "libdir", required_argument, 0, 'L'},
 		{ "cpu-cap", required_argument, 0, 57},
 		{ "force-irmap", no_argument, 0, 58},
+		{ "ext-mount-map", required_argument, 0, 'M'},
 		{ "exec-cmd", no_argument, 0, 59},
 		{ },
 	};
@@ -338,6 +341,19 @@ int main(int argc, char *argv[])
 		case 59:
 			has_exec_cmd = true;
 			break;
+		case 'M':
+			{
+				char *aux;
+
+				aux = strchr(optarg, ':');
+				if (aux == NULL)
+					goto bad_arg;
+
+				*aux = '\0';
+				if (ext_mount_add(optarg, aux + 1))
+					return 1;
+			}
+			break;
 		case 'V':
 			pr_msg("Version: %s\n", CRIU_VERSION);
 			if (strcmp(CRIU_GITID, "0"))
@@ -511,6 +527,8 @@ usage:
 "  -l|--" OPT_FILE_LOCKS "       handle file locks, for safety, only used for container\n"
 "  -L|--libdir           path to a plugin directory (by default " CR_PLUGIN_DEFAULT ")\n"
 "  --force-irmap         force resolving names for inotify/fsnotify watches\n"
+"  -M|--ext-mount-map KEY:VALUE\n"
+"                        add external mount mapping\n"
 "\n"
 "* Logging:\n"
 "  -o|--log-file FILE    log file name\n"
diff --git a/include/cr_options.h b/include/cr_options.h
index f2106b0..2732e58 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -39,6 +39,7 @@ struct cr_options {
 	char			*pidfile;
 	struct list_head	veth_pairs;
 	struct list_head	scripts;
+	struct list_head	ext_mounts;
 	char			*libdir;
 	bool			use_page_server;
 	unsigned short		ps_port;
diff --git a/include/mount.h b/include/mount.h
index 82e8440..670e779 100644
--- a/include/mount.h
+++ b/include/mount.h
@@ -35,5 +35,6 @@ extern int restore_task_mnt_ns(struct pstree_item *);
 extern int fini_mnt_ns(void);
 
 char *rst_get_mnt_root(int mnt_id);
+int ext_mount_add(char *key, char *val);
 
 #endif /* __CR_MOUNT_H__ */
diff --git a/include/proc_parse.h b/include/proc_parse.h
index 09c9efd..cca5322 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -99,6 +99,7 @@ struct fstype {
 	int (*parse)(struct mount_info *pm);
 };
 
+struct ext_mount;
 struct mount_info {
 	int		mnt_id;
 	int		parent_mnt_id;
@@ -123,6 +124,8 @@ struct mount_info {
 	struct mount_info *next;
 	struct ns_id	*nsid;
 
+	struct ext_mount *external;
+
 	/* tree linkage */
 	struct mount_info *parent;
 	struct mount_info *bind;
diff --git a/mount.c b/mount.c
index 1d1e696..9cc26ef 100644
--- a/mount.c
+++ b/mount.c
@@ -30,6 +30,40 @@
 #include "protobuf/mnt.pb-c.h"
 
 /*
+ * Structure to keep external mount points resolving info.
+ *
+ * On dump the key is the mountpoint as seen from the mount
+ * namespace, the val is some name that will be put into image
+ * instead of the mount point's root path.
+ *
+ * On restore the key is the name from the image (the one 
+ * mentioned above) and the val is the path in criu's mount 
+ * namespace that will become the mount point's root, i.e. -- 
+ * be bind mounted to the respective mountpoint.
+ */
+
+struct ext_mount {
+	char *key;
+	char *val;
+	struct list_head l;
+};
+
+int ext_mount_add(char *key, char *val)
+{
+	struct ext_mount *em;
+
+	em = xmalloc(sizeof(*em));
+	if (!em)
+		return -1;
+
+	em->key = key;
+	em->val = val;
+	list_add_tail(&em->l, &opts.ext_mounts);
+	pr_info("Added %s:%s ext mount mapping\n", key, val);
+	return 0;
+}
+
+/*
  * Single linked list of mount points get from proc/images
  */
 struct mount_info *mntinfo;
diff --git a/protobuf/rpc.proto b/protobuf/rpc.proto
index b26186a..e50d97c 100644
--- a/protobuf/rpc.proto
+++ b/protobuf/rpc.proto
@@ -9,6 +9,11 @@ message criu_veth_pair {
 	required string		if_out	= 2;
 };
 
+message ext_mount_map {
+	required string		key	= 1;
+	required string		val	= 2;
+};
+
 message criu_opts {
 	required int32			images_dir_fd	= 1;
 	optional int32			pid		= 2; /* if not set on dump, will dump requesting process */
@@ -38,6 +43,8 @@ message criu_opts {
 	optional uint32			cpu_cap		= 20 [default = 0xffffffff];
 	optional bool			force_irmap	= 21;
 	repeated string			exec_cmd	= 22;
+
+	repeated ext_mount_map		ext_mnt		= 23;
 }
 
 message criu_dump_resp {
-- 
1.8.4.2


More information about the CRIU mailing list