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)
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);
......
......@@ -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,
sizeof(cr_fdset->desc[i].name),
cr_fdset->desc[i].tmpl->fmt,
pid);
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;
......
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