Commit 4c479da2 authored by Andrey Vagin's avatar Andrey Vagin Committed by Cyrill Gorcunov

Dump and restore current work directory (v2)

CWD is saved as file descriptor with number -1.

v2: use dump_regular_file
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 d261cf79
...@@ -137,6 +137,21 @@ err: ...@@ -137,6 +137,21 @@ err:
return ret; return ret;
} }
static int dump_cwd(char *path, struct cr_fdset *cr_fdset)
{
int ret = -1;
int fd;
fd = open(path, O_RDONLY | O_DIRECTORY);
if (fd < 0) {
pr_perror("Failed to openat %s\n", path);
return -1;
}
return dump_one_reg_file(FDINFO_FD, ~0L, fd, 1, 0, 0, cr_fdset);
}
static int dump_pipe_and_data(int lfd, struct pipe_entry *e, static int dump_pipe_and_data(int lfd, struct pipe_entry *e,
struct cr_fdset *cr_fdset) struct cr_fdset *cr_fdset)
{ {
...@@ -306,6 +321,12 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset) ...@@ -306,6 +321,12 @@ static int dump_task_files(pid_t pid, struct cr_fdset *cr_fdset)
pr_info("Dumping opened files (pid: %d)\n", pid); pr_info("Dumping opened files (pid: %d)\n", pid);
pr_info("----------------------------------------\n"); pr_info("----------------------------------------\n");
snprintf(pid_fd_dir, sizeof(pid_fd_dir), "/proc/%d/cwd", pid);
if (dump_cwd(pid_fd_dir, cr_fdset)) {
pr_perror("Can't dump cwd %s\n", pid_fd_dir);
return -1;
}
snprintf(pid_fd_dir, sizeof(pid_fd_dir), "/proc/%d/fd", pid); snprintf(pid_fd_dir, sizeof(pid_fd_dir), "/proc/%d/fd", pid);
fd_dir = opendir(pid_fd_dir); fd_dir = opendir(pid_fd_dir);
if (!fd_dir) { if (!fd_dir) {
......
...@@ -437,11 +437,8 @@ static struct fmap_fd *pop_fmap_fd(int pid, unsigned long start) ...@@ -437,11 +437,8 @@ static struct fmap_fd *pop_fmap_fd(int pid, unsigned long start)
return NULL; return NULL;
} }
static int open_fe_fd(struct fdinfo_entry *fe, int fd) static int get_file_path(char *path, struct fdinfo_entry *fe, int fd)
{ {
char path[PATH_MAX];
int tmp;
if (read(fd, path, fe->len) != fe->len) { if (read(fd, path, fe->len) != fe->len) {
pr_err("Error reading path"); pr_err("Error reading path");
return -1; return -1;
...@@ -449,6 +446,17 @@ static int open_fe_fd(struct fdinfo_entry *fe, int fd) ...@@ -449,6 +446,17 @@ static int open_fe_fd(struct fdinfo_entry *fe, int fd)
path[fe->len] = '\0'; path[fe->len] = '\0';
return 0;
}
static int open_fe_fd(struct fdinfo_entry *fe, int fd)
{
char path[PATH_MAX];
int tmp;
if (get_file_path(path, fe, fd))
return -1;
tmp = open(path, fe->flags); tmp = open(path, fe->flags);
if (tmp < 0) { if (tmp < 0) {
pr_perror("Can't open file %s\n", path); pr_perror("Can't open file %s\n", path);
...@@ -460,6 +468,24 @@ static int open_fe_fd(struct fdinfo_entry *fe, int fd) ...@@ -460,6 +468,24 @@ static int open_fe_fd(struct fdinfo_entry *fe, int fd)
return tmp; return tmp;
} }
static int restore_cwd(struct fdinfo_entry *fe, int fd)
{
char path[PATH_MAX];
int ret;
if (get_file_path(path, fe, fd))
return -1;
pr_info("Restore CWD %s\n", path);
ret = chdir(path);
if (ret < 0) {
pr_perror("Can't change dir %s\n", path);
return -1;
}
return 0;
}
static int open_fd(int pid, struct fdinfo_entry *fe, int *cfd) static int open_fd(int pid, struct fdinfo_entry *fe, int *cfd)
{ {
int fd, tmp; int fd, tmp;
...@@ -474,6 +500,9 @@ static int open_fd(int pid, struct fdinfo_entry *fe, int *cfd) ...@@ -474,6 +500,9 @@ static int open_fd(int pid, struct fdinfo_entry *fe, int *cfd)
*cfd = tmp; *cfd = tmp;
} }
if (fe->addr == ~0L)
return restore_cwd(fe, *cfd);
tmp = open_fe_fd(fe, *cfd); tmp = open_fe_fd(fe, *cfd);
if (tmp < 0) if (tmp < 0)
return 1; return 1;
......
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