Commit f17b60ef authored by Veronika Kabatova's avatar Veronika Kabatova Committed by Andrei Vagin

Extend the parser to accept negative options

Introducing negative options for true / false values. The original
getopt_long parser is kept since it is able to set flag-like values
(instead of setting these values in the switch when it's not needed).
The type of the options needed to be changed to integers for getopt_long
to accept flag-like value settings (as per getopt_long documentation,
the address of integer variable has to be passed).

Corresponding negative options are not added for deprecated options.

This patch is a preparation for the addition of configuration files
(GitHub issue #278). General idea of this feature is to have global
configuration files in /etc/criu.d/ directory and user-specific
configuration files in $HOME/.criu.d/ directory, with the possibility
of specifying a chosen file to be used (default files will be used if
none is specified, or none in case the default ones are not present,
to not break compatibility). The options in configuration files should
be possible to be overriden by the options specified on command line,
hence the negative options addition.

The whole feature of configuration files will remove the need of
specifying all the options on command line, with the possibility of
reusing a file for different use case with only overriding some of the
values specified there.

In case both types of option (negative and positive) are passed, the
later one will be applied -- this works with the philosophy of
overriding the "earlier" options from configuration files.

Changes since v1:
- Describe the --no- option prefix in the beginning of OPTIONS section in
  both man page and --help instead of mentioning it at every eligible line
  (this also fixes line length issue with --help)
- Fix the accidental removal of check_only case caused by bad rebase
- Use a macro for getopt_long struct option generating instead of additional
  defines and hardcoded lines
Signed-off-by: 's avatarVeronika Kabatova <vkabatov@redhat.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 42cbc9e3
...@@ -24,6 +24,10 @@ on a different system, or both. ...@@ -24,6 +24,10 @@ on a different system, or both.
OPTIONS OPTIONS
------- -------
Most of the true / false long options (the ones without arguments) can be
prefixed with *--no-* to negate the option (example: *--display-stats*
and *--no-display-stats*).
Common options Common options
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
Common options are applicable to any 'command'. Common options are applicable to any 'command'.
......
...@@ -211,6 +211,11 @@ bool deprecated_ok(char *what) ...@@ -211,6 +211,11 @@ bool deprecated_ok(char *what)
int main(int argc, char *argv[], char *envp[]) int main(int argc, char *argv[], char *envp[])
{ {
#define BOOL_OPT(OPT_NAME, SAVE_TO) \
{OPT_NAME, no_argument, SAVE_TO, true},\
{"no-" OPT_NAME, no_argument, SAVE_TO, false}
pid_t pid = 0, tree_id = 0; pid_t pid = 0, tree_id = 0;
int ret = -1; int ret = -1;
bool usage_error = true; bool usage_error = true;
...@@ -225,9 +230,9 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -225,9 +230,9 @@ int main(int argc, char *argv[], char *envp[])
{ "pid", required_argument, 0, 'p' }, { "pid", required_argument, 0, 'p' },
{ "leave-stopped", no_argument, 0, 's' }, { "leave-stopped", no_argument, 0, 's' },
{ "leave-running", no_argument, 0, 'R' }, { "leave-running", no_argument, 0, 'R' },
{ "restore-detached", no_argument, 0, 'd' }, BOOL_OPT("restore-detached", &opts.restore_detach),
{ "restore-sibling", no_argument, 0, 'S' }, BOOL_OPT("restore-sibling", &opts.restore_sibling),
{ "daemon", no_argument, 0, 'd' }, BOOL_OPT("daemon", &opts.restore_detach),
{ "contents", no_argument, 0, 'c' }, { "contents", no_argument, 0, 'c' },
{ "file", required_argument, 0, 'f' }, { "file", required_argument, 0, 'f' },
{ "fields", required_argument, 0, 'F' }, { "fields", required_argument, 0, 'F' },
...@@ -238,27 +243,27 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -238,27 +243,27 @@ int main(int argc, char *argv[], char *envp[])
{ "root", required_argument, 0, 'r' }, { "root", required_argument, 0, 'r' },
{ USK_EXT_PARAM, optional_argument, 0, 'x' }, { USK_EXT_PARAM, optional_argument, 0, 'x' },
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ SK_EST_PARAM, no_argument, 0, 1042 }, BOOL_OPT(SK_EST_PARAM, &opts.tcp_established_ok),
{ "close", required_argument, 0, 1043 }, { "close", required_argument, 0, 1043 },
{ "log-pid", no_argument, 0, 1044 }, BOOL_OPT("log-pid", &opts.log_file_per_pid),
{ "version", no_argument, 0, 'V' }, { "version", no_argument, 0, 'V' },
{ "evasive-devices", no_argument, 0, 1045 }, BOOL_OPT("evasive-devices", &opts.evasive_devices),
{ "pidfile", required_argument, 0, 1046 }, { "pidfile", required_argument, 0, 1046 },
{ "veth-pair", required_argument, 0, 1047 }, { "veth-pair", required_argument, 0, 1047 },
{ "action-script", required_argument, 0, 1049 }, { "action-script", required_argument, 0, 1049 },
{ LREMAP_PARAM, no_argument, 0, 1041 }, BOOL_OPT(LREMAP_PARAM, &opts.link_remap_ok),
{ OPT_SHELL_JOB, no_argument, 0, 'j' }, BOOL_OPT(OPT_SHELL_JOB, &opts.shell_job),
{ OPT_FILE_LOCKS, no_argument, 0, 'l' }, BOOL_OPT(OPT_FILE_LOCKS, &opts.handle_file_locks),
{ "page-server", no_argument, 0, 1050 }, BOOL_OPT("page-server", &opts.use_page_server),
{ "address", required_argument, 0, 1051 }, { "address", required_argument, 0, 1051 },
{ "port", required_argument, 0, 1052 }, { "port", required_argument, 0, 1052 },
{ "prev-images-dir", required_argument, 0, 1053 }, { "prev-images-dir", required_argument, 0, 1053 },
{ "ms", no_argument, 0, 1054 }, { "ms", no_argument, 0, 1054 },
{ "track-mem", no_argument, 0, 1055 }, BOOL_OPT("track-mem", &opts.track_mem),
{ "auto-dedup", no_argument, 0, 1056 }, BOOL_OPT("auto-dedup", &opts.auto_dedup),
{ "libdir", required_argument, 0, 'L' }, { "libdir", required_argument, 0, 'L' },
{ "cpu-cap", optional_argument, 0, 1057 }, { "cpu-cap", optional_argument, 0, 1057 },
{ "force-irmap", no_argument, 0, 1058 }, BOOL_OPT("force-irmap", &opts.force_irmap),
{ "ext-mount-map", required_argument, 0, 'M' }, { "ext-mount-map", required_argument, 0, 'M' },
{ "exec-cmd", no_argument, 0, 1059 }, { "exec-cmd", no_argument, 0, 1059 },
{ "manage-cgroups", optional_argument, 0, 1060 }, { "manage-cgroups", optional_argument, 0, 1060 },
...@@ -267,8 +272,8 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -267,8 +272,8 @@ int main(int argc, char *argv[], char *envp[])
{ "feature", required_argument, 0, 1063 }, { "feature", required_argument, 0, 1063 },
{ "skip-mnt", required_argument, 0, 1064 }, { "skip-mnt", required_argument, 0, 1064 },
{ "enable-fs", required_argument, 0, 1065 }, { "enable-fs", required_argument, 0, 1065 },
{ "enable-external-sharing", no_argument, 0, 1066 }, { "enable-external-sharing", no_argument, &opts.enable_external_sharing, true },
{ "enable-external-masters", no_argument, 0, 1067 }, { "enable-external-masters", no_argument, &opts.enable_external_masters, true },
{ "freeze-cgroup", required_argument, 0, 1068 }, { "freeze-cgroup", required_argument, 0, 1068 },
{ "ghost-limit", required_argument, 0, 1069 }, { "ghost-limit", required_argument, 0, 1069 },
{ "irmap-scan-path", required_argument, 0, 1070 }, { "irmap-scan-path", required_argument, 0, 1070 },
...@@ -276,20 +281,22 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -276,20 +281,22 @@ int main(int argc, char *argv[], char *envp[])
{ "timeout", required_argument, 0, 1072 }, { "timeout", required_argument, 0, 1072 },
{ "external", required_argument, 0, 1073 }, { "external", required_argument, 0, 1073 },
{ "empty-ns", required_argument, 0, 1074 }, { "empty-ns", required_argument, 0, 1074 },
{ "extra", no_argument, 0, 1077 }, BOOL_OPT("extra", &opts.check_extra_features),
{ "experimental", no_argument, 0, 1078 }, BOOL_OPT("experimental", &opts.check_experimental_features),
{ "all", no_argument, 0, 1079 }, { "all", no_argument, 0, 1079 },
{ "cgroup-props", required_argument, 0, 1080 }, { "cgroup-props", required_argument, 0, 1080 },
{ "cgroup-props-file", required_argument, 0, 1081 }, { "cgroup-props-file", required_argument, 0, 1081 },
{ "cgroup-dump-controller", required_argument, 0, 1082 }, { "cgroup-dump-controller", required_argument, 0, 1082 },
{ SK_INFLIGHT_PARAM, no_argument, 0, 1083 }, BOOL_OPT(SK_INFLIGHT_PARAM, &opts.tcp_skip_in_flight),
{ "deprecated", no_argument, 0, 1084 }, BOOL_OPT("deprecated", &opts.deprecated_ok),
{ "display-stats", no_argument, 0, 1086 }, BOOL_OPT("display-stats", &opts.display_stats),
{ "weak-sysctls", no_argument, 0, 1087 }, BOOL_OPT("weak-sysctls", &opts.weak_sysctls),
{ "status-fd", required_argument, 0, 1088 }, { "status-fd", required_argument, 0, 1088 },
{ }, { },
}; };
#undef BOOL_OPT
BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE); BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
BUILD_BUG_ON(CTL_32 != SYSCTL_TYPE__CTL_32); BUILD_BUG_ON(CTL_32 != SYSCTL_TYPE__CTL_32);
BUILD_BUG_ON(__CTL_STR != SYSCTL_TYPE__CTL_STR); BUILD_BUG_ON(__CTL_STR != SYSCTL_TYPE__CTL_STR);
...@@ -326,6 +333,8 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -326,6 +333,8 @@ int main(int argc, char *argv[], char *envp[])
opt = getopt_long(argc, argv, short_opts, long_opts, &idx); opt = getopt_long(argc, argv, short_opts, long_opts, &idx);
if (opt == -1) if (opt == -1)
break; break;
if (!opt)
continue;
switch (opt) { switch (opt) {
case 's': case 's':
...@@ -390,14 +399,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -390,14 +399,6 @@ int main(int argc, char *argv[], char *envp[])
} else } else
log_level++; log_level++;
break; break;
case 1041:
pr_info("Will allow link remaps on FS\n");
opts.link_remap_ok = true;
break;
case 1042:
pr_info("Will dump TCP connections\n");
opts.tcp_established_ok = true;
break;
case 1043: { case 1043: {
int fd; int fd;
...@@ -406,12 +407,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -406,12 +407,6 @@ int main(int argc, char *argv[], char *envp[])
close(fd); close(fd);
break; break;
} }
case 1044:
opts.log_file_per_pid = 1;
break;
case 1045:
opts.evasive_devices = true;
break;
case 1046: case 1046:
opts.pidfile = optarg; opts.pidfile = optarg;
break; break;
...@@ -432,9 +427,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -432,9 +427,6 @@ int main(int argc, char *argv[], char *envp[])
if (add_script(optarg)) if (add_script(optarg))
return 1; return 1;
break;
case 1050:
opts.use_page_server = true;
break; break;
case 1051: case 1051:
opts.addr = optarg; opts.addr = optarg;
...@@ -453,12 +445,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -453,12 +445,6 @@ int main(int argc, char *argv[], char *envp[])
case 1053: case 1053:
opts.img_parent = optarg; opts.img_parent = optarg;
break; break;
case 1055:
opts.track_mem = true;
break;
case 1056:
opts.auto_dedup = true;
break;
case 1057: case 1057:
if (parse_cpu_cap(&opts, optarg)) if (parse_cpu_cap(&opts, optarg))
goto usage; goto usage;
...@@ -516,12 +502,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -516,12 +502,6 @@ int main(int argc, char *argv[], char *envp[])
if (!add_fsname_auto(optarg)) if (!add_fsname_auto(optarg))
return 1; return 1;
break; break;
case 1066:
opts.enable_external_sharing = true;
break;
case 1067:
opts.enable_external_masters = true;
break;
case 1068: case 1068:
opts.freeze_cgroup = optarg; opts.freeze_cgroup = optarg;
break; break;
...@@ -570,12 +550,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -570,12 +550,6 @@ int main(int argc, char *argv[], char *envp[])
return 1; return 1;
} }
break; break;
case 1077:
opts.check_extra_features = true;
break;
case 1078:
opts.check_experimental_features = true;
break;
case 1079: case 1079:
opts.check_extra_features = true; opts.check_extra_features = true;
opts.check_experimental_features = true; opts.check_experimental_features = true;
...@@ -590,21 +564,6 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -590,21 +564,6 @@ int main(int argc, char *argv[], char *envp[])
if (!cgp_add_dump_controller(optarg)) if (!cgp_add_dump_controller(optarg))
return 1; return 1;
break; break;
case 1083:
pr_msg("Will skip in-flight TCP connections\n");
opts.tcp_skip_in_flight = true;
break;
case 1084:
pr_msg("Turn deprecated stuff ON\n");
opts.deprecated_ok = true;
break;
case 1086:
opts.display_stats = true;
break;
case 1087:
pr_msg("Will skip non-existant sysctls on restore\n");
opts.weak_sysctls = true;
break;
case 1088: case 1088:
if (sscanf(optarg, "%d", &opts.status_fd) != 1) { if (sscanf(optarg, "%d", &opts.status_fd) != 1) {
pr_err("Unable to parse a value of --status-fd\n"); pr_err("Unable to parse a value of --status-fd\n");
...@@ -624,6 +583,17 @@ int main(int argc, char *argv[], char *envp[]) ...@@ -624,6 +583,17 @@ int main(int argc, char *argv[], char *envp[])
} }
} }
if (opts.deprecated_ok)
pr_msg("Turn deprecated stuff ON\n");
if (opts.tcp_skip_in_flight)
pr_msg("Will skip in-flight TCP connections\n");
if (opts.tcp_established_ok)
pr_info("Will dump TCP connections\n");
if (opts.link_remap_ok)
pr_info("Will allow link remaps on FS\n");
if (opts.weak_sysctls)
pr_msg("Will skip non-existant sysctls on restore\n");
if (getenv("CRIU_DEPRECATED")) { if (getenv("CRIU_DEPRECATED")) {
pr_msg("Turn deprecated stuff ON via env\n"); pr_msg("Turn deprecated stuff ON via env\n");
opts.deprecated_ok = true; opts.deprecated_ok = true;
...@@ -819,6 +789,11 @@ usage: ...@@ -819,6 +789,11 @@ usage:
} }
pr_msg("\n" pr_msg("\n"
"Most of the true / false long options (the ones without arguments) can be\n"
"prefixed with --no- to negate the option (example: --display-stats and\n"
"--no-display-stats).\n"
"\n"
"Dump/Restore options:\n" "Dump/Restore options:\n"
"\n" "\n"
"* Generic:\n" "* Generic:\n"
......
...@@ -51,21 +51,21 @@ struct cr_options { ...@@ -51,21 +51,21 @@ struct cr_options {
int final_state; int final_state;
char *show_dump_file; char *show_dump_file;
char *show_fmt; char *show_fmt;
bool check_extra_features; int check_extra_features;
bool check_experimental_features; int check_experimental_features;
bool show_pages_content; bool show_pages_content;
union { union {
bool restore_detach; int restore_detach;
bool daemon_mode; bool daemon_mode;
}; };
bool restore_sibling; int restore_sibling;
bool ext_unix_sk; bool ext_unix_sk;
bool shell_job; int shell_job;
bool handle_file_locks; int handle_file_locks;
bool tcp_established_ok; int tcp_established_ok;
bool evasive_devices; int evasive_devices;
bool link_remap_ok; int link_remap_ok;
bool log_file_per_pid; int log_file_per_pid;
bool swrk_restore; bool swrk_restore;
char *output; char *output;
char *root; char *root;
...@@ -76,15 +76,15 @@ struct cr_options { ...@@ -76,15 +76,15 @@ struct cr_options {
struct list_head external; struct list_head external;
struct list_head join_ns; struct list_head join_ns;
char *libdir; char *libdir;
bool use_page_server; int use_page_server;
unsigned short port; unsigned short port;
char *addr; char *addr;
int ps_socket; int ps_socket;
bool track_mem; int track_mem;
char *img_parent; char *img_parent;
bool auto_dedup; int auto_dedup;
unsigned int cpu_cap; unsigned int cpu_cap;
bool force_irmap; int force_irmap;
char **exec_cmd; char **exec_cmd;
unsigned int manage_cgroups; unsigned int manage_cgroups;
char *new_global_cg_root; char *new_global_cg_root;
...@@ -92,8 +92,8 @@ struct cr_options { ...@@ -92,8 +92,8 @@ struct cr_options {
char *cgroup_props_file; char *cgroup_props_file;
struct list_head new_cgroup_roots; struct list_head new_cgroup_roots;
bool autodetect_ext_mounts; bool autodetect_ext_mounts;
bool enable_external_sharing; int enable_external_sharing;
bool enable_external_masters; int enable_external_masters;
bool aufs; /* auto-deteced, not via cli */ bool aufs; /* auto-deteced, not via cli */
bool overlayfs; bool overlayfs;
#ifdef CONFIG_BINFMT_MISC_VIRTUALIZED #ifdef CONFIG_BINFMT_MISC_VIRTUALIZED
...@@ -105,7 +105,7 @@ struct cr_options { ...@@ -105,7 +105,7 @@ struct cr_options {
char *lsm_profile; char *lsm_profile;
unsigned int timeout; unsigned int timeout;
unsigned int empty_ns; unsigned int empty_ns;
bool tcp_skip_in_flight; int tcp_skip_in_flight;
char *work_dir; char *work_dir;
/* /*
...@@ -114,9 +114,9 @@ struct cr_options { ...@@ -114,9 +114,9 @@ struct cr_options {
* the deprecated stuff is not working, but it's still possible * the deprecated stuff is not working, but it's still possible
* to turn one ON while the code is in. * to turn one ON while the code is in.
*/ */
bool deprecated_ok; int deprecated_ok;
bool display_stats; int display_stats;
bool weak_sysctls; int weak_sysctls;
int status_fd; int status_fd;
bool orphan_pts_master; bool orphan_pts_master;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment