[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