From 3fa85bcdcc0a7d1042dd8774ebc105397cd4aac4 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Fri, 10 Dec 2021 12:13:06 +0300 Subject: [PATCH] crtools/rpc: export current criu mode to opts.mode We have multiple options which are valid only on restore or only on dump or in any other specific criu mode, so it would be useful to have info about current mode in opts so that we can validate other options against current mode. Plan is to use it for mount-v2 option as it is only valid on restore, and this would make handling of different types mountpoints much easier. Realization is a bit different for general code and rpc: - When criu mode is set from main() we just parse mode from argv[optind] just after parse_options() found optind of the command. Note that opts.mode is available before check_options(). - For rpc service we reset opts.mode to CR_SWRK each time we restart cr_service_work(), in the original service process we still have CR_SERVICE to differentiate between them, and each request handling function which does setup_opts_from_req sets opts.mode in accordance with the processed request type. And it is also available before check_options(). Now in check_options we can add filters on one mode only options. Signed-off-by: Pavel Tikhomirov --- criu/cr-service.c | 8 +++++ criu/crtools.c | 73 +++++++++++++++++++++++++++++---------- criu/include/cr_options.h | 19 ++++++++++ 3 files changed, 82 insertions(+), 18 deletions(-) diff --git a/criu/cr-service.c b/criu/cr-service.c index 80d12c7b0..59f46b320 100644 --- a/criu/cr-service.c +++ b/criu/cr-service.c @@ -735,6 +735,7 @@ static int dump_using_req(int sk, CriuOpts *req) bool success = false; bool self_dump = !req->pid; + opts.mode = CR_DUMP; if (setup_opts_from_req(sk, req)) goto exit; @@ -777,6 +778,7 @@ static int restore_using_req(int sk, CriuOpts *req) opts.restore_detach = true; + opts.mode = CR_RESTORE; if (setup_opts_from_req(sk, req)) goto exit; @@ -828,6 +830,7 @@ static int check(int sk, CriuOpts *req) if (pid == 0) { setproctitle("check --rpc"); + opts.mode = CR_CHECK; if (setup_opts_from_req(sk, req)) exit(1); @@ -859,6 +862,7 @@ static int pre_dump_using_req(int sk, CriuOpts *req, bool single) if (pid == 0) { int ret = 1; + opts.mode = CR_PRE_DUMP; if (setup_opts_from_req(sk, req)) goto cout; @@ -936,6 +940,7 @@ static int start_page_server_req(int sk, CriuOpts *req, bool daemon_mode) if (pid == 0) { close(start_pipe[0]); + opts.mode = CR_PAGE_SERVER; if (setup_opts_from_req(sk, req)) goto out_ch; @@ -1182,6 +1187,7 @@ static int handle_cpuinfo(int sk, CriuReq *msg) if (pid == 0) { int ret = 1; + opts.mode = CR_CPUINFO; if (setup_opts_from_req(sk, msg->opts)) goto cout; @@ -1231,6 +1237,8 @@ int cr_service_work(int sk) CriuReq *msg = 0; more: + opts.mode = CR_SWRK; + if (recv_criu_msg(sk, &msg) != 0) { pr_perror("Can't recv request"); goto err; diff --git a/criu/crtools.c b/criu/crtools.c index 3adfb190f..d10d7f7d0 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -67,6 +67,38 @@ static int image_dir_mode(char *argv[], int optind) return -1; } +static int parse_criu_mode(char *mode) +{ + if (!strcmp(mode, "dump")) + opts.mode = CR_DUMP; + else if (!strcmp(mode, "pre-dump")) + opts.mode = CR_PRE_DUMP; + else if (!strcmp(mode, "restore")) + opts.mode = CR_RESTORE; + else if (!strcmp(mode, "lazy-pages")) + opts.mode = CR_LAZY_PAGES; + else if (!strcmp(mode, "check")) + opts.mode = CR_CHECK; + else if (!strcmp(mode, "page-server")) + opts.mode = CR_PAGE_SERVER; + else if (!strcmp(mode, "service")) + opts.mode = CR_SERVICE; + else if (!strcmp(mode, "swrk")) + opts.mode = CR_SWRK; + else if (!strcmp(mode, "dedup")) + opts.mode = CR_DEDUP; + else if (!strcmp(mode, "cpuinfo")) + opts.mode = CR_CPUINFO; + else if (!strcmp(mode, "exec")) + opts.mode = CR_EXEC_DEPRECATED; + else if (!strcmp(mode, "show")) + opts.mode = CR_SHOW_DEPRECATED; + else + return -1; + + return 0; +} + int main(int argc, char *argv[], char *envp[]) { int ret = -1; @@ -124,7 +156,12 @@ int main(int argc, char *argv[], char *envp[]) return 1; } - if (!strcmp(argv[optind], "swrk")) { + if (parse_criu_mode(argv[optind])) { + pr_err("unknown command: %s\n", argv[optind]); + goto usage; + } + + if (opts.mode == CR_SWRK) { if (argc != optind + 2) { fprintf(stderr, "Usage: criu swrk \n"); return 1; @@ -156,7 +193,7 @@ int main(int argc, char *argv[], char *envp[]) goto usage; } - if (strcmp(argv[optind], "restore")) { + if (opts.mode != CR_RESTORE) { pr_err("--exec-cmd is available for the restore command only\n"); goto usage; } @@ -173,7 +210,7 @@ int main(int argc, char *argv[], char *envp[]) opts.exec_cmd[argc - optind - 1] = NULL; } else { /* No subcommands except for cpuinfo and restore --exec-cmd */ - if (strcmp(argv[optind], "cpuinfo") && has_sub_command) { + if (opts.mode != CR_CPUINFO && has_sub_command) { pr_err("excessive parameter%s for command %s\n", (argc - optind) > 2 ? "s" : "", argv[optind]); goto usage; } @@ -185,7 +222,7 @@ int main(int argc, char *argv[], char *envp[]) } /* We must not open imgs dir, if service is called */ - if (strcmp(argv[optind], "service")) { + if (opts.mode != CR_SERVICE) { ret = open_image_dir(opts.imgs_dir, image_dir_mode(argv, optind)); if (ret < 0) { pr_err("Couldn't open image dir %s\n", opts.imgs_dir); @@ -197,8 +234,7 @@ int main(int argc, char *argv[], char *envp[]) * When a process group becomes an orphan, * its processes are sent a SIGHUP signal */ - if (!strcmp(argv[optind], "restore") && opts.restore_detach && opts.final_state == TASK_STOPPED && - opts.shell_job) + if (opts.mode == CR_RESTORE && opts.restore_detach && opts.final_state == TASK_STOPPED && opts.shell_job) pr_warn("Stopped and detached shell job will get SIGHUP from OS.\n"); if (chdir(opts.work_dir)) { @@ -218,7 +254,7 @@ int main(int argc, char *argv[], char *envp[]) kdat.can_map_vdso = 0; if (!list_empty(&opts.inherit_fds)) { - if (strcmp(argv[optind], "restore")) { + if (opts.mode != CR_RESTORE) { pr_err("--inherit-fd is restore-only option\n"); return 1; } @@ -229,13 +265,14 @@ int main(int argc, char *argv[], char *envp[]) if (opts.img_parent) pr_info("Will do snapshot from %s\n", opts.img_parent); - if (!strcmp(argv[optind], "dump")) { + if (opts.mode == CR_DUMP) { if (!opts.tree_id) goto opt_pid_missing; + return cr_dump_tasks(opts.tree_id); } - if (!strcmp(argv[optind], "pre-dump")) { + if (opts.mode == CR_PRE_DUMP) { if (!opts.tree_id) goto opt_pid_missing; @@ -247,7 +284,7 @@ int main(int argc, char *argv[], char *envp[]) return cr_pre_dump_tasks(opts.tree_id) != 0; } - if (!strcmp(argv[optind], "restore")) { + if (opts.mode == CR_RESTORE) { if (opts.tree_id) pr_warn("Using -t with criu restore is obsoleted\n"); @@ -262,22 +299,22 @@ int main(int argc, char *argv[], char *envp[]) return ret != 0; } - if (!strcmp(argv[optind], "lazy-pages")) + if (opts.mode == CR_LAZY_PAGES) return cr_lazy_pages(opts.daemon_mode) != 0; - if (!strcmp(argv[optind], "check")) + if (opts.mode == CR_CHECK) return cr_check() != 0; - if (!strcmp(argv[optind], "page-server")) + if (opts.mode == CR_PAGE_SERVER) return cr_page_server(opts.daemon_mode, false, -1) != 0; - if (!strcmp(argv[optind], "service")) + if (opts.mode == CR_SERVICE) return cr_service(opts.daemon_mode); - if (!strcmp(argv[optind], "dedup")) + if (opts.mode == CR_DEDUP) return cr_dedup() != 0; - if (!strcmp(argv[optind], "cpuinfo")) { + if (opts.mode == CR_CPUINFO) { if (!argv[optind + 1]) { pr_err("cpuinfo requires an action: dump or check\n"); goto usage; @@ -288,12 +325,12 @@ int main(int argc, char *argv[], char *envp[]) return cpuinfo_check(); } - if (!strcmp(argv[optind], "exec")) { + if (opts.mode == CR_EXEC_DEPRECATED) { pr_err("The \"exec\" action is deprecated by the Compel library.\n"); return -1; } - if (!strcmp(argv[optind], "show")) { + if (opts.mode == CR_SHOW_DEPRECATED) { pr_err("The \"show\" action is deprecated by the CRIT utility.\n"); pr_err("To view an image use the \"crit decode -i $name --pretty\" command.\n"); return -1; diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h index a34f8dbbf..85648bf1c 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -100,6 +100,22 @@ struct irmap_path_opt { struct irmap *ir; }; +enum criu_mode { + CR_UNSET = 0, + CR_DUMP, + CR_PRE_DUMP, + CR_RESTORE, + CR_LAZY_PAGES, + CR_CHECK, + CR_PAGE_SERVER, + CR_SERVICE, + CR_SWRK, + CR_DEDUP, + CR_CPUINFO, + CR_EXEC_DEPRECATED, + CR_SHOW_DEPRECATED, +}; + struct cr_options { int final_state; int check_extra_features; @@ -188,6 +204,9 @@ struct cr_options { /* This stores which method to use for file validation. */ int file_validation_method; + + /* Shows the mode criu is running at the moment: dump/pre-dump/restore/... */ + enum criu_mode mode; }; extern struct cr_options opts;