[CRIU] [PATCH 3/7] files: Pre-dump file descriptors
Pavel Emelyanov
xemul at parallels.com
Thu Jan 30 02:23:55 PST 2014
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: Pavel Emelyanov <xemul at parallels.com>
---
cr-dump.c | 6 ++++++
files.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
fsnotify.c | 22 ++++++++++++++++++++
include/files.h | 2 ++
4 files changed, 94 insertions(+)
diff --git a/cr-dump.c b/cr-dump.c
index c0f29b0..2c77810 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1346,6 +1346,12 @@ static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
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;
ret = parasite_dump_pages_seized(parasite_ctl, &vmas, ¶site_ctl->mem_pp);
diff --git a/files.c b/files.c
index 412e2f8..df0e2f1 100644
--- a/files.c
+++ b/files.c
@@ -411,6 +411,70 @@ err:
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)
{
struct f_owner_ex owner;
diff --git a/fsnotify.c b/fsnotify.c
index 9430919..7464494 100644
--- a/fsnotify.c
+++ b/fsnotify.c
@@ -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);
}
+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 = {
.type = FD_TYPES__INOTIFY,
.dump = dump_one_inotify,
+ .pre_dump = pre_dump_one_inotify,
};
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)
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 = {
.type = FD_TYPES__FANOTIFY,
.dump = dump_one_fanotify,
+ .pre_dump = pre_dump_one_fanotify,
};
static char *get_mark_path(const char *who, struct file_remap *remap,
diff --git a/include/files.h b/include/files.h
index 6d43a71..6a69955 100644
--- a/include/files.h
+++ b/include/files.h
@@ -112,6 +112,7 @@ struct file_desc {
struct fdtype_ops {
unsigned int type;
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,
@@ -120,6 +121,7 @@ extern int do_dump_gen_file(struct fd_parms *p, int lfd,
struct parasite_drain_fd;
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
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 struct fdinfo_list_entry *file_master(struct file_desc *d);
--
1.8.4.2
More information about the CRIU
mailing list