cr-service: refactor RPC opts parsing for check()

The check() functionality is very different from dump, pre-dump,
and restore. It is used only to check if the kernel supports required
features, and does not need the majority of options set via RPC.

In particular, we don't need to open `image_dir` when running `check()`
because this functionality doesn't create or process image files. In
this case, `image_dir` is used as `work_dir`, only when the latter is
not specified and a log file is used.

This patch updates the RPC options parser so that it only handles the
logging options when check() is used. Logging to a file is required when
log_file is explicitly set or no log_to_stderr is used. In such case, we
also resolve images_dir and work_dir where the log file will be created.

Fixes: #2758

Suggested-by: Andrei Vagin <avagin@google.com>
Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
Radostin Stoyanov 2025-10-24 07:12:03 +01:00 committed by Andrei Vagin
parent 72ca94db4d
commit 9371c4a789

View file

@ -311,6 +311,12 @@ static int resolve_images_dir_path(char *images_dir_path,
strncpy(images_dir_path, req->images_dir, PATH_MAX - 1);
images_dir_path[PATH_MAX - 1] = '\0';
} else {
/*
* Since images dir is not required in CHECK mode, we need to
* check for work_dir_fd in setup_images_and_workdir()
*/
if (opts.mode == CR_CHECK)
return 0;
pr_err("Neither images_dir_fd nor images_dir was passed by RPC client.\n");
return -1;
}
@ -323,18 +329,21 @@ static int setup_images_and_workdir(const char *images_dir_path,
CriuOpts *req,
pid_t peer_pid)
{
char work_dir_path[PATH_MAX];
char work_dir_path[PATH_MAX] = "";
/*
* Image streaming is not supported with CRIU's service feature as
* the streamer must be started for each dump/restore operation.
* It is unclear how to do that with RPC, so we punt for now.
* This explains why we provide the argument mode=-1 instead of
* O_RSTR or O_DUMP.
*/
if (open_image_dir(images_dir_path, -1) < 0) {
pr_perror("Can't open images directory");
return -1;
/* We don't need to open images dir in CHECK mode. */
if (opts.mode != CR_CHECK) {
/*
* Image streaming is not supported with CRIU's service feature as
* the streamer must be started for each dump/restore operation.
* It is unclear how to do that with RPC, so we punt for now.
* This explains why we provide the argument mode=-1 instead of
* O_RSTR or O_DUMP.
*/
if (open_image_dir(images_dir_path, -1) < 0) {
pr_perror("Can't open images directory");
return -1;
}
}
if (work_changed_by_rpc_conf)
@ -343,9 +352,14 @@ static int setup_images_and_workdir(const char *images_dir_path,
sprintf(work_dir_path, "/proc/%d/fd/%d", peer_pid, req->work_dir_fd);
else if (opts.work_dir)
strncpy(work_dir_path, opts.work_dir, PATH_MAX - 1);
else
else if (images_dir_path[0] != '\0')
strcpy(work_dir_path, images_dir_path);
if (work_dir_path[0] == '\0') {
pr_err("images-dir or work-dir is required when using log file\n");
return -1;
}
if (chdir(work_dir_path)) {
pr_perror("Can't chdir to work_dir");
return -1;
@ -384,7 +398,7 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
struct ucred ids;
struct stat st;
socklen_t ids_len = sizeof(struct ucred);
char images_dir_path[PATH_MAX];
char images_dir_path[PATH_MAX] = "";
char status_fd[PATH_MAX];
bool output_changed_by_rpc_conf = false;
bool work_changed_by_rpc_conf = false;
@ -397,6 +411,23 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
goto err;
}
/*
* The options relevant in CHECK mode are: log_file, log_to_stderr, and log_level.
* When logging to a file, we also need to resolve images_dir and work_dir.
*/
if (opts.mode == CR_CHECK) {
if (!req)
return 0; /* nothing to do */
/*
* A log file is needed only if:
* - log_file is explicitly set, or
* - log_to_stderr is NOT requested (i.e., using DEFAULT_LOG_FILENAME)
*/
if (!req->log_file || (req->has_log_to_stderr && req->log_to_stderr))
return 0; /* no log file, don't require images_dir or work_dir */
}
if (fstat(sk, &st)) {
pr_perror("Can't get socket stat");
goto err;