Commit fcfa5802 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

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: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7fe62208
......@@ -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);
......
......@@ -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);
}
......
......@@ -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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment