Commit e5e57e83 authored by Pavel Emelyanov's avatar Pavel Emelyanov

fs: Move info about cwd into separate file

Why? Because one day we'll support various CLONE_ flags and
for fdtable and fs info we'd like to have separate images (since
these objects are separate in kernel).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 69b3ebd0
......@@ -348,21 +348,6 @@ static int dump_task_special_files(pid_t pid, const struct cr_fdset *cr_fdset)
struct fd_parms params;
int fd, ret;
/* Dump /proc/pid/cwd */
params = (struct fd_parms) {
.id = FD_ID_INVALID,
.pid = FD_PID_INVALID,
.type = FDINFO_CWD,
};
fd = open_proc(pid, "cwd");
if (fd < 0)
return -1;
ret = do_dump_one_fdinfo(&params, fd, cr_fdset);
close(fd);
if (ret)
return ret;
/* Dump /proc/pid/exe */
params = (struct fd_parms) {
.id = FD_ID_INVALID,
......@@ -488,6 +473,36 @@ err:
return ret;
}
static int dump_task_fs(pid_t pid, struct cr_fdset *fdset)
{
struct fd_parms p;
struct fs_entry fe;
int fd, ret;
fd = open_proc(pid, "cwd");
if (fd < 0)
return -1;
if (fstat(fd, &p.stat) < 0) {
pr_perror("Can't stat cwd");
return -1;
}
p.type = FDINFO_REG;
p.flags = 0;
p.pos = 0;
fe.cwd_id = fd_id_generate_special();
ret = dump_one_reg_file(fd, fe.cwd_id, &p);
if (!ret) {
pr_info("Dumping task cwd id %x\n", fe.cwd_id);
ret = write_img(fdset_fd(fdset, CR_FD_FS), &fe);
}
close(fd);
return ret;
}
struct shmem_info
{
unsigned long size;
......@@ -1452,6 +1467,13 @@ static int dump_one_task(const struct pstree_item *item)
pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
goto err;
}
ret = dump_task_fs(pid, cr_fdset);
if (ret) {
pr_err("Dump fs (pid: %d) failed with %d\n", pid, ret);
goto err;
}
err:
close_cr_fdset(&cr_fdset);
close_pid_proc();
......
......@@ -510,6 +510,9 @@ static int restore_one_alive_task(int pid)
if (prepare_fds(pid))
return -1;
if (prepare_fs(pid))
return -1;
if (prepare_sigactions(pid))
return -1;
......
......@@ -59,7 +59,6 @@ static char *fdtype2s(u8 type)
static char und[4];
static char *fdtypes[] = {
[FDINFO_REG] = "reg",
[FDINFO_CWD] = "cwd",
[FDINFO_EXE] = "exe",
[FDINFO_INETSK] = "isk",
[FDINFO_PIPE] = "pipe",
......@@ -172,6 +171,18 @@ out:
pr_img_tail(CR_FD_PIPES);
}
void show_fs(int fd_fs, struct cr_options *o)
{
struct fs_entry fe;
pr_img_head(CR_FD_FS);
if (read_img(fd_fs, &fe) > 0)
pr_msg("CWD: %x\n", fe.cwd_id);
pr_img_tail(CR_FD_FS);
}
void show_vmas(int fd_vma, struct cr_options *o)
{
struct vma_area vma_area = {};
......
......@@ -170,6 +170,12 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
.magic = IPCNS_SEM_MAGIC,
.show = show_ipc_sem,
},
[CR_FD_FS] = {
.fmt = FMT_FNAME_FS,
.magic = FS_MAGIC,
.show = show_fs,
},
};
static struct cr_fdset *alloc_cr_fdset(int nr)
......
......@@ -259,23 +259,6 @@ static int find_open_fe_fd(struct fdinfo_entry *fe)
return open_fe_fd(&rfi->d);
}
static int restore_cwd(struct fdinfo_entry *fe, int fd)
{
int cfd;
cfd = find_open_fe_fd(fe);
if (cfd < 0)
return cfd;
if (fchdir(cfd)) {
pr_perror("Can't chdir");
return -1;
}
close(cfd);
return 0;
}
int self_exe_fd;
static int restore_exe_early(struct fdinfo_entry *fe, int fd)
......@@ -493,8 +476,6 @@ static int open_special_fdinfo(int pid, struct fdinfo_entry *fe,
if (state != FD_STATE_RECV)
return 0;
if (fe->type == FDINFO_CWD)
return restore_cwd(fe, fdinfo_fd);
if (fe->type == FDINFO_EXE)
return restore_exe_early(fe, fdinfo_fd);
......@@ -550,6 +531,41 @@ int prepare_fds(int pid)
return run_unix_connections();
}
int prepare_fs(int pid)
{
int ifd, cwd;
struct fs_entry fe;
struct file_desc *fd;
ifd = open_image_ro(CR_FD_FS, pid);
if (ifd < 0)
return -1;
if (read_img(ifd, &fe) < 0)
return -1;
fd = find_file_desc_raw(FDINFO_REG, fe.cwd_id);
if (fd == NULL) {
pr_err("Can't find file for %d's cwd (%x)\n",
pid, fe.cwd_id);
return -1;
}
cwd = open_fe_fd(fd);
if (cwd < 0)
return -1;
if (fchdir(cwd) < 0) {
pr_perror("Can't change root");
return -1;
}
close(cwd);
close(ifd);
return 0;
}
int get_filemap_fd(int pid, struct vma_entry *vma_entry)
{
struct file_desc *fd;
......
......@@ -26,6 +26,7 @@ enum {
CR_FD_SIGACT,
CR_FD_ITIMERS,
CR_FD_CREDS,
CR_FD_FS,
_CR_FD_TASK_TO,
/*
......@@ -90,6 +91,7 @@ void show_pstree(int fd_pstree, struct cr_options *o);
void show_sigacts(int fd_sigacts, struct cr_options *o);
void show_itimers(int fd, struct cr_options *o);
void show_creds(int fd, struct cr_options *o);
void show_fs(int fd, struct cr_options *o);
extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
......@@ -113,6 +115,7 @@ extern struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX];
#define FMT_FNAME_IPCNS_MSG "ipcns-msg-%d.img"
#define FMT_FNAME_IPCNS_SEM "ipcns-sem-%d.img"
#define FMT_FNAME_SK_QUEUES "sk-queues.img"
#define FMT_FNAME_FS "fs-%d.img"
extern int open_image_dir(void);
extern void close_image_dir(void);
......
......@@ -66,6 +66,7 @@ extern int prepare_fds(int pid);
extern int prepare_fd_pid(int pid);
extern int prepare_shared_fdinfo(void);
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
extern int prepare_fs(int pid);
extern int self_exe_fd;
......
......@@ -28,6 +28,7 @@
#define IPCNS_MSG_MAGIC 0x55453737 /* Moscow */
#define IPCNS_SEM_MAGIC 0x59573019 /* St. Petersburg */
#define REG_FILES_MAGIC 0x50363636 /* Belgorod */
#define FS_MAGIC 0x51403912 /* Voronezh */
#define PIPEFS_MAGIC 0x50495045
......@@ -37,7 +38,6 @@ enum fd_types {
FDINFO_PIPE,
FDINFO_INETSK,
FDINFO_UNIXSK,
FDINFO_CWD,
FDINFO_EXE,
FD_INFO_MAX
......@@ -61,9 +61,11 @@ struct fdinfo_entry {
u32 id;
} __packed;
#define fd_is_special(fe) ( \
((fe)->type == FDINFO_CWD) || \
((fe)->type == FDINFO_EXE))
#define fd_is_special(fe) ((fe)->type == FDINFO_EXE)
struct fs_entry {
u32 cwd_id;
} __packed;
struct pstree_entry {
u32 pid;
......
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