mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
crtools: Introduce the --ext-mount-map option (v3)
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@parallels.com>
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
|
||||
|
20
crtools.c
20
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"
|
||||
|
@@ -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;
|
||||
|
@@ -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__ */
|
||||
|
@@ -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;
|
||||
|
34
mount.c
34
mount.c
@@ -29,6 +29,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
|
||||
*/
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user