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 <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov 2021-12-10 12:13:06 +03:00 committed by Andrei Vagin
parent 1b015df9ba
commit 3fa85bcdcc
3 changed files with 82 additions and 18 deletions

View file

@ -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;

View file

@ -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 <fd>\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;

View file

@ -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;