Commit 751856c8 authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Pre-dump file descriptors

We will generate some info about file-descriptors at that
stage. For now these pre-dumped ones would be fsnotifies,
so the pre-dump of a single fd is written as simple as
possible, but enough for that type of FDs pre-dump.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 84ebc64b
...@@ -1346,6 +1346,12 @@ static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls) ...@@ -1346,6 +1346,12 @@ static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
goto err_cure; goto err_cure;
} }
ret = predump_task_files(pid);
if (ret) {
pr_err("Pre-dumping files failed (pid: %d)\n", pid);
goto err_cure;
}
parasite_ctl->pid.virt = item->pid.virt = misc.pid; parasite_ctl->pid.virt = item->pid.virt = misc.pid;
ret = parasite_dump_pages_seized(parasite_ctl, &vmas, &parasite_ctl->mem_pp); ret = parasite_dump_pages_seized(parasite_ctl, &vmas, &parasite_ctl->mem_pp);
......
...@@ -411,6 +411,70 @@ err: ...@@ -411,6 +411,70 @@ err:
return ret; return ret;
} }
static int predump_one_fd(int pid, int fd)
{
int lfd, ret = 0;
struct statfs buf;
const struct fdtype_ops *ops;
/*
* This should look like the dump_task_files_seized,
* but since we pre-dump only *notify-s, we use the
* enightened version without fds draining.
*/
lfd = open_proc(pid, "fd/%d", fd);
if (lfd < 0)
return 0; /* That's OK, it can be a socket */
if (fstatfs(lfd, &buf)) {
pr_perror("Can't fstatfs file");
return -1;
}
if (buf.f_type != ANON_INODE_FS_MAGIC)
goto out;
if (is_inotify_link(lfd))
ops = &inotify_dump_ops;
else if (is_fanotify_link(lfd))
ops = &fanotify_dump_ops;
else
goto out;
pr_debug("Pre-dumping %d's %d fd\n", pid, fd);
ret = ops->pre_dump(pid, fd);
out:
close(lfd);
return ret;
}
int predump_task_files(int pid)
{
struct dirent *de;
DIR *fd_dir;
int ret = -1;
pr_info("Pre-dump fds for %d)\n", pid);
fd_dir = opendir_proc(pid, "fd");
if (!fd_dir)
return -1;
while ((de = readdir(fd_dir))) {
if (dir_dots(de))
continue;
if (predump_one_fd(pid, atoi(de->d_name)))
goto out;
}
ret = 0;
out:
closedir(fd_dir);
return ret;
}
int restore_fown(int fd, FownEntry *fown) int restore_fown(int fd, FownEntry *fown)
{ {
struct f_owner_ex owner; struct f_owner_ex owner;
......
...@@ -181,9 +181,20 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p) ...@@ -181,9 +181,20 @@ static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
return parse_fdinfo(lfd, FD_TYPES__INOTIFY, dump_inotify_entry, &id); return parse_fdinfo(lfd, FD_TYPES__INOTIFY, dump_inotify_entry, &id);
} }
static int pre_dump_inotify_entry(union fdinfo_entries *e, void *arg)
{
return 0;
}
static int pre_dump_one_inotify(int pid, int lfd)
{
return parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, pre_dump_inotify_entry, NULL);
}
const struct fdtype_ops inotify_dump_ops = { const struct fdtype_ops inotify_dump_ops = {
.type = FD_TYPES__INOTIFY, .type = FD_TYPES__INOTIFY,
.dump = dump_one_inotify, .dump = dump_one_inotify,
.pre_dump = pre_dump_one_inotify,
}; };
static int dump_fanotify_entry(union fdinfo_entries *e, void *arg) static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
...@@ -249,9 +260,20 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p) ...@@ -249,9 +260,20 @@ static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
return pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE); return pb_write_one(fdset_fd(glob_fdset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE);
} }
static int pre_dump_fanotify_entry(union fdinfo_entries *e, void *arg)
{
return 0;
}
static int pre_dump_one_fanotify(int pid, int lfd)
{
return parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, pre_dump_fanotify_entry, NULL);
}
const struct fdtype_ops fanotify_dump_ops = { const struct fdtype_ops fanotify_dump_ops = {
.type = FD_TYPES__FANOTIFY, .type = FD_TYPES__FANOTIFY,
.dump = dump_one_fanotify, .dump = dump_one_fanotify,
.pre_dump = pre_dump_one_fanotify,
}; };
static char *get_mark_path(const char *who, struct file_remap *remap, static char *get_mark_path(const char *who, struct file_remap *remap,
......
...@@ -112,6 +112,7 @@ struct file_desc { ...@@ -112,6 +112,7 @@ struct file_desc {
struct fdtype_ops { struct fdtype_ops {
unsigned int type; unsigned int type;
int (*dump)(int lfd, u32 id, const struct fd_parms *p); int (*dump)(int lfd, u32 id, const struct fd_parms *p);
int (*pre_dump)(int pid, int lfd);
}; };
extern int do_dump_gen_file(struct fd_parms *p, int lfd, extern int do_dump_gen_file(struct fd_parms *p, int lfd,
...@@ -120,6 +121,7 @@ extern int do_dump_gen_file(struct fd_parms *p, int lfd, ...@@ -120,6 +121,7 @@ extern int do_dump_gen_file(struct fd_parms *p, int lfd,
struct parasite_drain_fd; struct parasite_drain_fd;
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
struct parasite_drain_fd *dfds); struct parasite_drain_fd *dfds);
int predump_task_files(int pid);
extern int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops); extern int file_desc_add(struct file_desc *d, u32 id, struct file_desc_ops *ops);
extern struct fdinfo_list_entry *file_master(struct file_desc *d); extern struct fdinfo_list_entry *file_master(struct file_desc *d);
......
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