From 4f2e4ab3be01ef8ff8c20205608370fbb8ee770d Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Wed, 16 Sep 2015 07:27:00 +0300 Subject: [PATCH] irmap: add --irmap-scan-path option 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 Signed-off-by: Pavel Emelyanov --- 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 0a9900404..938ea9e14 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 838e7d9c5..4de8b0bb1 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 }, { }, }; @@ -487,6 +490,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; @@ -719,6 +726,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 34306d999..af130ddc5 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 3938d07be..033f71e37 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 6289f7f19..d0577b8e1 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 e89a86118..de70ac0c5 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 6e4b17591..c2ad84da1 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 f186a1e24..466780e85 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 {