Commit d261cf79 authored by Andrey Vagin's avatar Andrey Vagin Committed by Cyrill Gorcunov

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: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent a5439d5f
...@@ -295,7 +295,7 @@ static int prepare_shmem_pid(int pid) ...@@ -295,7 +295,7 @@ static int prepare_shmem_pid(int pid)
int sh_fd; int sh_fd;
u32 type = 0; 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) { if (sh_fd < 0) {
pr_perror("%d: Can't open shmem info\n", pid); pr_perror("%d: Can't open shmem info\n", pid);
return 1; return 1;
...@@ -333,7 +333,7 @@ static int prepare_pipes_pid(int pid) ...@@ -333,7 +333,7 @@ static int prepare_pipes_pid(int pid)
int p_fd; int p_fd;
u32 type = 0; 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) { if (p_fd < 0) {
pr_perror("%d: Can't open pipes image\n", pid); pr_perror("%d: Can't open pipes image\n", pid);
return 1; return 1;
...@@ -514,7 +514,7 @@ static int prepare_fds(int pid) ...@@ -514,7 +514,7 @@ static int prepare_fds(int pid)
pr_info("%d: Opening files img\n", 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) { if (fdinfo_fd < 0) {
pr_perror("Can't open %d fdinfo", pid); pr_perror("Can't open %d fdinfo", pid);
return 1; return 1;
...@@ -593,7 +593,7 @@ static int prepare_shmem(int pid) ...@@ -593,7 +593,7 @@ static int prepare_shmem(int pid)
int sh_fd; int sh_fd;
u32 type = 0; 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) { if (sh_fd < 0) {
pr_perror("%d: Can't open shmem info\n", pid); pr_perror("%d: Can't open shmem info\n", pid);
return 1; return 1;
...@@ -754,7 +754,7 @@ static int fixup_pages_data(int pid, int fd) ...@@ -754,7 +754,7 @@ static int fixup_pages_data(int pid, int fd)
pr_info("%d: Reading shmem pages img\n", pid); 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) { if (shfd < 0) {
pr_perror("Can't open %d shmem image %s\n", pid); pr_perror("Can't open %d shmem image %s\n", pid);
return 1; return 1;
...@@ -836,7 +836,7 @@ static int prepare_and_sigreturn(int pid) ...@@ -836,7 +836,7 @@ static int prepare_and_sigreturn(int pid)
int fd, fd_new; int fd, fd_new;
struct stat buf; struct stat buf;
fd = open_fmt_ro(FMT_FNAME_CORE, pid); fd = open_image_ro(FMT_FNAME_CORE, pid);
if (fd < 0) { if (fd < 0) {
pr_perror("%d: Can't open exec image\n", pid); pr_perror("%d: Can't open exec image\n", pid);
return 1; return 1;
...@@ -846,7 +846,7 @@ static int prepare_and_sigreturn(int pid) ...@@ -846,7 +846,7 @@ static int prepare_and_sigreturn(int pid)
return 1; return 1;
} }
sprintf(path, FMT_FNAME_CORE_OUT, pid); IMAGE_PATH(path, FMT_FNAME_CORE_OUT, pid);
unlink(path); unlink(path);
fd_new = open(path, O_RDWR | O_CREAT | O_EXCL, CR_FD_PERM); fd_new = open(path, O_RDWR | O_CREAT | O_EXCL, CR_FD_PERM);
...@@ -1058,7 +1058,7 @@ static int prepare_sigactions(int pid) ...@@ -1058,7 +1058,7 @@ static int prepare_sigactions(int pid)
u32 type = 0; u32 type = 0;
int sig, i; 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) { if (fd_sigact < 0) {
pr_perror("%d: Can't open sigactions img\n", pid); pr_perror("%d: Can't open sigactions img\n", pid);
return 1; return 1;
...@@ -1111,7 +1111,7 @@ static int prepare_pipes(int pid) ...@@ -1111,7 +1111,7 @@ static int prepare_pipes(int pid)
pr_info("%d: Opening pipes\n", 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) { if (pipes_fd < 0) {
pr_perror("%d: Can't open pipes img\n", pid); pr_perror("%d: Can't open pipes img\n", pid);
return 1; return 1;
...@@ -1310,7 +1310,7 @@ static int restore_all_tasks(pid_t pid) ...@@ -1310,7 +1310,7 @@ static int restore_all_tasks(pid_t pid)
int pstree_fd; int pstree_fd;
u32 type = 0; u32 type = 0;
sprintf(path, FMT_FNAME_PSTREE, pid); IMAGE_PATH(path, FMT_FNAME_PSTREE, pid);
pstree_fd = open(path, O_RDONLY); pstree_fd = open(path, O_RDONLY);
if (pstree_fd < 0) { if (pstree_fd < 0) {
pr_perror("%d: Can't open pstree image\n", pid); 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 ...@@ -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. * 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); fd = open(path, O_RDONLY, CR_FD_PERM);
if (fd < 0) { if (fd < 0) {
pr_perror("Can't open %s\n", path); pr_perror("Can't open %s\n", path);
...@@ -1431,21 +1431,21 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -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 task_restore_core_args) & 1);
BUILD_BUG_ON(sizeof(struct thread_restore_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); fd_pstree = open(path, O_RDONLY, CR_FD_PERM);
if (fd_pstree < 0) { if (fd_pstree < 0) {
pr_perror("Can't open %s\n", path); pr_perror("Can't open %s\n", path);
goto err; 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); fd_core = open(path, O_RDONLY, CR_FD_PERM);
if (fd_core < 0) { if (fd_core < 0) {
pr_perror("Can't open %s\n", path); pr_perror("Can't open %s\n", path);
goto err; 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); unlink(self_vmas_path);
fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR, CR_FD_PERM); fd_self_vmas = open(self_vmas_path, O_CREAT | O_RDWR, CR_FD_PERM);
if (fd_self_vmas < 0) { if (fd_self_vmas < 0) {
...@@ -1593,7 +1593,7 @@ static void sigreturn_restore(pid_t pstree_pid, pid_t pid) ...@@ -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); read_ptr_safe(fd_pstree, &thread_args[i].pid, err);
/* Core files are to be opened */ /* 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); thread_args[i].fd_core = open(path, O_RDONLY, CR_FD_PERM);
if (thread_args[i].fd_core < 0) { if (thread_args[i].fd_core < 0) {
pr_perror("Can't open %s\n", path); pr_perror("Can't open %s\n", path);
......
...@@ -91,6 +91,7 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid) ...@@ -91,6 +91,7 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid)
{ {
struct cr_fdset *cr_fdset; struct cr_fdset *cr_fdset;
unsigned int i; unsigned int i;
int ret;
cr_fdset = xzalloc(sizeof(*cr_fdset)); cr_fdset = xzalloc(sizeof(*cr_fdset));
if (!cr_fdset) if (!cr_fdset)
...@@ -98,10 +99,14 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid) ...@@ -98,10 +99,14 @@ struct cr_fdset *alloc_cr_fdset(pid_t pid)
for (i = 0; i < CR_FD_MAX; i++) { for (i = 0; i < CR_FD_MAX; i++) {
cr_fdset->desc[i].tmpl = &fdset_template[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), sizeof(cr_fdset->desc[i].name),
cr_fdset->desc[i].tmpl->fmt, cr_fdset->desc[i].tmpl->fmt,
pid); pid);
if (ret) {
xfree(cr_fdset);
return NULL;
}
cr_fdset->desc[i].fd = -1; cr_fdset->desc[i].fd = -1;
} }
...@@ -226,6 +231,22 @@ void free_cr_fdset(struct cr_fdset **cr_fdset) ...@@ -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[]) int main(int argc, char *argv[])
{ {
pid_t pid; pid_t pid;
...@@ -233,7 +254,7 @@ int main(int argc, char *argv[]) ...@@ -233,7 +254,7 @@ int main(int argc, char *argv[])
int opt, idx; int opt, idx;
int action = -1; 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[] = { static const struct option long_opts[] = {
{ "dump", no_argument, NULL, 'd' }, { "dump", no_argument, NULL, 'd' },
{ "restore", no_argument, NULL, 'r' }, { "restore", no_argument, NULL, 'r' },
...@@ -284,12 +305,23 @@ int main(int argc, char *argv[]) ...@@ -284,12 +305,23 @@ int main(int argc, char *argv[])
case 'k': case 'k':
opts.final_state = CR_TASK_KILL; opts.final_state = CR_TASK_KILL;
break; break;
case 'D':
if (chdir(optarg)) {
pr_perror("can't change working directory");
return 1;
}
break;
case 'h': case 'h':
default: default:
goto usage; goto usage;
} }
} }
if (getcwd(image_dir, sizeof(image_dir)) < 0) {
pr_perror("can't get currect directory\n");
return 1;
}
switch (action) { switch (action) {
case 'd': case 'd':
ret = cr_dump_tasks(pid, &opts); ret = cr_dump_tasks(pid, &opts);
......
...@@ -58,6 +58,12 @@ struct cr_fd_desc_tmpl { ...@@ -58,6 +58,12 @@ struct cr_fd_desc_tmpl {
#define FMT_FNAME_VMAS "vmas-%d.img" #define FMT_FNAME_VMAS "vmas-%d.img"
#define FMT_FNAME_SIGACTS "sigacts-%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_PATH "/proc/sys/kernel/ns_last_pid"
#define LAST_PID_PERM 0666 #define LAST_PID_PERM 0666
......
...@@ -174,8 +174,6 @@ DIR *opendir_proc(char *fmt, ...); ...@@ -174,8 +174,6 @@ DIR *opendir_proc(char *fmt, ...);
FILE *fopen_proc(char *fmt, char *mode, ...); FILE *fopen_proc(char *fmt, char *mode, ...);
int open_fmt(char *fmt, int mode, ...); int open_fmt(char *fmt, int mode, ...);
#define open_fmt_ro(fmt, ...) open_fmt(fmt, O_RDONLY, __VA_ARGS__)
#define __xalloc(op, size, ...) \ #define __xalloc(op, size, ...) \
({ \ ({ \
void *___p = op( __VA_ARGS__ ); \ void *___p = op( __VA_ARGS__ ); \
......
...@@ -345,20 +345,12 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f ...@@ -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 = { }; parasite_args_cmd_dumpsigacts_t parasite_sigacts = { };
int status, path_len, ret = -1; int status, path_len, ret = -1;
char *cwd = NULL;
pr_info("\n"); pr_info("\n");
pr_info("Dumping sigactions (pid: %d)\n", ctl->pid); pr_info("Dumping sigactions (pid: %d)\n", ctl->pid);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
cwd = get_current_dir_name(); path_len = strlen(cr_fdset->desc[CR_FD_SIGACT].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;
if (path_len > sizeof(parasite_sigacts.open_path)) { if (path_len > sizeof(parasite_sigacts.open_path)) {
pr_panic("Dumping sigactions path is too long (%d while %d allowed)\n", 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 ...@@ -371,9 +363,9 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
goto out; goto out;
} }
snprintf(parasite_sigacts.open_path, strncpy(parasite_sigacts.open_path,
sizeof(parasite_sigacts.open_path), cr_fdset->desc[CR_FD_SIGACT].name,
"%s/%s", cwd, cr_fdset->desc[CR_FD_SIGACT].name); sizeof(parasite_sigacts.open_path));
parasite_sigacts.open_flags = O_WRONLY; parasite_sigacts.open_flags = O_WRONLY;
parasite_sigacts.open_mode = CR_FD_PERM_DUMP; 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 ...@@ -385,7 +377,6 @@ int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_f
err: err:
jerr(fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM), out); jerr(fchmod(cr_fdset->desc[CR_FD_SIGACT].fd, CR_FD_PERM), out);
out: out:
xfree(cwd);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
return ret; return ret;
...@@ -406,20 +397,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a ...@@ -406,20 +397,13 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl, struct list_head *vma_a
struct vma_area *vma_area; struct vma_area *vma_area;
siginfo_t siginfo; siginfo_t siginfo;
int status, path_len, ret = -1; int status, path_len, ret = -1;
char *cwd = NULL;
pr_info("\n"); pr_info("\n");
pr_info("Dumping pages (type: %d pid: %d)\n", fd_type, ctl->pid); pr_info("Dumping pages (type: %d pid: %d)\n", fd_type, ctl->pid);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
cwd = get_current_dir_name(); path_len = strlen(cr_fdset->desc[fd_type].name);
if (!cwd) { pr_info("Dumping pages %s\n", cr_fdset->desc[fd_type].name);
pr_err("No memory to obtain cwd\n");
goto out;
}
path_len = strlen(cr_fdset->desc[fd_type].name) +
strlen(cwd) + 2;
if (path_len > sizeof(parasite_dumppages.open_path)) { if (path_len > sizeof(parasite_dumppages.open_path)) {
pr_panic("Dumping pages path is too long (%d while %d allowed)\n", 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 ...@@ -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); fsync(cr_fdset->desc[fd_type].fd);
snprintf(parasite_dumppages.open_path, strncpy(parasite_dumppages.open_path,
sizeof(parasite_dumppages.open_path), cr_fdset->desc[fd_type].name,
"%s/%s", cwd, cr_fdset->desc[fd_type].name); sizeof(parasite_dumppages.open_path));
parasite_dumppages.open_flags = O_WRONLY; parasite_dumppages.open_flags = O_WRONLY;
parasite_dumppages.open_mode = CR_FD_PERM_DUMP; parasite_dumppages.open_mode = CR_FD_PERM_DUMP;
...@@ -511,7 +495,6 @@ err_restore: ...@@ -511,7 +495,6 @@ err_restore:
jerr(fchmod(cr_fdset->desc[fd_type].fd, CR_FD_PERM), out); jerr(fchmod(cr_fdset->desc[fd_type].fd, CR_FD_PERM), out);
out: out:
xfree(cwd);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
return ret; return ret;
......
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