[CRIU] [PATCH] irmap: add --irmap-scan-path option
Tycho Andersen
tycho.andersen at canonical.com
Tue Sep 15 21:27:25 PDT 2015
This option allows users to specify their own irmap paths to scan in the event
that they don't have a path in one of the hard coded hints.
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
cr-service.c | 8 ++++++++
crtools.c | 9 +++++++++
include/cr_options.h | 6 ++++++
include/irmap.h | 1 +
irmap.c | 36 ++++++++++++++++++++++++++++++++++++
lib/criu.c | 39 +++++++++++++++++++++++++++++++++++++++
lib/criu.h | 2 ++
protobuf/rpc.proto | 1 +
8 files changed, 102 insertions(+)
diff --git a/cr-service.c b/cr-service.c
index 0a99004..938ea9e 100644
--- a/cr-service.c
+++ b/cr-service.c
@@ -31,6 +31,7 @@
#include "action-scripts.h"
#include "security.h"
#include "sockets.h"
+#include "irmap.h"
#include "setproctitle.h"
@@ -445,6 +446,13 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
if (req->has_ghost_limit)
opts.ghost_limit = req->ghost_limit;
+ if (req->n_irmap_scan_paths) {
+ for (i = 0; i < req->n_irmap_scan_paths; i++) {
+ if (irmap_scan_path_add(req->irmap_scan_paths[i]))
+ goto err;
+ }
+ }
+
return 0;
err:
diff --git a/crtools.c b/crtools.c
index ac74c10..2a84e4a 100644
--- a/crtools.c
+++ b/crtools.c
@@ -39,6 +39,7 @@
#include "cpu.h"
#include "action-scripts.h"
#include "security.h"
+#include "irmap.h"
#include "setproctitle.h"
@@ -56,6 +57,7 @@ void init_opts(void)
INIT_LIST_HEAD(&opts.ext_mounts);
INIT_LIST_HEAD(&opts.inherit_fds);
INIT_LIST_HEAD(&opts.new_cgroup_roots);
+ INIT_LIST_HEAD(&opts.irmap_scan_paths);
opts.cpu_cap = CPU_CAP_DEFAULT;
opts.manage_cgroups = CG_MODE_DEFAULT;
@@ -249,6 +251,7 @@ int main(int argc, char *argv[], char *envp[])
{ "enable-external-masters", no_argument, 0, 1067 },
{ "freeze-cgroup", required_argument, 0, 1068 },
{ "ghost-limit", required_argument, 0, 1069 },
+ { "irmap-scan-path", required_argument, 0, 1070 },
{ },
};
@@ -485,6 +488,10 @@ int main(int argc, char *argv[], char *envp[])
case 1069:
opts.ghost_limit = parse_size(optarg);
break;
+ case 1070:
+ if (irmap_scan_path_add(optarg))
+ return -1;
+ break;
case 'M':
{
char *aux;
@@ -715,6 +722,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"
+" --irmap-scan-path FILE\n"
+" add a path the irmap hints to scan\n"
" -M|--ext-mount-map KEY:VALUE\n"
" add external mount mapping\n"
" -M|--ext-mount-map auto\n"
diff --git a/include/cr_options.h b/include/cr_options.h
index 34306d9..af130dd 100644
--- a/include/cr_options.h
+++ b/include/cr_options.h
@@ -38,6 +38,11 @@ struct cg_root_opt {
*/
#define DEFAULT_GHOST_LIMIT (1 << 20)
+struct irmap_path_opt {
+ struct list_head node;
+ char *path;
+};
+
struct cr_options {
int final_state;
char *show_dump_file;
@@ -87,6 +92,7 @@ struct cr_options {
bool aufs; /* auto-deteced, not via cli */
bool overlayfs;
size_t ghost_limit;
+ struct list_head irmap_scan_paths;
};
extern struct cr_options opts;
diff --git a/include/irmap.h b/include/irmap.h
index 3938d07..033f71e 100644
--- a/include/irmap.h
+++ b/include/irmap.h
@@ -9,4 +9,5 @@ int irmap_predump_run(void);
int check_open_handle(unsigned int s_dev, unsigned long i_ino,
struct _FhEntry *f_handle);
int irmap_load_cache(void);
+int irmap_scan_path_add(char *path);
#endif
diff --git a/irmap.c b/irmap.c
index 6289f7f..d0577b8 100644
--- a/irmap.c
+++ b/irmap.c
@@ -24,6 +24,7 @@
#include "image.h"
#include "stats.h"
#include "pstree.h"
+#include "cr_options.h"
#include "protobuf.h"
#include "protobuf/fsnotify.pb-c.h"
@@ -229,6 +230,7 @@ char *irmap_lookup(unsigned int s_dev, unsigned long i_ino)
struct irmap *c, *h, **p;
char *path = NULL;
int hv;
+ struct irmap_path_opt *o;
s_dev = kdev_to_odev(s_dev);
@@ -260,6 +262,27 @@ char *irmap_lookup(unsigned int s_dev, unsigned long i_ino)
goto out;
}
+ /* Let's scan any user provided paths first; since the user told us
+ * about them, hopefully they're more interesting than our hints.
+ */
+ list_for_each_entry(o, &opts.irmap_scan_paths, node) {
+ struct irmap *ir;
+
+ ir = xzalloc(sizeof(*ir));
+ if (!ir)
+ goto out;
+
+ ir->nr_kids = -1;
+ ir->path = o->path;
+
+ c = irmap_scan(ir, s_dev, i_ino);
+ if (c) {
+ pr_debug("\tScanned %s\n", c->path);
+ path = c->path;
+ goto out;
+ }
+ }
+
for (h = hints; h->path; h++) {
pr_debug("Scanning %s hint\n", h->path);
c = irmap_scan(h, s_dev, i_ino);
@@ -457,3 +480,16 @@ int irmap_load_cache(void)
close_image(img);
return ret;
}
+
+int irmap_scan_path_add(char *path)
+{
+ struct irmap_path_opt *o;
+
+ o = xmalloc(sizeof(*o));
+ if (!o)
+ return -1;
+
+ o->path = path;
+ list_add(&o->node, &opts.irmap_scan_paths);
+ return 0;
+}
diff --git a/lib/criu.c b/lib/criu.c
index e89a861..de70ac0 100644
--- a/lib/criu.c
+++ b/lib/criu.c
@@ -669,6 +669,40 @@ err:
return -ENOMEM;
}
+int criu_local_add_irmap_path(criu_opts *opts, char *path)
+{
+ int nr;
+ char *my_path;
+ char **m;
+
+ if (!opts)
+ return -1;
+
+ my_path = strdup(path);
+ if (!my_path)
+ goto err;
+
+ nr = opts->rpc->n_irmap_scan_paths + 1;
+ m = realloc(opts->rpc->irmap_scan_paths, nr * sizeof(*m));
+ if (!m)
+ goto err;
+
+ m[nr - 1] = my_path;
+
+ opts->rpc->n_irmap_scan_paths = nr;
+ opts->rpc->irmap_scan_paths = m;
+
+ return 0;
+
+err:
+ if (my_path)
+ free(my_path);
+ if (m)
+ free(m);
+
+ return -ENOMEM;
+}
+
int criu_add_skip_mnt(char *mnt)
{
return criu_local_add_skip_mnt(global_opts, mnt);
@@ -685,6 +719,11 @@ void criu_set_ghost_limit(unsigned int limit)
criu_local_set_ghost_limit(global_opts, limit);
}
+int criu_add_irmap_path(char *path)
+{
+ return criu_local_add_irmap_path(global_opts, path);
+}
+
static CriuResp *recv_resp(int socket_fd)
{
unsigned char *buf;
diff --git a/lib/criu.h b/lib/criu.h
index 6e4b175..c2ad84d 100644
--- a/lib/criu.h
+++ b/lib/criu.h
@@ -88,6 +88,7 @@ int criu_add_cg_root(char *ctrl, char *path);
int criu_add_enable_fs(char *fs);
int criu_add_skip_mnt(char *mnt);
void criu_set_ghost_limit(unsigned int limit);
+int criu_add_irmap_path(char *path);
/*
* The criu_notify_arg_t na argument is an opaque
@@ -189,6 +190,7 @@ int criu_local_add_cg_root(criu_opts *opts, char *ctrl, char *path);
int criu_local_add_enable_fs(criu_opts *opts, char *fs);
int criu_local_add_skip_mnt(criu_opts *opts, char *mnt);
void criu_local_set_ghost_limit(criu_opts *opts, unsigned int limit);
+int criu_local_add_irmap_path(criu_opts *opts, char *path);
void criu_local_set_notify_cb(criu_opts *opts, int (*cb)(char *action, criu_notify_arg_t na));
diff --git a/protobuf/rpc.proto b/protobuf/rpc.proto
index f186a1e..466780e 100644
--- a/protobuf/rpc.proto
+++ b/protobuf/rpc.proto
@@ -87,6 +87,7 @@ message criu_opts {
optional criu_cg_mode manage_cgroups_mode = 34;
optional uint32 ghost_limit = 35 [default = 0x100000];
+ repeated string irmap_scan_paths = 36;
}
message criu_dump_resp {
--
2.1.4
More information about the CRIU
mailing list