From fcfa58026ca5fd2ec3b0199165ba4185f5a50d0c Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 1 Nov 2013 00:50:48 +0400 Subject: [PATCH] dump: Don't forget to cleanup link remap if needed In case if checkpoint is failed or -R option passed we need to remove link remap files created during dump procedure. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- cr-dump.c | 2 ++ files-reg.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ include/files-reg.h | 3 +++ 3 files changed, 52 insertions(+) diff --git a/cr-dump.c b/cr-dump.c index c63c1b116..39e4555c7 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -1789,6 +1789,7 @@ err: */ if (ret || post_dump_ret || opts.final_state == TASK_ALIVE) { network_unlock(); + delete_link_remaps(); } pstree_switch_state(root_item, (ret || post_dump_ret) ? @@ -1796,6 +1797,7 @@ err: timing_stop(TIME_FROZEN); free_pstree(root_item); free_file_locks(); + free_link_remaps(); close_service_fd(CR_PROC_FD_OFF); diff --git a/files-reg.c b/files-reg.c index 41050efe2..640cb60eb 100644 --- a/files-reg.c +++ b/files-reg.c @@ -40,6 +40,15 @@ static LIST_HEAD(ghost_files); static mutex_t *ghost_file_mutex; +/* + * To rollback link remaps. + */ +struct link_remap_rlb { + struct list_head list; + char *path; +}; +static LIST_HEAD(link_remaps); + /* * This constant is selected without any calculations. Just do not * want to pick up too big files with us in the image. @@ -310,11 +319,31 @@ dump_entry: &rpe, PB_REMAP_FPATH); } +static void __rollback_link_remaps(bool do_unlink) +{ + struct link_remap_rlb *rlb, *tmp; + + if (!opts.link_remap_ok) + return; + + list_for_each_entry_safe(rlb, tmp, &link_remaps, list) { + list_del(&rlb->list); + if (do_unlink) + unlinkat(mntns_root, rlb->path, 0); + xfree(rlb->path); + xfree(rlb); + } +} + +void delete_link_remaps(void) { __rollback_link_remaps(true); } +void free_link_remaps(void) { __rollback_link_remaps(false); } + static int create_link_remap(char *path, int len, int lfd, u32 *idp) { char link_name[PATH_MAX], *tmp; RegFileEntry rfe = REG_FILE_ENTRY__INIT; FownEntry fwn = FOWN_ENTRY__INIT; + struct link_remap_rlb *rlb; if (!opts.link_remap_ok) { pr_err("Can't create link remap for %s. " @@ -353,6 +382,24 @@ static int create_link_remap(char *path, int len, int lfd, u32 *idp) return -1; } + /* + * Remember the name to delete it if needed on error or + * rollback action. Note we don't expect that there will + * be a HUGE number of link remaps, so in a sake of speed + * we keep all data in memory. + */ + rlb = xmalloc(sizeof(*rlb)); + if (rlb) + rlb->path = strdup(link_name); + + if (!rlb || !rlb->path) { + pr_perror("Can't register rollback for %s", path); + xfree(rlb ? rlb->path : NULL); + xfree(rlb); + return -1; + } + list_add(&rlb->list, &link_remaps); + return pb_write_one(fdset_fd(glob_fdset, CR_FD_REG_FILES), &rfe, PB_REG_FILE); } diff --git a/include/files-reg.h b/include/files-reg.h index a93064113..d3bd4f0cd 100644 --- a/include/files-reg.h +++ b/include/files-reg.h @@ -38,4 +38,7 @@ extern void remap_put(struct file_remap *remap); extern struct collect_image_info reg_file_cinfo; extern struct collect_image_info remap_cinfo; +extern void delete_link_remaps(void); +extern void free_link_remaps(void); + #endif /* __CR_FILES_REG_H__ */