[CRIU] [PATCH 1/2] dump: Rollback in case if -R option passed
Andrew Vagin
avagin at parallels.com
Thu Oct 31 13:34:33 PDT 2013
On Thu, Oct 31, 2013 at 10:04:53PM +0400, Cyrill Gorcunov wrote:
>
> It's been found that if -R (leave task running after checkpoint)
> option passed we don't unlock network, nether we clean service
> files (such as link remaps).
>
> After a long discussion we choose the following path: if -R option
> is passed, it means a user is quite confident in what he is doing
> and consistency of the resources (file system) is achieved by
> a user himself with help of post-dump script. Also a user knows
> that the network will be unlocked and accept such case.
>
> So here we check of -R being passed in command line and once
> checkpoint complete we unlock the network and cleanup remap
> links if they were created durig checkpoint.
>
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
> cr-dump.c | 27 +++++++++++++++++++++++----
> files-reg.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> include/files-reg.h | 3 +++
> 3 files changed, 73 insertions(+), 4 deletions(-)
>
> diff --git a/cr-dump.c b/cr-dump.c
> index 1106e31..39e4555 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -1767,18 +1767,37 @@ err:
> }
>
> /*
> - * If we've failed to do anything -- unlock all TCP sockets
> - * so that the connections can go on. But if we succeeded --
> - * don't, just close them silently.
> + * Dump is complete at this stage. To choose what
> + * to do next we need to consider the following
> + * scenarios
> + *
> + * - error happened during checkpoint: just clean up
> + * everything and continue execution of the dumpee;
> + *
> + * - dump successed but post-dump script returned
> + * some ret code: same as in previous scenario --
> + * just clean up everything and continue execution,
> + * we will return script ret code back to criu caller
> + * and it's up to a caller what to do with running instance
> + * of the dumpee -- either kill it, or continue running;
> + *
> + * - dump successed but -R option passed, pointing that
> + * we're asked to continue execution of the dumpee. It's
> + * assumed that a user will use post-dump script to keep
> + * consistency of the FS and other resources, we simply
> + * start rollback procedure and cleanup everyhting.
> */
> - if (ret || post_dump_ret)
> + if (ret || post_dump_ret || opts.final_state == TASK_ALIVE) {
> network_unlock();
> + delete_link_remaps();
delete_link_remaps must be in another patch.
> + }
> pstree_switch_state(root_item,
> (ret || post_dump_ret) ?
> TASK_ALIVE : opts.final_state);
> 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 41050ef..4aa6c34 100644
> --- a/files-reg.c
> +++ b/files-reg.c
> @@ -41,6 +41,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(int 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(1); }
> +void free_link_remaps(void) { __rollback_link_remaps(0); }
> +
> 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 a930641..d3bd4f0 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__ */
More information about the CRIU
mailing list