[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