diff --git a/Documentation/criu.txt b/Documentation/criu.txt index 6ce384163..ff6886d9d 100644 --- a/Documentation/criu.txt +++ b/Documentation/criu.txt @@ -400,6 +400,22 @@ By default the option is set to *fpu* and *ins*. option is intended for post-copy (lazy) migration and should be used in conjunction with *restore* with appropriate options. +*--file-validation* ['mode']:: + Set the method to be used to validate open files. Validation is done + to ensure that the version of the file being restored is the same + version when it was dumped. + +The 'mode' may be one of the following: + + *filesize*::: + To explicitly use only the file size check all the time. + This is the fastest and least intensive check. + + *buildid*::: + To validate ELF files with their build-ID. If the + build-ID cannot be obtained, 'chksm-first' method will be + used. This is the default if mode is unspecified. + *restore* ~~~~~~~~~ Restores previously checkpointed processes. @@ -576,6 +592,22 @@ are not adequate, but this can be suppressed by using *--cpu-cap=none*. restored process. This option requires running *lazy-pages* daemon. +*--file-validation* ['mode']:: + Set the method to be used to validate open files. Validation is done + to ensure that the version of the file being restored is the same + version when it was dumped. + +The 'mode' may be one of the following: + + *filesize*::: + To explicitly use only the file size check all the time. + This is the fastest and least intensive check. + + *buildid*::: + To validate ELF files with their build-ID. If the + build-ID cannot be obtained, 'chksm-first' method will be + used. This is the default if mode is unspecified. + *check* ~~~~~~~ Checks whether the kernel supports the features needed by *criu* to diff --git a/criu/config.c b/criu/config.c index 3a3a13edb..08606fb33 100644 --- a/criu/config.c +++ b/criu/config.c @@ -280,6 +280,7 @@ void init_opts(void) opts.status_fd = -1; opts.log_level = DEFAULT_LOGLEVEL; opts.pre_dump_mode = PRE_DUMP_SPLICE; + opts.file_validation_method = FILE_VALIDATION_DEFAULT; } bool deprecated_ok(char *what) @@ -420,6 +421,22 @@ static int parse_join_ns(const char *ptr) return 0; } +static int parse_file_validation_method(struct cr_options *opts, const char *optarg) +{ + if (!strcmp(optarg, "filesize")) + opts->file_validation_method = FILE_VALIDATION_FILE_SIZE; + else if (!strcmp(optarg, "buildid")) + opts->file_validation_method = FILE_VALIDATION_BUILD_ID; + else + goto Esyntax; + + return 0; + +Esyntax: + pr_err("Unknown file validation method `%s' selected\n", optarg); + return -1; +} + /* * parse_options() is the point where the getopt parsing happens. The CLI * parsing as well as the configuration file parsing happens here. @@ -523,6 +540,7 @@ int parse_options(int argc, char **argv, bool *usage_error, {"tls-no-cn-verify", no_argument, &opts.tls_no_cn_verify, true}, { "cgroup-yard", required_argument, 0, 1096 }, { "pre-dump-mode", required_argument, 0, 1097}, + { "file-validation", required_argument, 0, 1098 }, { }, }; @@ -848,6 +866,10 @@ int parse_options(int argc, char **argv, bool *usage_error, return 1; } break; + case 1098: + if (parse_file_validation_method(&opts, optarg)) + return 2; + break; case 'V': pr_msg("Version: %s\n", CRIU_VERSION); if (strcmp(CRIU_GITID, "0")) diff --git a/criu/crtools.c b/criu/crtools.c index 4f5d13957..7a32d9443 100644 --- a/criu/crtools.c +++ b/criu/crtools.c @@ -437,6 +437,9 @@ usage: " Namespace can be specified as either pid or file path.\n" " OPTIONS can be used to specify parameters for userns:\n" " user:PID,UID,GID\n" +" --file-validation METHOD\n" + "pass the validation method to be used; argument\n" + "can be 'filesize' or 'buildid' (default).\n" "\n" "Check options:\n" " Without options, \"criu check\" checks availability of absolutely required\n" diff --git a/criu/files-reg.c b/criu/files-reg.c index 27b8164ce..2914b4941 100644 --- a/criu/files-reg.c +++ b/criu/files-reg.c @@ -1632,7 +1632,8 @@ static bool store_validation_data(RegFileEntry *rfe, rfe->has_size = true; rfe->size = p->stat.st_size; - result = store_validation_data_build_id(rfe, lfd, p); + if (opts.file_validation_method == FILE_VALIDATION_BUILD_ID) + result = store_validation_data_build_id(rfe, lfd, p); if (result == -1) return false; @@ -2053,7 +2054,8 @@ static bool validate_file(const int fd, const struct stat *fd_status, return false; } - result = validate_with_build_id(fd, fd_status, rfi); + if (opts.file_validation_method == FILE_VALIDATION_BUILD_ID) + result = validate_with_build_id(fd, fd_status, rfi); if (result == -1) return false; diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h index d5655212d..ac1c9e9c7 100644 --- a/criu/include/cr_options.h +++ b/criu/include/cr_options.h @@ -63,6 +63,24 @@ struct cg_root_opt { #define DEFAULT_TIMEOUT 10 +enum FILE_VALIDATION_OPTIONS +{ + /* + * This constant indicates that the file validation should be tried with the + * file size method by default. + */ + FILE_VALIDATION_FILE_SIZE, + + /* + * This constant indicates that the file validation should be tried with the + * build-ID method by default. + */ + FILE_VALIDATION_BUILD_ID +}; + +/* This constant dictates which file validation method should be tried by default. */ +#define FILE_VALIDATION_DEFAULT FILE_VALIDATION_BUILD_ID + struct irmap; struct irmap_path_opt { @@ -153,6 +171,9 @@ struct cr_options { char *tls_key; int tls; int tls_no_cn_verify; + + /* This stores which method to use for file validation. */ + int file_validation_method; }; extern struct cr_options opts;