|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH Remus v2 08/10] tools/libxc: implement Remus checkpointed save
With Remus, the save flow should be:
live migration->{ periodically save(checkpointed save) }
Signed-off-by: Yang Hongyang <yanghy@xxxxxxxxxxxxxx>
---
tools/libxc/include/xenguest.h | 1 +
tools/libxc/xc_sr_common.h | 6 ++++
tools/libxc/xc_sr_save.c | 74 +++++++++++++++++++++++++++++-------------
tools/libxl/libxl_dom.c | 1 +
4 files changed, 59 insertions(+), 23 deletions(-)
diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 8e39075..7581263 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -30,6 +30,7 @@
#define XCFLAGS_HVM (1 << 2)
#define XCFLAGS_STDVGA (1 << 3)
#define XCFLAGS_CHECKPOINT_COMPRESS (1 << 4)
+#define XCFLAGS_CHECKPOINTED (1 << 5)
#define X86_64_B_SIZE 64
#define X86_32_B_SIZE 32
diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 9567a35..95e0f19 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -172,6 +172,12 @@ struct xc_sr_context
/* Further debugging information in the stream. */
bool debug;
+ /*
+ * Whether it is a checkpointed save, we'll enter checkpointed
+ * save after live migration under Remus.
+ */
+ bool checkpointed;
+
/* Parameters for tweaking live migration. */
unsigned max_iterations;
unsigned dirty_threshold;
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 7efffe6..7cf45ed 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -466,6 +466,9 @@ static int send_domain_memory_live(struct xc_sr_context
*ctx)
DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
(&ctx->save.dirty_bitmap_hbuf));
+ if ( !ctx->save.live )
+ goto last_iter;
+
rc = enable_logdirty(ctx);
if ( rc )
goto out;
@@ -504,6 +507,7 @@ static int send_domain_memory_live(struct xc_sr_context
*ctx)
goto out;
}
+ last_iter:
rc = suspend_domain(ctx);
if ( rc )
goto out;
@@ -664,35 +668,52 @@ static int save(struct xc_sr_context *ctx, uint16_t
guest_type)
if ( rc )
goto err;
- rc = ctx->save.ops.start_of_stream(ctx);
- if ( rc )
- goto err;
+ do {
+ rc = ctx->save.ops.start_of_stream(ctx);
+ if ( rc )
+ goto err;
- if ( ctx->save.live )
- rc = send_domain_memory_live(ctx);
- else
- rc = send_domain_memory_nonlive(ctx);
+ if ( ctx->save.live || ctx->save.checkpointed )
+ rc = send_domain_memory_live(ctx);
+ else
+ rc = send_domain_memory_nonlive(ctx);
- if ( rc )
- goto err;
+ if ( rc )
+ goto err;
- if ( !ctx->dominfo.shutdown ||
- (ctx->dominfo.shutdown_reason != SHUTDOWN_suspend) )
- {
- ERROR("Domain has not been suspended");
- rc = -1;
- goto err;
- }
+ if ( !ctx->dominfo.shutdown ||
+ (ctx->dominfo.shutdown_reason != SHUTDOWN_suspend) )
+ {
+ ERROR("Domain has not been suspended");
+ rc = -1;
+ goto err;
+ }
- xc_report_progress_single(xch, "End of stream");
+ xc_report_progress_single(xch, "End of stream");
- rc = ctx->save.ops.end_of_stream(ctx);
- if ( rc )
- goto err;
+ rc = ctx->save.ops.end_of_stream(ctx);
+ if ( rc )
+ goto err;
- rc = write_end_record(ctx);
- if ( rc )
- goto err;
+ rc = write_end_record(ctx);
+ if ( rc )
+ goto err;
+
+ if ( ctx->save.live ) {
+ /* End of live migration */
+ ctx->save.live = false;
+ }
+
+ if ( ctx->save.checkpointed ) {
+ ctx->save.callbacks->postcopy(ctx->save.callbacks->data);
+
+ rc = ctx->save.callbacks->checkpoint(ctx->save.callbacks->data);
+ if ( rc > 0 )
+ IPRINTF("Checkpointed save");
+ else
+ ctx->save.checkpointed = false;
+ }
+ } while ( ctx->save.checkpointed );
xc_report_progress_single(xch, "Complete");
goto done;
@@ -720,6 +741,13 @@ int xc_domain_save2(xc_interface *xch, int io_fd, uint32_t
dom,
ctx.save.callbacks = callbacks;
ctx.save.live = !!(flags & XCFLAGS_LIVE);
ctx.save.debug = !!(flags & XCFLAGS_DEBUG);
+ ctx.save.checkpointed = !!(flags & XCFLAGS_CHECKPOINTED);
+
+ if ( ctx.save.checkpointed ) {
+ /* This is a checkpointed save, we need these callbacks */
+ assert(ctx.save.callbacks->postcopy);
+ assert(ctx.save.callbacks->checkpoint);
+ }
/*
* TODO: Find some time to better tweak the live migration algorithm.
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index f408646..a0c9850 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -2003,6 +2003,7 @@ void libxl__domain_suspend(libxl__egc *egc,
libxl__domain_suspend_state *dss)
if (r_info != NULL) {
dss->interval = r_info->interval;
+ dss->xcflags |= XCFLAGS_CHECKPOINTED;
if (libxl_defbool_val(r_info->compression))
dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS;
}
--
1.9.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |