[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