mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 23:05:39 +00:00
Use absolute path for image files
Now I try to restore CWD and a relative path will be invalid. Add new options -D to set image files directory. Signed-off-by: Andrey Vagin <avagin@openvz.org> Acked-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
This commit is contained in:
committed by
Cyrill Gorcunov
parent
a5439d5fed
commit
d261cf7958
30
cr-restore.c
30
cr-restore.c
@@ -295,7 +295,7 @@ static int prepare_shmem_pid(int pid)
|
||||
int sh_fd;
|
||||
u32 type = 0;
|
||||
|
||||
sh_fd = open_fmt_ro(FMT_FNAME_SHMEM, pid);
|
||||
sh_fd = open_image_ro(FMT_FNAME_SHMEM, pid);
|
||||
if (sh_fd < 0) {
|
||||
pr_perror("%d: Can't open shmem info\n", pid);
|
||||
return 1;
|
||||
@@ -333,7 +333,7 @@ static int prepare_pipes_pid(int pid)
|
||||
int p_fd;
|
||||
u32 type = 0;
|
||||
|
||||
p_fd = open_fmt_ro(FMT_FNAME_PIPES, pid);
|
||||
p_fd = open_image_ro(FMT_FNAME_PIPES, pid);
|
||||
if (p_fd < 0) {
|
||||
pr_perror("%d: Can't open pipes image\n", pid);
|
||||
return 1;
|
||||
@@ -514,7 +514,7 @@ static int prepare_fds(int pid)
|
||||
|
||||
pr_info("%d: Opening files img\n", pid);
|
||||
|
||||
fdinfo_fd = open_fmt_ro(FMT_FNAME_FDINFO, pid);
|
||||
fdinfo_fd = open_image_ro(FMT_FNAME_FDINFO, pid);
|
||||
if (fdinfo_fd < 0) {
|
||||
pr_perror("Can't open %d fdinfo", pid);
|
||||
return 1;
|
||||
@@ -593,7 +593,7 @@ static int prepare_shmem(int pid)
|
||||
int sh_fd;
|
||||
u32 type = 0;
|
||||
|
||||
sh_fd = open_fmt_ro(FMT_FNAME_SHMEM, pid);
|
||||
sh_fd = open_image_ro(FMT_FNAME_SHMEM, pid);
|
||||
if (sh_fd < 0) {
|
||||
pr_perror("%d: Can't open shmem info\n", pid);
|
||||
return 1;
|
||||
@@ -754,7 +754,7 @@ static int fixup_pages_data(int pid, int fd)
|
||||
|
||||
pr_info("%d: Reading shmem pages img\n", pid);
|
||||
|
||||
shfd = open_fmt_ro(FMT_FNAME_PAGES_SHMEM, pid);
|
||||
shfd = open_image_ro(FMT_FNAME_PAGES_SHMEM, pid);
|
||||
if (shfd < 0) {
|
||||
pr_perror("Can't open %d shmem image %s\n", pid);
|
||||
return 1;
|
||||
@@ -836,7 +836,7 @@ static int prepare_and_sigreturn(int pid)
|
||||
int fd, fd_new;
|
||||
struct stat buf;
|
||||
|
||||
fd = open_fmt_ro(FMT_FNAME_CORE, pid);
|
||||
fd = open_image_ro(FMT_FNAME_CORE, pid);
|
||||
if (fd < 0) {
|
||||
pr_perror("%d: Can't open exec image\n", pid);
|
||||
return 1;
|
||||
@@ -846,7 +846,7 @@ static int prepare_and_sigreturn(int pid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf(path, FMT_FNAME_CORE_OUT, pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_CORE_OUT, pid);
|
||||
unlink(path);
|
||||
|
||||
fd_new = open(path, O_RDWR | O_CREAT | O_EXCL, CR_FD_PERM);
|
||||
@@ -1058,7 +1058,7 @@ static int prepare_sigactions(int pid)
|
||||
u32 type = 0;
|
||||
int sig, i;
|
||||
|
||||
fd_sigact = open_fmt_ro(FMT_FNAME_SIGACTS, pid);
|
||||
fd_sigact = open_image_ro(FMT_FNAME_SIGACTS, pid);
|
||||
if (fd_sigact < 0) {
|
||||
pr_perror("%d: Can't open sigactions img\n", pid);
|
||||
return 1;
|
||||
@@ -1111,7 +1111,7 @@ static int prepare_pipes(int pid)
|
||||
|
||||
pr_info("%d: Opening pipes\n", pid);
|
||||
|
||||
pipes_fd = open_fmt_ro(FMT_FNAME_PIPES, pid);
|
||||
pipes_fd = open_image_ro(FMT_FNAME_PIPES, pid);
|
||||
if (pipes_fd < 0) {
|
||||
pr_perror("%d: Can't open pipes img\n", pid);
|
||||
return 1;
|
||||
@@ -1310,7 +1310,7 @@ static int restore_all_tasks(pid_t pid)
|
||||
int pstree_fd;
|
||||
u32 type = 0;
|
||||
|
||||
sprintf(path, FMT_FNAME_PSTREE, pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_PSTREE, pid);
|
||||
pstree_fd = open(path, O_RDONLY);
|
||||
if (pstree_fd < 0) {
|
||||
pr_perror("%d: Can't open pstree image\n", pid);
|
||||
@@ -1349,7 +1349,7 @@ static long restorer_get_vma_hint(pid_t pid, struct list_head *self_vma_list, lo
|
||||
* better to stick with it.
|
||||
*/
|
||||
|
||||
snprintf(path, sizeof(path), FMT_FNAME_CORE, pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_CORE, pid);
|
||||
fd = open(path, O_RDONLY, CR_FD_PERM);
|
||||
if (fd < 0) {
|
||||
pr_perror("Can't open %s\n", path);
|
||||
@@ -1431,21 +1431,21 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
||||
BUILD_BUG_ON(sizeof(struct task_restore_core_args) & 1);
|
||||
BUILD_BUG_ON(sizeof(struct thread_restore_args) & 1);
|
||||
|
||||
snprintf(path, sizeof(path), FMT_FNAME_PSTREE, pstree_pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_PSTREE, pstree_pid);
|
||||
fd_pstree = open(path, O_RDONLY, CR_FD_PERM);
|
||||
if (fd_pstree < 0) {
|
||||
pr_perror("Can't open %s\n", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(path, sizeof(path), FMT_FNAME_CORE_OUT, pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_CORE_OUT, pid);
|
||||
fd_core = open(path, O_RDONLY, CR_FD_PERM);
|
||||
if (fd_core < 0) {
|
||||
pr_perror("Can't open %s\n", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(self_vmas_path, sizeof(self_vmas_path), FMT_FNAME_VMAS, getpid());
|
||||
IMAGE_PATH(self_vmas_path, FMT_FNAME_VMAS, getpid());
|
||||
unlink(self_vmas_path);
|
||||
fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR, CR_FD_PERM);
|
||||
if (fd_self_vmas < 0) {
|
||||
@@ -1593,7 +1593,7 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid)
|
||||
read_ptr_safe(fd_pstree, &thread_args[i].pid, err);
|
||||
|
||||
/* Core files are to be opened */
|
||||
snprintf(path, sizeof(path), FMT_FNAME_CORE, thread_args[i].pid);
|
||||
IMAGE_PATH(path, FMT_FNAME_CORE, thread_args[i].pid);
|
||||
thread_args[i].fd_core = open(path, O_RDONLY, CR_FD_PERM);
|
||||
if (thread_args[i].fd_core < 0) {
|
||||
pr_perror("Can't open %s\n", path);
|
||||
|
36
crtools.c
36
crtools.c
@@ -91,6 +91,7 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid)
|
||||
{
|
||||
struct cr_fdset *cr_fdset;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
cr_fdset = xzalloc(sizeof(*cr_fdset));
|
||||
if (!cr_fdset)
|
||||
@@ -98,10 +99,14 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid)
|
||||
|
||||
for (i = 0; i < CR_FD_MAX; i++) {
|
||||
cr_fdset->desc[i].tmpl = &fdset_template[i];
|
||||
snprintf(cr_fdset->desc[i].name,
|
||||
ret = get_image_path(cr_fdset->desc[i].name,
|
||||
sizeof(cr_fdset->desc[i].name),
|
||||
cr_fdset->desc[i].tmpl->fmt,
|
||||
pid);
|
||||
if (ret) {
|
||||
xfree(cr_fdset);
|
||||
return NULL;
|
||||
}
|
||||
cr_fdset->desc[i].fd = -1;
|
||||
}
|
||||
|
||||
@@ -226,6 +231,22 @@ void free_cr_fdset(struct cr_fdset **cr_fdset)
|
||||
}
|
||||
}
|
||||
|
||||
char image_dir[PATH_MAX];
|
||||
int get_image_path(char *path, int size, const char *fmt, int pid)
|
||||
{
|
||||
int image_dir_size = strlen(image_dir);
|
||||
int ret;
|
||||
|
||||
strcpy(path, image_dir);
|
||||
path[image_dir_size] = '/';
|
||||
ret = snprintf(path + image_dir_size + 1, size, fmt, pid);
|
||||
if (ret == -1 || ret > size) {
|
||||
pr_err("can't get image path");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
pid_t pid;
|
||||
@@ -233,7 +254,7 @@ int main(int argc, char *argv[])
|
||||
int opt, idx;
|
||||
int action = -1;
|
||||
|
||||
static const char short_opts[] = "drskf:p:t:hc";
|
||||
static const char short_opts[] = "drskf:p:t:hcD:";
|
||||
static const struct option long_opts[] = {
|
||||
{ "dump", no_argument, NULL, 'd' },
|
||||
{ "restore", no_argument, NULL, 'r' },
|
||||
@@ -284,12 +305,23 @@ int main(int argc, char *argv[])
|
||||
case 'k':
|
||||
opts.final_state = CR_TASK_KILL;
|
||||
break;
|
||||
case 'D':
|
||||
if (chdir(optarg)) {
|
||||
pr_perror("can't change working directory");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
|
||||
if (getcwd(image_dir, sizeof(image_dir)) < 0) {
|
||||
pr_perror("can't get currect directory\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case 'd':
|
||||
ret = cr_dump_tasks(pid, &opts);
|
||||
|
@@ -58,6 +58,12 @@ struct cr_fd_desc_tmpl {
|
||||
#define FMT_FNAME_VMAS "vmas-%d.img"
|
||||
#define FMT_FNAME_SIGACTS "sigacts-%d.img"
|
||||
|
||||
extern int get_image_path(char *path, int size, const char *fmt, int pid);
|
||||
#define IMAGE_PATH(path, fmt, pid) get_image_path(path, sizeof(path), fmt, pid);
|
||||
|
||||
extern char image_dir[];
|
||||
#define open_image_ro(fmt, ...) open_fmt("%s/" fmt, O_RDONLY, image_dir, __VA_ARGS__)
|
||||
|
||||
#define LAST_PID_PATH "/proc/sys/kernel/ns_last_pid"
|
||||
#define LAST_PID_PERM 0666
|
||||
|
||||
|
@@ -174,8 +174,6 @@ DIR *opendir_proc(char *fmt, ...);
|
||||
FILE *fopen_proc(char *fmt, char *mode, ...);
|
||||
int open_fmt(char *fmt, int mode, ...);
|
||||
|
||||
#define open_fmt_ro(fmt, ...) open_fmt(fmt, O_RDONLY, __VA_ARGS__)
|
||||
|
||||
#define __xalloc(op, size, ...) \
|
||||
({ \
|
||||
void *___p = op( __VA_ARGS__ ); \
|
||||
|
@@ -345,20 +345,12 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
|
||||
parasite_args_cmd_dumpsigacts_t parasite_sigacts = { };
|
||||
|
||||
int status, path_len, ret = -1;
|
||||
char *cwd = NULL;
|
||||
|
||||
pr_info("\n");
|
||||
pr_info("Dumping sigactions (pid: %d)\n", ctl->pid);
|
||||
pr_info("----------------------------------------\n");
|
||||
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd) {
|
||||
pr_err("No memory to obtain cwd\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
path_len = strlen(cr_fdset->desc[CR_FD_SIGACT].name) +
|
||||
strlen(cwd) + 2;
|
||||
path_len = strlen(cr_fdset->desc[CR_FD_SIGACT].name);
|
||||
|
||||
if (path_len > sizeof(parasite_sigacts.open_path)) {
|
||||
pr_panic("Dumping sigactions path is too long (%d while %d allowed)\n",
|
||||
@@ -371,9 +363,9 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
|
||||
goto out;
|
||||
}
|
||||
|
||||
snprintf(parasite_sigacts.open_path,
|
||||
sizeof(parasite_sigacts.open_path),
|
||||
"%s/%s", cwd, cr_fdset->desc[CR_FD_SIGACT].name);
|
||||
strncpy(parasite_sigacts.open_path,
|
||||
cr_fdset->desc[CR_FD_SIGACT].name,
|
||||
sizeof(parasite_sigacts.open_path));
|
||||
|
||||
parasite_sigacts.open_flags = O_WRONLY;
|
||||
parasite_sigacts.open_mode = CR_FD_PERM_DUMP;
|
||||
@@ -385,7 +377,6 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
|
||||
err:
|
||||
jerr(fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM), out);
|
||||
out:
|
||||
xfree(cwd);
|
||||
pr_info("----------------------------------------\n");
|
||||
|
||||
return ret;
|
||||
@@ -406,20 +397,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
|
||||
struct vma_area *vma_area;
|
||||
siginfo_t siginfo;
|
||||
int status, path_len, ret = -1;
|
||||
char *cwd = NULL;
|
||||
|
||||
pr_info("\n");
|
||||
pr_info("Dumping pages (type: %d pid: %d)\n", fd_type, ctl->pid);
|
||||
pr_info("----------------------------------------\n");
|
||||
|
||||
cwd = get_current_dir_name();
|
||||
if (!cwd) {
|
||||
pr_err("No memory to obtain cwd\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
path_len = strlen(cr_fdset->desc[fd_type].name) +
|
||||
strlen(cwd) + 2;
|
||||
path_len = strlen(cr_fdset->desc[fd_type].name);
|
||||
pr_info("Dumping pages %s\n", cr_fdset->desc[fd_type].name);
|
||||
|
||||
if (path_len > sizeof(parasite_dumppages.open_path)) {
|
||||
pr_panic("Dumping pages path is too long (%d while %d allowed)\n",
|
||||
@@ -438,9 +422,9 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
|
||||
*/
|
||||
fsync(cr_fdset->desc[fd_type].fd);
|
||||
|
||||
snprintf(parasite_dumppages.open_path,
|
||||
sizeof(parasite_dumppages.open_path),
|
||||
"%s/%s", cwd, cr_fdset->desc[fd_type].name);
|
||||
strncpy(parasite_dumppages.open_path,
|
||||
cr_fdset->desc[fd_type].name,
|
||||
sizeof(parasite_dumppages.open_path));
|
||||
|
||||
parasite_dumppages.open_flags = O_WRONLY;
|
||||
parasite_dumppages.open_mode = CR_FD_PERM_DUMP;
|
||||
@@ -511,7 +495,6 @@ err_restore:
|
||||
jerr(fchmod(cr_fdset->desc[fd_type].fd, CR_FD_PERM), out);
|
||||
|
||||
out:
|
||||
xfree(cwd);
|
||||
pr_info("----------------------------------------\n");
|
||||
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user