[CRIU] [PATCH 2/4] files: resort code about dumping file descriptors
Andrey Vagin
avagin at openvz.org
Thu Mar 31 22:53:26 PDT 2016
From: Andrew Vagin <avagin at virtuozzo.com>
We are going to dump file descriptors by portions. In this patch,
we move collect_fds into dump_task_files_seized.
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
criu/cr-dump.c | 54 ++-------------------------------
criu/files.c | 85 ++++++++++++++++++++++++++++++++++++++++++----------
criu/include/files.h | 3 +-
3 files changed, 73 insertions(+), 69 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index aaa09e3..4a3db27 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -184,40 +184,6 @@ static int dump_sched_info(int pid, ThreadCoreEntry *tc)
struct cr_imgset *glob_imgset;
-static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds)
-{
- struct dirent *de;
- DIR *fd_dir;
- int n;
-
- pr_info("\n");
- pr_info("Collecting fds (pid: %d)\n", pid);
- pr_info("----------------------------------------\n");
-
- fd_dir = opendir_proc(pid, "fd");
- if (!fd_dir)
- return -1;
-
- n = 0;
- while ((de = readdir(fd_dir))) {
- if (dir_dots(de))
- continue;
-
- if (n > PARASITE_MAX_FDS - 1)
- return -ENOMEM;
-
- dfds->fds[n++] = atoi(de->d_name);
- }
-
- dfds->nr_fds = n;
- pr_info("Found %d file descriptors\n", n);
- pr_info("----------------------------------------\n");
-
- closedir(fd_dir);
-
- return 0;
-}
-
static int fill_fd_params_special(int fd, struct fd_parms *p)
{
*p = FD_PARMS_INIT;
@@ -1176,7 +1142,6 @@ static int dump_one_task(struct pstree_item *item)
int ret, exit_code = -1;
struct parasite_dump_misc misc;
struct cr_imgset *cr_imgset = NULL;
- struct parasite_drain_fd *dfds = NULL;
struct proc_posix_timers_stat proc_args;
INIT_LIST_HEAD(&vmas.h);
@@ -1203,20 +1168,6 @@ static int dump_one_task(struct pstree_item *item)
goto err;
}
- if (!shared_fdtable(item)) {
- dfds = xmalloc(sizeof(*dfds));
- if (!dfds)
- goto err;
-
- ret = collect_fds(pid, dfds);
- if (ret) {
- pr_err("Collect fds (pid: %d) failed with %d\n", pid, ret);
- goto err;
- }
-
- parasite_ensure_args_size(drain_fds_size(dfds));
- }
-
ret = parse_posix_timers(pid, &proc_args);
if (ret < 0) {
pr_err("Can't read posix timers file (pid: %d)\n", pid);
@@ -1298,8 +1249,8 @@ static int dump_one_task(struct pstree_item *item)
goto err_cure;
}
- if (dfds) {
- ret = dump_task_files_seized(parasite_ctl, item, dfds);
+ if (!shared_fdtable(item)) {
+ ret = dump_task_files_seized(parasite_ctl, item);
if (ret) {
pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
goto err_cure;
@@ -1369,7 +1320,6 @@ static int dump_one_task(struct pstree_item *item)
err:
close_pid_proc();
free_mappings(&vmas);
- xfree(dfds);
return exit_code;
err_cure:
diff --git a/criu/files.c b/criu/files.c
index a30dd06..eb5f3d9 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -459,33 +459,89 @@ static int dump_one_file(struct parasite_ctl *ctl, int fd, int lfd, struct fd_op
return dump_unsupp_fd(&p, lfd, img, "unknown", NULL);
}
-int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
- struct parasite_drain_fd *dfds)
+static int collect_fds(pid_t pid, struct parasite_drain_fd *dfds, int *skip_fds, int skip_n)
{
- int *lfds;
- struct cr_img *img;
- struct fd_opts *opts;
+ struct dirent *de;
+ DIR *fd_dir;
+ int n;
+
+ pr_info("\n");
+ pr_info("Collecting fds (pid: %d)\n", pid);
+ pr_info("----------------------------------------\n");
+
+ fd_dir = opendir_proc(pid, "fd");
+ if (!fd_dir)
+ return -1;
+
+ n = 0;
+ while ((de = readdir(fd_dir))) {
+ int fd, i;
+
+ if (dir_dots(de))
+ continue;
+
+ if (n > PARASITE_MAX_FDS - 1)
+ return -ENOMEM;
+
+ fd = atoi(de->d_name);
+ for (i = 0; i < skip_n; i++)
+ if (skip_fds[i] == fd)
+ break;
+ if (i < skip_n)
+ continue;
+
+ dfds->fds[n++] = fd;
+ }
+
+ dfds->nr_fds = n;
+ pr_info("Found %d file descriptors\n", n);
+ pr_info("----------------------------------------\n");
+
+ closedir(fd_dir);
+
+ return 0;
+}
+
+int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item)
+{
+ struct parasite_drain_fd *dfds = NULL;
+ struct fd_opts *opts = NULL;
+ struct cr_img *img = NULL;
+ pid_t pid = ctl->pid.real;
+ int *lfds = NULL;
int i, ret = -1;
pr_info("\n");
pr_info("Dumping opened files (pid: %d)\n", ctl->pid.real);
pr_info("----------------------------------------\n");
+ dfds = xmalloc(sizeof(*dfds));
+ if (!dfds)
+ goto err;
+
+ img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
+ if (!img)
+ goto err;
+
+ ret = collect_fds(pid, dfds, (int [2]) {ctl->ptsock, ctl->plogfd} , 2);
+ if (ret) {
+ pr_err("Collect fds (pid: %d) failed with %d\n", pid, ret);
+ goto err;
+ }
+
+ parasite_ensure_args_size(drain_fds_size(dfds));
+
lfds = xmalloc(dfds->nr_fds * sizeof(int));
if (!lfds)
goto err;
opts = xmalloc(dfds->nr_fds * sizeof(struct fd_opts));
if (!opts)
- goto err1;
+ goto err;
ret = parasite_drain_fds_seized(ctl, dfds, lfds, opts);
if (ret)
- goto err2;
-
- img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
- if (!img)
- goto err2;
+ goto err;
for (i = 0; i < dfds->nr_fds; i++) {
ret = dump_one_file(ctl, dfds->fds[i], lfds[i], opts + i, img);
@@ -494,14 +550,13 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
break;
}
- close_image(img);
pr_info("----------------------------------------\n");
-err2:
+err:
+ if (img)
+ close_image(img);
xfree(opts);
-err1:
xfree(lfds);
-err:
return ret;
}
diff --git a/criu/include/files.h b/criu/include/files.h
index 363437b..0ef6f70 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -165,8 +165,7 @@ extern int do_dump_gen_file(struct fd_parms *p, int lfd,
const struct fdtype_ops *ops,
struct cr_img *);
struct parasite_drain_fd;
-int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
- struct parasite_drain_fd *dfds);
+int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item);
int predump_task_files(int pid);
extern void file_desc_init(struct file_desc *d, u32 id, struct file_desc_ops *ops);
--
2.5.0
More information about the CRIU
mailing list