[CRIU] [PATCH] files: remove ghost directories when a restore failed

Andrey Vagin avagin at openvz.org
Tue Mar 1 14:07:14 PST 2016


From: Andrew Vagin <avagin at virtuozzo.com>

The current code doesn't work becuase ghost files and directories
have different formats.

ghost directories are created from a root task, but they are
cleaned up from the criu process, so reg_file_info is allocated
from shared memory and is_dir is added into it.

https://github.com/xemul/criu/issues/120
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 criu/files-reg.c         | 24 ++++++++++++------------
 criu/include/files-reg.h |  1 +
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/criu/files-reg.c b/criu/files-reg.c
index debc348..77238b6 100644
--- a/criu/files-reg.c
+++ b/criu/files-reg.c
@@ -132,6 +132,8 @@ static int mkreg_ghost(char *path, u32 mode, struct ghost_file *gf, struct cr_im
 		return -1;
 
 	ret = copy_file(img_raw_fd(img), gfd, 0);
+	if (ret < 0)
+		unlink(path);
 	close(gfd);
 
 	return ret;
@@ -295,6 +297,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
 	gf->remap.owner = gfe->uid;
 	list_add_tail(&gf->list, &ghost_files);
 gf_found:
+	rfi->is_dir = gf->remap.is_dir;
 	rfi->remap = &gf->remap;
 	return 0;
 
@@ -493,19 +496,15 @@ static void try_clean_ghost(struct remap_info *ri)
 	if (ret < 0)
 		return;
 
-	ghost_path(path + ret, sizeof(path) - 1, ri->rfi, ri->rfe);
-	if (!unlink(path)) {
-		pr_info(" `- X [%s] ghost\n", path);
+	if (ri->rfi->remap == NULL)
 		return;
-	}
-
-	/*
-	 * We can also find out the ghost type by stat()-ing
-	 * it or by reading the ghost image, but this way
-	 * is the fastest one.
-	 */
-
-	if ((errno == EISDIR)) {
+	if (!ri->rfi->is_dir) {
+		ghost_path(path + ret, sizeof(path) - 1, ri->rfi, ri->rfe);
+		if (!unlink(path)) {
+			pr_info(" `- X [%s] ghost\n", path);
+			return;
+		}
+	} else {
 		strncpy(path + ret, ri->rfi->path, sizeof(path) - 1);
 		if (!rmdir(path)) {
 			pr_info(" `- Xd [%s] ghost\n", path);
@@ -1644,6 +1643,7 @@ static struct collect_image_info reg_file_cinfo = {
 	.pb_type = PB_REG_FILE,
 	.priv_size = sizeof(struct reg_file_info),
 	.collect = collect_one_regfile,
+	.flags = COLLECT_SHARED,
 };
 
 int prepare_shared_reg_files(void)
diff --git a/criu/include/files-reg.h b/criu/include/files-reg.h
index 1cbefb0..50e1b30 100644
--- a/criu/include/files-reg.h
+++ b/criu/include/files-reg.h
@@ -24,6 +24,7 @@ struct reg_file_info {
 	RegFileEntry		*rfe;
 	struct file_remap	*remap;
 	bool			size_checked;
+	bool			is_dir;
 	char			*path;
 };
 
-- 
2.5.0



More information about the CRIU mailing list