From 9eb9abb62f96164e96a24ef607d22193dbdeb593 Mon Sep 17 00:00:00 2001 From: Andy Tucker Date: Tue, 10 Apr 2018 12:54:11 -0700 Subject: [PATCH] files: Fail dump if dump_one_file() fails 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 Reviewed-by: Dmitry Safonov <0x7f454c46@gmail.com> Signed-off-by: Andrei Vagin --- criu/files.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/criu/files.c b/criu/files.c index ac0d1715e..4585395a6 100644 --- a/criu/files.c +++ b/criu/files.c @@ -606,7 +606,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; @@ -620,7 +620,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; @@ -628,6 +627,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");