[CRIU] [PATCH] files: Fail dump if dump_one_file() fails

Andy Tucker agtucker at google.com
Tue Apr 10 22:54:11 MSK 2018


When dumping a process with a large number of open files,
dump_task_files_seized() processes the fds in batches. If
dump_one_file() results in an error, processing of the current batch is
stopped but the next batch (if any) will still be fetched and the error
value is overwritten. The result is a corrupt dump image (the fdinfo
file is missing a bunch of fds) which results in restore failure.

Also close all received fds after an error (previously the skipped ones
were left open).

Signed-off-by: Andy Tucker <agtucker at google.com>
---
 criu/files.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/criu/files.c b/criu/files.c
index 8c83d41f..130a5e8b 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -618,7 +618,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
 		goto err;
 
 	ret = 0; /* Don't fail if nr_fds == 0 */
-	for (off = 0; off < dfds->nr_fds; off += nr_fds) {
+	for (off = 0; ret == 0 && off < dfds->nr_fds; off += nr_fds) {
 		if (nr_fds + off > dfds->nr_fds)
 			nr_fds = dfds->nr_fds - off;
 
@@ -632,7 +632,6 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
 
 			ret = dump_one_file(item->pid, dfds->fds[i + off],
 						lfds[i], opts + i, ctl, &e);
-			close(lfds[i]);
 			if (ret)
 				break;
 
@@ -640,6 +639,9 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item,
 			if (ret)
 				break;
 		}
+
+		for (i = 0; i < nr_fds; i++)
+			close(lfds[i]);
 	}
 
 	pr_info("----------------------------------------\n");
-- 
2.17.0.484.g0c8726318c-goog



More information about the CRIU mailing list