[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/3] libxc/migrationv2: Split {start, end}_of_stream() to make checkpoint variants
This is in preparation for supporting checkpointed streams in migration v2. - For PV guests, the VCPU context is moved to end_of_checkpoint(). - For HVM guests, the HVM context and params are moved to end_of_checkpoint(). For regular migration, this results in a reordering of the tail records, but no semantic change. In addition fix a couple of stylistic issues and adjust some comments. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx> CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Yang Hongyang <yanghy@xxxxxxxxxxxxxx> --- This patch has not tested yet, but is just some code shuffling and should have no observable effect from the guests point of view. --- tools/libxc/xc_sr_common.h | 25 +++++++++++++++------ tools/libxc/xc_sr_save.c | 8 +++++++ tools/libxc/xc_sr_save_x86_hvm.c | 46 ++++++++++++++++++++++++-------------- tools/libxc/xc_sr_save_x86_pv.c | 46 +++++++++++++++++++++++++------------- 4 files changed, 85 insertions(+), 40 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index ef42412..56169ea 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -61,17 +61,28 @@ struct xc_sr_save_ops int (*setup)(struct xc_sr_context *ctx); /** - * Write records which need to be at the start of the stream. This is - * called after the Image and Domain headers are written. (Any records - * which need to be ahead of the memory.) + * Send records which need to be at the start of the stream. This is + * called once, after the Image and Domain headers are written. */ int (*start_of_stream)(struct xc_sr_context *ctx); /** - * Write records which need to be at the end of the stream, following the - * complete memory contents. The caller shall handle writing the END - * record into the stream. (Any records which need to be after the memory - * is complete.) + * Send records which need to be at the start of a checkpoint. This is + * called once, or once per checkpoint in a checkpointed stream, and is + * ahead of memory data. + */ + int (*start_of_checkpoint)(struct xc_sr_context *ctx); + + /** + * Send records which need to be at the end of the checkpoint. This is + * called once, or once per checkpoint in a checkpointed stream, and is + * after the memory data. + */ + int (*end_of_checkpoint)(struct xc_sr_context *ctx); + + /** + * Send records which need to be at the end of the stream. This is called + * once, before the END record is written. */ int (*end_of_stream)(struct xc_sr_context *ctx); diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index 5d9c267..49c65e9 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -662,6 +662,10 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( rc ) goto err; + rc = ctx->save.ops.start_of_checkpoint(ctx); + if ( rc ) + goto err; + if ( ctx->save.live ) rc = send_domain_memory_live(ctx); else @@ -678,6 +682,10 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) goto err; } + rc = ctx->save.ops.end_of_checkpoint(ctx); + if ( rc ) + goto err; + xc_report_progress_single(xch, "End of stream"); rc = ctx->save.ops.end_of_stream(ctx); diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c index 8baa104..4ad1264 100644 --- a/tools/libxc/xc_sr_save_x86_hvm.c +++ b/tools/libxc/xc_sr_save_x86_hvm.c @@ -191,32 +191,42 @@ static int x86_hvm_start_of_stream(struct xc_sr_context *ctx) return 0; } -static int x86_hvm_end_of_stream(struct xc_sr_context *ctx) +static int x86_hvm_start_of_checkpoint(struct xc_sr_context *ctx) +{ + /* no-op */ + return 0; +} + +static int x86_hvm_end_of_checkpoint(struct xc_sr_context *ctx) { int rc; - /* Write the TSC record. */ - rc = write_tsc_info(ctx); + rc = write_hvm_context(ctx); if ( rc ) return rc; -#ifdef XG_LIBXL_HVM_COMPAT - rc = write_toolstack(ctx); + rc = write_hvm_params(ctx); if ( rc ) return rc; -#endif - /* Write the HVM_CONTEXT record. */ - rc = write_hvm_context(ctx); + return 0; +} + +static int x86_hvm_end_of_stream(struct xc_sr_context *ctx) +{ + int rc; + + rc = write_tsc_info(ctx); if ( rc ) return rc; - /* Write HVM_PARAMS record contains applicable HVM params. */ - rc = write_hvm_params(ctx); +#ifdef XG_LIBXL_HVM_COMPAT + rc = write_toolstack(ctx); if ( rc ) return rc; +#endif - return rc; + return 0; } static int x86_hvm_cleanup(struct xc_sr_context *ctx) @@ -237,12 +247,14 @@ static int x86_hvm_cleanup(struct xc_sr_context *ctx) struct xc_sr_save_ops save_ops_x86_hvm = { - .pfn_to_gfn = x86_hvm_pfn_to_gfn, - .normalise_page = x86_hvm_normalise_page, - .setup = x86_hvm_setup, - .start_of_stream = x86_hvm_start_of_stream, - .end_of_stream = x86_hvm_end_of_stream, - .cleanup = x86_hvm_cleanup, + .pfn_to_gfn = x86_hvm_pfn_to_gfn, + .normalise_page = x86_hvm_normalise_page, + .setup = x86_hvm_setup, + .start_of_stream = x86_hvm_start_of_stream, + .start_of_checkpoint = x86_hvm_start_of_checkpoint, + .end_of_checkpoint = x86_hvm_end_of_checkpoint, + .end_of_stream = x86_hvm_end_of_stream, + .cleanup = x86_hvm_cleanup, }; /* diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c index a668221..df54ef3 100644 --- a/tools/libxc/xc_sr_save_x86_pv.c +++ b/tools/libxc/xc_sr_save_x86_pv.c @@ -805,9 +805,6 @@ static int x86_pv_setup(struct xc_sr_context *ctx) return 0; } -/* - * save_ops function. Writes PV header records into the stream. - */ static int x86_pv_start_of_stream(struct xc_sr_context *ctx) { int rc; @@ -816,6 +813,12 @@ static int x86_pv_start_of_stream(struct xc_sr_context *ctx) if ( rc ) return rc; + /* + * Ideally should be able to change during migration. Currently + * corruption will occur if the contents or location of the P2M changes + * during the live migration loop. If one is very lucky, the breakage + * will not be subtle. + */ rc = write_x86_pv_p2m_frames(ctx); if ( rc ) return rc; @@ -823,22 +826,31 @@ static int x86_pv_start_of_stream(struct xc_sr_context *ctx) return 0; } -/* - * save_ops function. Writes tail records information into the stream. - */ -static int x86_pv_end_of_stream(struct xc_sr_context *ctx) +static int x86_pv_start_of_checkpoint(struct xc_sr_context *ctx) +{ + return 0; +} + +static int x86_pv_end_of_checkpoint(struct xc_sr_context *ctx) { int rc; - rc = write_tsc_info(ctx); + rc = write_all_vcpu_information(ctx); if ( rc ) return rc; - rc = write_shared_info(ctx); + return 0; +} + +static int x86_pv_end_of_stream(struct xc_sr_context *ctx) +{ + int rc; + + rc = write_tsc_info(ctx); if ( rc ) return rc; - rc = write_all_vcpu_information(ctx); + rc = write_shared_info(ctx); if ( rc ) return rc; @@ -866,12 +878,14 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx) struct xc_sr_save_ops save_ops_x86_pv = { - .pfn_to_gfn = x86_pv_pfn_to_gfn, - .normalise_page = x86_pv_normalise_page, - .setup = x86_pv_setup, - .start_of_stream = x86_pv_start_of_stream, - .end_of_stream = x86_pv_end_of_stream, - .cleanup = x86_pv_cleanup, + .pfn_to_gfn = x86_pv_pfn_to_gfn, + .normalise_page = x86_pv_normalise_page, + .setup = x86_pv_setup, + .start_of_stream = x86_pv_start_of_stream, + .start_of_checkpoint = x86_pv_start_of_checkpoint, + .end_of_checkpoint = x86_pv_end_of_checkpoint, + .end_of_stream = x86_pv_end_of_stream, + .cleanup = x86_pv_cleanup, }; /* -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |