[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