mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 22:35:33 +00:00
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: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
52
cr-dump.c
52
cr-dump.c
@@ -348,21 +348,6 @@ static int dump_task_special_files(pid_t pid, const struct cr_fdset *cr_fdset)
|
|||||||
struct fd_parms params;
|
struct fd_parms params;
|
||||||
int fd, ret;
|
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(¶ms, fd, cr_fdset);
|
|
||||||
close(fd);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Dump /proc/pid/exe */
|
/* Dump /proc/pid/exe */
|
||||||
params = (struct fd_parms) {
|
params = (struct fd_parms) {
|
||||||
.id = FD_ID_INVALID,
|
.id = FD_ID_INVALID,
|
||||||
@@ -488,6 +473,36 @@ err:
|
|||||||
return ret;
|
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
|
struct shmem_info
|
||||||
{
|
{
|
||||||
unsigned long size;
|
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);
|
pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
|
||||||
goto err;
|
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:
|
err:
|
||||||
close_cr_fdset(&cr_fdset);
|
close_cr_fdset(&cr_fdset);
|
||||||
close_pid_proc();
|
close_pid_proc();
|
||||||
|
@@ -510,6 +510,9 @@ static int restore_one_alive_task(int pid)
|
|||||||
if (prepare_fds(pid))
|
if (prepare_fds(pid))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (prepare_fs(pid))
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (prepare_sigactions(pid))
|
if (prepare_sigactions(pid))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
13
cr-show.c
13
cr-show.c
@@ -59,7 +59,6 @@ static char *fdtype2s(u8 type)
|
|||||||
static char und[4];
|
static char und[4];
|
||||||
static char *fdtypes[] = {
|
static char *fdtypes[] = {
|
||||||
[FDINFO_REG] = "reg",
|
[FDINFO_REG] = "reg",
|
||||||
[FDINFO_CWD] = "cwd",
|
|
||||||
[FDINFO_EXE] = "exe",
|
[FDINFO_EXE] = "exe",
|
||||||
[FDINFO_INETSK] = "isk",
|
[FDINFO_INETSK] = "isk",
|
||||||
[FDINFO_PIPE] = "pipe",
|
[FDINFO_PIPE] = "pipe",
|
||||||
@@ -172,6 +171,18 @@ out:
|
|||||||
pr_img_tail(CR_FD_PIPES);
|
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)
|
void show_vmas(int fd_vma, struct cr_options *o)
|
||||||
{
|
{
|
||||||
struct vma_area vma_area = {};
|
struct vma_area vma_area = {};
|
||||||
|
@@ -170,6 +170,12 @@ struct cr_fd_desc_tmpl fdset_template[CR_FD_MAX] = {
|
|||||||
.magic = IPCNS_SEM_MAGIC,
|
.magic = IPCNS_SEM_MAGIC,
|
||||||
.show = show_ipc_sem,
|
.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)
|
static struct cr_fdset *alloc_cr_fdset(int nr)
|
||||||
|
54
files.c
54
files.c
@@ -259,23 +259,6 @@ static int find_open_fe_fd(struct fdinfo_entry *fe)
|
|||||||
return open_fe_fd(&rfi->d);
|
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;
|
int self_exe_fd;
|
||||||
|
|
||||||
static int restore_exe_early(struct fdinfo_entry *fe, int 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)
|
if (state != FD_STATE_RECV)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (fe->type == FDINFO_CWD)
|
|
||||||
return restore_cwd(fe, fdinfo_fd);
|
|
||||||
if (fe->type == FDINFO_EXE)
|
if (fe->type == FDINFO_EXE)
|
||||||
return restore_exe_early(fe, fdinfo_fd);
|
return restore_exe_early(fe, fdinfo_fd);
|
||||||
|
|
||||||
@@ -550,6 +531,41 @@ int prepare_fds(int pid)
|
|||||||
return run_unix_connections();
|
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)
|
int get_filemap_fd(int pid, struct vma_entry *vma_entry)
|
||||||
{
|
{
|
||||||
struct file_desc *fd;
|
struct file_desc *fd;
|
||||||
|
@@ -26,6 +26,7 @@ enum {
|
|||||||
CR_FD_SIGACT,
|
CR_FD_SIGACT,
|
||||||
CR_FD_ITIMERS,
|
CR_FD_ITIMERS,
|
||||||
CR_FD_CREDS,
|
CR_FD_CREDS,
|
||||||
|
CR_FD_FS,
|
||||||
_CR_FD_TASK_TO,
|
_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_sigacts(int fd_sigacts, struct cr_options *o);
|
||||||
void show_itimers(int fd, struct cr_options *o);
|
void show_itimers(int fd, struct cr_options *o);
|
||||||
void show_creds(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];
|
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_MSG "ipcns-msg-%d.img"
|
||||||
#define FMT_FNAME_IPCNS_SEM "ipcns-sem-%d.img"
|
#define FMT_FNAME_IPCNS_SEM "ipcns-sem-%d.img"
|
||||||
#define FMT_FNAME_SK_QUEUES "sk-queues.img"
|
#define FMT_FNAME_SK_QUEUES "sk-queues.img"
|
||||||
|
#define FMT_FNAME_FS "fs-%d.img"
|
||||||
|
|
||||||
extern int open_image_dir(void);
|
extern int open_image_dir(void);
|
||||||
extern void close_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_fd_pid(int pid);
|
||||||
extern int prepare_shared_fdinfo(void);
|
extern int prepare_shared_fdinfo(void);
|
||||||
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
|
extern int get_filemap_fd(int pid, struct vma_entry *vma_entry);
|
||||||
|
extern int prepare_fs(int pid);
|
||||||
|
|
||||||
extern int self_exe_fd;
|
extern int self_exe_fd;
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#define IPCNS_MSG_MAGIC 0x55453737 /* Moscow */
|
#define IPCNS_MSG_MAGIC 0x55453737 /* Moscow */
|
||||||
#define IPCNS_SEM_MAGIC 0x59573019 /* St. Petersburg */
|
#define IPCNS_SEM_MAGIC 0x59573019 /* St. Petersburg */
|
||||||
#define REG_FILES_MAGIC 0x50363636 /* Belgorod */
|
#define REG_FILES_MAGIC 0x50363636 /* Belgorod */
|
||||||
|
#define FS_MAGIC 0x51403912 /* Voronezh */
|
||||||
|
|
||||||
#define PIPEFS_MAGIC 0x50495045
|
#define PIPEFS_MAGIC 0x50495045
|
||||||
|
|
||||||
@@ -37,7 +38,6 @@ enum fd_types {
|
|||||||
FDINFO_PIPE,
|
FDINFO_PIPE,
|
||||||
FDINFO_INETSK,
|
FDINFO_INETSK,
|
||||||
FDINFO_UNIXSK,
|
FDINFO_UNIXSK,
|
||||||
FDINFO_CWD,
|
|
||||||
FDINFO_EXE,
|
FDINFO_EXE,
|
||||||
|
|
||||||
FD_INFO_MAX
|
FD_INFO_MAX
|
||||||
@@ -61,9 +61,11 @@ struct fdinfo_entry {
|
|||||||
u32 id;
|
u32 id;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define fd_is_special(fe) ( \
|
#define fd_is_special(fe) ((fe)->type == FDINFO_EXE)
|
||||||
((fe)->type == FDINFO_CWD) || \
|
|
||||||
((fe)->type == FDINFO_EXE))
|
struct fs_entry {
|
||||||
|
u32 cwd_id;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
struct pstree_entry {
|
struct pstree_entry {
|
||||||
u32 pid;
|
u32 pid;
|
||||||
|
Reference in New Issue
Block a user