mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-03 07:45:17 +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;
|
||||
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 */
|
||||
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;
|
||||
|
||||
|
13
cr-show.c
13
cr-show.c
@@ -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)
|
||||
|
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
Reference in New Issue
Block a user