cr-service: refactor images/workdir setup

Move the code that opens the images directory, resolves its absolute
path via readlink(), selects the work_dir, and chdir()s into it into a
new function: setup_images_and_workdir(). This reduces the size of
`setup_opts_from_req()`, improves its readability, and allows this
functionality to be reused.

While at it, change open_image_dir() to take a const char *dir
parameter, reflecting that the path is not modified by the function and
allowing callers to pass string literals without casts.

No functional changes are intended.

Signed-off-by: Radostin Stoyanov <rstoyanov@fedoraproject.org>
This commit is contained in:
Radostin Stoyanov 2025-10-24 06:42:53 +01:00 committed by Andrei Vagin
parent 71a637923f
commit ee4100c09f
3 changed files with 45 additions and 33 deletions

View file

@ -285,13 +285,54 @@ int exec_rpc_query_external_files(char *name, int sk)
static char images_dir[PATH_MAX];
static int setup_images_and_workdir(const char *images_dir_path,
bool work_changed_by_rpc_conf,
CriuOpts *req,
pid_t peer_pid)
{
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;
}
/* get full path to images_dir to use in process title */
if (readlink(images_dir_path, images_dir, PATH_MAX) == -1) {
pr_perror("Can't readlink %s", images_dir_path);
return -1;
}
if (work_changed_by_rpc_conf)
strncpy(work_dir_path, opts.work_dir, PATH_MAX - 1);
else if (req->has_work_dir_fd)
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
strcpy(work_dir_path, images_dir_path);
if (chdir(work_dir_path)) {
pr_perror("Can't chdir to work_dir");
return -1;
}
return 0;
}
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 work_dir_path[PATH_MAX];
char status_fd[PATH_MAX];
bool output_changed_by_rpc_conf = false;
bool work_changed_by_rpc_conf = false;
@ -701,37 +742,8 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
if (req->parent_img)
SET_CHAR_OPTS(img_parent, req->parent_img);
/*
* 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");
if (setup_images_and_workdir(images_dir_path, work_changed_by_rpc_conf, req, ids.pid))
goto err;
}
/* get full path to images_dir to use in process title */
if (readlink(images_dir_path, images_dir, PATH_MAX) == -1) {
pr_perror("Can't readlink %s", images_dir_path);
goto err;
}
if (work_changed_by_rpc_conf)
strncpy(work_dir_path, opts.work_dir, PATH_MAX - 1);
else if (req->has_work_dir_fd)
sprintf(work_dir_path, "/proc/%d/fd/%d", ids.pid, req->work_dir_fd);
else if (opts.work_dir)
strncpy(work_dir_path, opts.work_dir, PATH_MAX - 1);
else
strcpy(work_dir_path, images_dir_path);
if (chdir(work_dir_path)) {
pr_perror("Can't chdir to work_dir");
goto err;
}
if (req->n_irmap_scan_paths) {
for (i = 0; i < req->n_irmap_scan_paths; i++) {

View file

@ -717,7 +717,7 @@ struct cr_img *img_from_fd(int fd)
* This is used when opts.stream is enabled for picking the right streamer
* socket name. `mode` is ignored when opts.stream is not enabled.
*/
int open_image_dir(char *dir, int mode)
int open_image_dir(const char *dir, int mode)
{
int fd, ret;

View file

@ -165,7 +165,7 @@ static inline int img_raw_fd(struct cr_img *img)
extern off_t img_raw_size(struct cr_img *img);
extern int open_image_dir(char *dir, int mode);
extern int open_image_dir(const char *dir, int mode);
extern void close_image_dir(void);
/*
* Return -1 -- parent symlink points to invalid target