All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH Remus v3 0/3] Remus support for Migration-v2
@ 2015-05-13  8:34 Yang Hongyang
  2015-05-13  8:34 ` [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save Yang Hongyang
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Yang Hongyang @ 2015-05-13  8:34 UTC (permalink / raw)
  To: xen-devel
  Cc: wei.liu2, ian.campbell, wency, andrew.cooper3, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram, ian.jackson

This patchset implement the Remus support for Migration v2 but without
memory compressing.

Git tree available at:
    https://github.com/macrosheep/xen/tree/Remus-newmig-v3

This patchset is based on
    [PATCH v5 00/14] Misc patches to aid migration v2 Remus support
    https://github.com/macrosheep/xen/tree/misc-remus-v5

Yang Hongyang (3):
  libxc/save: implement Remus checkpointed save
  libxc/restore: add checkpointed flag to the restore context
  libxc/restore: implement Remus checkpointed restore

 tools/libxc/xc_sr_common.h  |  16 ++++++
 tools/libxc/xc_sr_restore.c | 125 +++++++++++++++++++++++++++++++++++++++-----
 tools/libxc/xc_sr_save.c    |  73 +++++++++++++++++++-------
 3 files changed, 183 insertions(+), 31 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save
  2015-05-13  8:34 [PATCH Remus v3 0/3] Remus support for Migration-v2 Yang Hongyang
@ 2015-05-13  8:34 ` Yang Hongyang
  2015-05-13 15:14   ` Andrew Cooper
  2015-05-13  8:35 ` [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context Yang Hongyang
  2015-05-13  8:35 ` [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore Yang Hongyang
  2 siblings, 1 reply; 13+ messages in thread
From: Yang Hongyang @ 2015-05-13  8:34 UTC (permalink / raw)
  To: xen-devel
  Cc: wei.liu2, ian.campbell, wency, andrew.cooper3, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram, ian.jackson

With Remus, the save flow should be:
live migration->{ periodically save(checkpointed save) }

Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_sr_save.c | 73 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 54 insertions(+), 19 deletions(-)

diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 1d0a46d..3890c4d 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -57,6 +57,16 @@ static int write_end_record(struct xc_sr_context *ctx)
 }
 
 /*
+ * Writes an CHECKPOINT record into the stream.
+ */
+static int write_checkpoint_record(struct xc_sr_context *ctx)
+{
+    struct xc_sr_record checkpoint = { REC_TYPE_CHECKPOINT, 0, NULL };
+
+    return write_record(ctx, &checkpoint);
+}
+
+/*
  * Writes a batch of memory as a PAGE_DATA record into the stream.  The batch
  * is constructed in ctx->save.batch_pfns.
  *
@@ -467,6 +477,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;
@@ -505,6 +518,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx)
             goto out;
     }
 
+ last_iter:
     rc = suspend_domain(ctx);
     if ( rc )
         goto out;
@@ -667,29 +681,50 @@ 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;
+    do {
+        rc = ctx->save.ops.start_of_checkpoint(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;
+        }
 
-    rc = ctx->save.ops.end_of_checkpoint(ctx);
-    if ( rc )
-        goto err;
+        rc = ctx->save.ops.end_of_checkpoint(ctx);
+        if ( rc )
+            goto err;
+
+        if ( ctx->save.checkpointed ) {
+            if ( ctx->save.live ) {
+                /* End of live migration, we are sending checkpointed stream */
+                ctx->save.live = false;
+            }
+
+            rc = write_checkpoint_record(ctx);
+            if ( rc )
+                goto err;
+
+            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, "End of stream");
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context
  2015-05-13  8:34 [PATCH Remus v3 0/3] Remus support for Migration-v2 Yang Hongyang
  2015-05-13  8:34 ` [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save Yang Hongyang
@ 2015-05-13  8:35 ` Yang Hongyang
  2015-05-13 15:15   ` Andrew Cooper
  2015-05-13  8:35 ` [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore Yang Hongyang
  2 siblings, 1 reply; 13+ messages in thread
From: Yang Hongyang @ 2015-05-13  8:35 UTC (permalink / raw)
  To: xen-devel
  Cc: wei.liu2, ian.campbell, wency, andrew.cooper3, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram, ian.jackson

add checkpointed flag to the restore context.

Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libxc/xc_sr_common.h  | 3 +++
 tools/libxc/xc_sr_restore.c | 1 +
 2 files changed, 4 insertions(+)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 0ba9728..f8121e7 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -205,6 +205,9 @@ struct xc_sr_context
             uint32_t guest_type;
             uint32_t guest_page_size;
 
+            /* Plain VM, or checkpoints over time. */
+            bool checkpointed;
+
             /*
              * Xenstore and Console parameters.
              * INPUT:  evtchn & domid
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 8022c3d..0e512ec 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -604,6 +604,7 @@ int xc_domain_restore2(xc_interface *xch, int io_fd, uint32_t dom,
     ctx.restore.console_domid = console_domid;
     ctx.restore.xenstore_evtchn = store_evtchn;
     ctx.restore.xenstore_domid = store_domid;
+    ctx.restore.checkpointed = checkpointed_stream;
     ctx.restore.callbacks = callbacks;
 
     IPRINTF("In experimental %s", __func__);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore
  2015-05-13  8:34 [PATCH Remus v3 0/3] Remus support for Migration-v2 Yang Hongyang
  2015-05-13  8:34 ` [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save Yang Hongyang
  2015-05-13  8:35 ` [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context Yang Hongyang
@ 2015-05-13  8:35 ` Yang Hongyang
  2015-05-13 16:16   ` Andrew Cooper
  2 siblings, 1 reply; 13+ messages in thread
From: Yang Hongyang @ 2015-05-13  8:35 UTC (permalink / raw)
  To: xen-devel
  Cc: wei.liu2, ian.campbell, wency, andrew.cooper3, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram, ian.jackson

With Remus, the restore flow should be:
the first full migration stream -> { periodically restore stream }

Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/xc_sr_common.h  |  13 +++++
 tools/libxc/xc_sr_restore.c | 124 +++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 125 insertions(+), 12 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index f8121e7..3740b89 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -208,6 +208,19 @@ struct xc_sr_context
             /* Plain VM, or checkpoints over time. */
             bool checkpointed;
 
+            /* Currently buffering records between a checkpoint */
+            bool buffer_all_records;
+
+/*
+ * With Remus, we buffer the records sent by primary at checkpoint,
+ * in case the primary will fail, we can recover from the last
+ * checkpoint state.
+ * This should be enough because primary only send dirty pages at
+ * checkpoint.
+ */
+#define MAX_BUF_RECORDS 1024
+            struct xc_sr_record *buffered_records[MAX_BUF_RECORDS];
+
             /*
              * Xenstore and Console parameters.
              * INPUT:  evtchn & domid
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 0e512ec..85534a8 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -468,10 +468,83 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
     return rc;
 }
 
+static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
+static int handle_checkpoint(struct xc_sr_context *ctx)
+{
+    xc_interface *xch = ctx->xch;
+    int rc = 0, i;
+    struct xc_sr_record *rec;
+
+    if ( !ctx->restore.checkpointed )
+    {
+        ERROR("Found checkpoint in non-checkpointed stream");
+        rc = -1;
+        goto err;
+    }
+
+    if ( ctx->restore.buffer_all_records )
+    {
+        IPRINTF("All records buffered");
+
+        /*
+         * We need to set buffer_all_records to false in
+         * order to process records instead of buffer records.
+         * buffer_all_records should be set back to true after
+         * we successfully processed all records.
+         */
+        ctx->restore.buffer_all_records = false;
+        i = 0;
+        rec = ctx->restore.buffered_records[i++];
+        while (rec)
+        {
+            rc = process_record(ctx, rec);
+            free(rec);
+            ctx->restore.buffered_records[i-1] = NULL;
+            if ( rc )
+                goto err;
+
+            rec = ctx->restore.buffered_records[i++];
+        }
+        IPRINTF("All records processed");
+        ctx->restore.buffer_all_records = true;
+    }
+    else
+        ctx->restore.buffer_all_records = true;
+
+ err:
+    return rc;
+}
+
 static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
 {
     xc_interface *xch = ctx->xch;
-    int rc = 0;
+    int rc = 0, i;
+    struct xc_sr_record *buf_rec;
+
+    if ( ctx->restore.buffer_all_records &&
+         rec->type != REC_TYPE_END &&
+         rec->type != REC_TYPE_CHECKPOINT )
+    {
+        buf_rec = malloc(sizeof(struct xc_sr_record));
+        if (!buf_rec)
+        {
+            ERROR("Unable to allocate memory for record");
+            return -1;
+        }
+        memcpy(buf_rec, rec, sizeof(struct xc_sr_record));
+
+        for ( i = 0; i < MAX_BUF_RECORDS; i++ )
+            if ( !ctx->restore.buffered_records[i] )
+                break;
+
+        if ( i >= MAX_BUF_RECORDS )
+        {
+            ERROR("There are too many records within a checkpoint");
+            return -1;
+        }
+        ctx->restore.buffered_records[i] = buf_rec;
+        return 0;
+    }
 
     switch ( rec->type )
     {
@@ -487,6 +560,10 @@ static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
         ctx->restore.verify = true;
         break;
 
+    case REC_TYPE_CHECKPOINT:
+        rc = handle_checkpoint(ctx);
+        break;
+
     default:
         rc = ctx->restore.ops.process_record(ctx, rec);
         break;
@@ -520,7 +597,7 @@ static int restore(struct xc_sr_context *ctx)
 {
     xc_interface *xch = ctx->xch;
     struct xc_sr_record rec;
-    int rc, saved_rc = 0, saved_errno = 0;
+    int rc, saved_rc = 0, saved_errno = 0, i;
 
     IPRINTF("Restoring domain");
 
@@ -541,7 +618,27 @@ static int restore(struct xc_sr_context *ctx)
     {
         rc = read_record(ctx, &rec);
         if ( rc )
-            goto err;
+        {
+            if ( ctx->restore.buffer_all_records )
+                goto err_buf;
+            else
+                goto err;
+        }
+
+#ifdef XG_LIBXL_HVM_COMPAT
+        if ( ctx->dominfo.hvm &&
+             (rec.type == REC_TYPE_END || rec.type == REC_TYPE_CHECKPOINT) )
+        {
+            rc = read_qemu(ctx);
+            if ( rc )
+            {
+                if ( ctx->restore.buffer_all_records )
+                    goto err_buf;
+                else
+                    goto err;
+            }
+        }
+#endif
 
         rc = process_record(ctx, &rec);
         if ( rc )
@@ -549,15 +646,11 @@ static int restore(struct xc_sr_context *ctx)
 
     } while ( rec.type != REC_TYPE_END );
 
-#ifdef XG_LIBXL_HVM_COMPAT
-    if ( ctx->dominfo.hvm )
-    {
-        rc = read_qemu(ctx);
-        if ( rc )
-            goto err;
-    }
-#endif
-
+ err_buf:
+    /*
+     * With Remus, if we reach here, there must be some error on primary,
+     * failover from the last checkpoint state.
+     */
     rc = ctx->restore.ops.stream_complete(ctx);
     if ( rc )
         goto err;
@@ -571,6 +664,13 @@ static int restore(struct xc_sr_context *ctx)
     PERROR("Restore failed");
 
  done:
+    for ( i = 0; i < MAX_BUF_RECORDS; i++)
+    {
+        if ( ctx->restore.buffered_records[i] ) {
+            free(ctx->restore.buffered_records[i]->data);
+            free(ctx->restore.buffered_records[i]);
+        }
+    }
     free(ctx->restore.populated_pfns);
     rc = ctx->restore.ops.cleanup(ctx);
     if ( rc )
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save
  2015-05-13  8:34 ` [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save Yang Hongyang
@ 2015-05-13 15:14   ` Andrew Cooper
  2015-05-14  1:08     ` Yang Hongyang
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Cooper @ 2015-05-13 15:14 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, ian.jackson, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram

On 13/05/15 09:34, Yang Hongyang wrote:
> With Remus, the save flow should be:
> live migration->{ periodically save(checkpointed save) }
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> CC: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  tools/libxc/xc_sr_save.c | 73 +++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 54 insertions(+), 19 deletions(-)
>
> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
> index 1d0a46d..3890c4d 100644
> --- a/tools/libxc/xc_sr_save.c
> +++ b/tools/libxc/xc_sr_save.c
> @@ -57,6 +57,16 @@ static int write_end_record(struct xc_sr_context *ctx)
>  }
>  
>  /*
> + * Writes an CHECKPOINT record into the stream.
> + */
> +static int write_checkpoint_record(struct xc_sr_context *ctx)
> +{
> +    struct xc_sr_record checkpoint = { REC_TYPE_CHECKPOINT, 0, NULL };
> +
> +    return write_record(ctx, &checkpoint);
> +}
> +
> +/*
>   * Writes a batch of memory as a PAGE_DATA record into the stream.  The batch
>   * is constructed in ctx->save.batch_pfns.
>   *
> @@ -467,6 +477,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;
> +

I really want to avoid this code getting into the same spiders web as it
used to be with goto, but I cannot suggest a better alternative.

However, please leave a comment explaining that subsequent checkpointed
loop skip the live part and pause straight away.

>      rc = enable_logdirty(ctx);
>      if ( rc )
>          goto out;
> @@ -505,6 +518,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx)
>              goto out;
>      }
>  
> + last_iter:
>      rc = suspend_domain(ctx);
>      if ( rc )
>          goto out;
> @@ -667,29 +681,50 @@ 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;
> +    do {
> +        rc = ctx->save.ops.start_of_checkpoint(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;
> +        }
>  
> -    rc = ctx->save.ops.end_of_checkpoint(ctx);
> -    if ( rc )
> -        goto err;
> +        rc = ctx->save.ops.end_of_checkpoint(ctx);
> +        if ( rc )
> +            goto err;
> +
> +        if ( ctx->save.checkpointed ) {
> +            if ( ctx->save.live ) {

Coding style.  libxc is admittedly inconsistent, but follows hypervisor
style, so { on the next line.

> +                /* End of live migration, we are sending checkpointed stream */
> +                ctx->save.live = false;
> +            }
> +
> +            rc = write_checkpoint_record(ctx);
> +            if ( rc )
> +                goto err;
> +
> +            ctx->save.callbacks->postcopy(ctx->save.callbacks->data);
> +
> +            rc = ctx->save.callbacks->checkpoint(ctx->save.callbacks->data);
> +            if ( rc > 0 )
> +                IPRINTF("Checkpointed save");

This should probably be progress information , so
xc_report_progress_single()

Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>

(I think this code is a bit of an improvement over xc_domain_save.c)

> +            else
> +                ctx->save.checkpointed = false;
> +        }
> +    } while ( ctx->save.checkpointed );
>  
>      xc_report_progress_single(xch, "End of stream");
>  

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context
  2015-05-13  8:35 ` [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context Yang Hongyang
@ 2015-05-13 15:15   ` Andrew Cooper
  2015-05-14  1:09     ` Yang Hongyang
  0 siblings, 1 reply; 13+ messages in thread
From: Andrew Cooper @ 2015-05-13 15:15 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, ian.jackson, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram

On 13/05/15 09:35, Yang Hongyang wrote:
> add checkpointed flag to the restore context.
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> CC: Andrew Cooper <andrew.cooper3@citrix.com>

This appears unused, given the new restore code.

~Andrew

> ---
>  tools/libxc/xc_sr_common.h  | 3 +++
>  tools/libxc/xc_sr_restore.c | 1 +
>  2 files changed, 4 insertions(+)
>
> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
> index 0ba9728..f8121e7 100644
> --- a/tools/libxc/xc_sr_common.h
> +++ b/tools/libxc/xc_sr_common.h
> @@ -205,6 +205,9 @@ struct xc_sr_context
>              uint32_t guest_type;
>              uint32_t guest_page_size;
>  
> +            /* Plain VM, or checkpoints over time. */
> +            bool checkpointed;
> +
>              /*
>               * Xenstore and Console parameters.
>               * INPUT:  evtchn & domid
> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
> index 8022c3d..0e512ec 100644
> --- a/tools/libxc/xc_sr_restore.c
> +++ b/tools/libxc/xc_sr_restore.c
> @@ -604,6 +604,7 @@ int xc_domain_restore2(xc_interface *xch, int io_fd, uint32_t dom,
>      ctx.restore.console_domid = console_domid;
>      ctx.restore.xenstore_evtchn = store_evtchn;
>      ctx.restore.xenstore_domid = store_domid;
> +    ctx.restore.checkpointed = checkpointed_stream;
>      ctx.restore.callbacks = callbacks;
>  
>      IPRINTF("In experimental %s", __func__);

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore
  2015-05-13  8:35 ` [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore Yang Hongyang
@ 2015-05-13 16:16   ` Andrew Cooper
  2015-05-13 16:38     ` Andrew Cooper
  2015-05-14  5:42     ` Yang Hongyang
  0 siblings, 2 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-05-13 16:16 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, guijianfeng, yunhong.jiang,
	eddie.dong, rshriram, ian.jackson

On 13/05/15 09:35, Yang Hongyang wrote:
> With Remus, the restore flow should be:
> the first full migration stream -> { periodically restore stream }
>
> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/xc_sr_common.h  |  13 +++++
>  tools/libxc/xc_sr_restore.c | 124 +++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 125 insertions(+), 12 deletions(-)
>
> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
> index f8121e7..3740b89 100644
> --- a/tools/libxc/xc_sr_common.h
> +++ b/tools/libxc/xc_sr_common.h
> @@ -208,6 +208,19 @@ struct xc_sr_context
>              /* Plain VM, or checkpoints over time. */
>              bool checkpointed;
>  
> +            /* Currently buffering records between a checkpoint */
> +            bool buffer_all_records;
> +
> +/*
> + * With Remus, we buffer the records sent by primary at checkpoint,

"sent by the primary"

> + * in case the primary will fail, we can recover from the last
> + * checkpoint state.
> + * This should be enough because primary only send dirty pages at
> + * checkpoint.
> + */
> +#define MAX_BUF_RECORDS 1024

As a general point, it occurs to me that this might be better as a
linked list, rather than having a hard limit.  A burst of activity on
the primary could potentially hit this limit

> +            struct xc_sr_record *buffered_records[MAX_BUF_RECORDS];

Your data handling will be much more simple if this were struct
xc_sr_record *buffered_records; and you do a one-time allocation of
MAX_BUF_RECORDS * sizeof(struct xc_sr_record), although it will require
an index integer as well.

It would probably be best to factor out setup() and clean() just like
you did for the save side.

> +
>              /*
>               * Xenstore and Console parameters.
>               * INPUT:  evtchn & domid
> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
> index 0e512ec..85534a8 100644
> --- a/tools/libxc/xc_sr_restore.c
> +++ b/tools/libxc/xc_sr_restore.c
> @@ -468,10 +468,83 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
>      return rc;
>  }
>  
> +static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
> +static int handle_checkpoint(struct xc_sr_context *ctx)
> +{
> +    xc_interface *xch = ctx->xch;
> +    int rc = 0, i;

Always an unsigned i for populated_pfnsindexing an array please.

> +    struct xc_sr_record *rec;
> +
> +    if ( !ctx->restore.checkpointed )
> +    {
> +        ERROR("Found checkpoint in non-checkpointed stream");
> +        rc = -1;
> +        goto err;
> +    }
> +
> +    if ( ctx->restore.buffer_all_records )
> +    {
> +        IPRINTF("All records buffered");
> +
> +        /*
> +         * We need to set buffer_all_records to false in
> +         * order to process records instead of buffer records.
> +         * buffer_all_records should be set back to true after
> +         * we successfully processed all records.
> +         */
> +        ctx->restore.buffer_all_records = false;
> +        i = 0;
> +        rec = ctx->restore.buffered_records[i++];
> +        while (rec)

Style (hypervisor style).

> +        {
> +            rc = process_record(ctx, rec);
> +            free(rec);
> +            ctx->restore.buffered_records[i-1] = NULL;
> +            if ( rc )
> +                goto err;
> +
> +            rec = ctx->restore.buffered_records[i++];
> +        }
> +        IPRINTF("All records processed");
> +        ctx->restore.buffer_all_records = true;
> +    }
> +    else
> +        ctx->restore.buffer_all_records = true;
> +
> + err:
> +    return rc;
> +}
> +
>  static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
>  {
>      xc_interface *xch = ctx->xch;
> -    int rc = 0;
> +    int rc = 0, i;
> +    struct xc_sr_record *buf_rec;
> +
> +    if ( ctx->restore.buffer_all_records &&
> +         rec->type != REC_TYPE_END &&
> +         rec->type != REC_TYPE_CHECKPOINT )
> +    {
> +        buf_rec = malloc(sizeof(struct xc_sr_record));
> +        if (!buf_rec)
> +        {
> +            ERROR("Unable to allocate memory for record");
> +            return -1;
> +        }
> +        memcpy(buf_rec, rec, sizeof(struct xc_sr_record));
> +
> +        for ( i = 0; i < MAX_BUF_RECORDS; i++ )
> +            if ( !ctx->restore.buffered_records[i] )
> +                break;
> +
> +        if ( i >= MAX_BUF_RECORDS )
> +        {
> +            ERROR("There are too many records within a checkpoint");
> +            return -1;
> +        }
> +        ctx->restore.buffered_records[i] = buf_rec;
> +        return 0;
> +    }
>  
>      switch ( rec->type )
>      {
> @@ -487,6 +560,10 @@ static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec)
>          ctx->restore.verify = true;
>          break;
>  
> +    case REC_TYPE_CHECKPOINT:
> +        rc = handle_checkpoint(ctx);
> +        break;
> +
>      default:
>          rc = ctx->restore.ops.process_record(ctx, rec);
>          break;
> @@ -520,7 +597,7 @@ static int restore(struct xc_sr_context *ctx)
>  {
>      xc_interface *xch = ctx->xch;
>      struct xc_sr_record rec;
> -    int rc, saved_rc = 0, saved_errno = 0;
> +    int rc, saved_rc = 0, saved_errno = 0, i;
>  
>      IPRINTF("Restoring domain");
>  
> @@ -541,7 +618,27 @@ static int restore(struct xc_sr_context *ctx)
>      {
>          rc = read_record(ctx, &rec);
>          if ( rc )
> -            goto err;
> +        {
> +            if ( ctx->restore.buffer_all_records )
> +                goto err_buf;

Please can we choose a label sufficiently different to "err".

"resume_from_checkpoint" perhaps?

~Andrew

> +            else
> +                goto err;
> +        }
> +
> +#ifdef XG_LIBXL_HVM_COMPAT
> +        if ( ctx->dominfo.hvm &&
> +             (rec.type == REC_TYPE_END || rec.type == REC_TYPE_CHECKPOINT) )
> +        {
> +            rc = read_qemu(ctx);
> +            if ( rc )
> +            {
> +                if ( ctx->restore.buffer_all_records )
> +                    goto err_buf;
> +                else
> +                    goto err;
> +            }
> +        }
> +#endif
>  
>          rc = process_record(ctx, &rec);
>          if ( rc )
> @@ -549,15 +646,11 @@ static int restore(struct xc_sr_context *ctx)
>  
>      } while ( rec.type != REC_TYPE_END );
>  
> -#ifdef XG_LIBXL_HVM_COMPAT
> -    if ( ctx->dominfo.hvm )
> -    {
> -        rc = read_qemu(ctx);
> -        if ( rc )
> -            goto err;
> -    }
> -#endif
> -
> + err_buf:
> +    /*
> +     * With Remus, if we reach here, there must be some error on primary,
> +     * failover from the last checkpoint state.
> +     */
>      rc = ctx->restore.ops.stream_complete(ctx);
>      if ( rc )
>          goto err;
> @@ -571,6 +664,13 @@ static int restore(struct xc_sr_context *ctx)
>      PERROR("Restore failed");
>  
>   done:
> +    for ( i = 0; i < MAX_BUF_RECORDS; i++)
> +    {
> +        if ( ctx->restore.buffered_records[i] ) {
> +            free(ctx->restore.buffered_records[i]->data);
> +            free(ctx->restore.buffered_records[i]);
> +        }
> +    }
>      free(ctx->restore.populated_pfns);
>      rc = ctx->restore.ops.cleanup(ctx);
>      if ( rc )

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore
  2015-05-13 16:16   ` Andrew Cooper
@ 2015-05-13 16:38     ` Andrew Cooper
  2015-05-14  5:42     ` Yang Hongyang
  1 sibling, 0 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-05-13 16:38 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, guijianfeng, yunhong.jiang,
	eddie.dong, rshriram, ian.jackson

On 13/05/15 17:16, Andrew Cooper wrote:
>
>> +
>>              /*
>>               * Xenstore and Console parameters.
>>               * INPUT:  evtchn & domid
>> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
>> index 0e512ec..85534a8 100644
>> --- a/tools/libxc/xc_sr_restore.c
>> +++ b/tools/libxc/xc_sr_restore.c
>> @@ -468,10 +468,83 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec)
>>      return rc;
>>  }
>>  
>> +static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec);
>> +static int handle_checkpoint(struct xc_sr_context *ctx)
>> +{
>> +    xc_interface *xch = ctx->xch;
>> +    int rc = 0, i;
> Always an unsigned i for populated_pfnsindexing an array please.

Erm - not sure what happened here.  Ignore the "populated_pfns" please. 
Sorry.

~Andrew

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save
  2015-05-13 15:14   ` Andrew Cooper
@ 2015-05-14  1:08     ` Yang Hongyang
  0 siblings, 0 replies; 13+ messages in thread
From: Yang Hongyang @ 2015-05-14  1:08 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: wei.liu2, ian.campbell, wency, ian.jackson, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram



On 05/13/2015 11:14 PM, Andrew Cooper wrote:
> On 13/05/15 09:34, Yang Hongyang wrote:
>> With Remus, the save flow should be:
>> live migration->{ periodically save(checkpointed save) }
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> CC: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>>   tools/libxc/xc_sr_save.c | 73 +++++++++++++++++++++++++++++++++++-------------
>>   1 file changed, 54 insertions(+), 19 deletions(-)
>>
>> diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
>> index 1d0a46d..3890c4d 100644
>> --- a/tools/libxc/xc_sr_save.c
>> +++ b/tools/libxc/xc_sr_save.c
>> @@ -57,6 +57,16 @@ static int write_end_record(struct xc_sr_context *ctx)
>>   }
>>
>>   /*
>> + * Writes an CHECKPOINT record into the stream.
>> + */
>> +static int write_checkpoint_record(struct xc_sr_context *ctx)
>> +{
>> +    struct xc_sr_record checkpoint = { REC_TYPE_CHECKPOINT, 0, NULL };
>> +
>> +    return write_record(ctx, &checkpoint);
>> +}
>> +
>> +/*
>>    * Writes a batch of memory as a PAGE_DATA record into the stream.  The batch
>>    * is constructed in ctx->save.batch_pfns.
>>    *
>> @@ -467,6 +477,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;
>> +
>
> I really want to avoid this code getting into the same spiders web as it
> used to be with goto, but I cannot suggest a better alternative.
>
> However, please leave a comment explaining that subsequent checkpointed
> loop skip the live part and pause straight away.

OK

>
>>       rc = enable_logdirty(ctx);
>>       if ( rc )
>>           goto out;
>> @@ -505,6 +518,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx)
>>               goto out;
>>       }
>>
>> + last_iter:
>>       rc = suspend_domain(ctx);
>>       if ( rc )
>>           goto out;
>> @@ -667,29 +681,50 @@ 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;
>> +    do {
>> +        rc = ctx->save.ops.start_of_checkpoint(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;
>> +        }
>>
>> -    rc = ctx->save.ops.end_of_checkpoint(ctx);
>> -    if ( rc )
>> -        goto err;
>> +        rc = ctx->save.ops.end_of_checkpoint(ctx);
>> +        if ( rc )
>> +            goto err;
>> +
>> +        if ( ctx->save.checkpointed ) {
>> +            if ( ctx->save.live ) {
>
> Coding style.  libxc is admittedly inconsistent, but follows hypervisor
> style, so { on the next line.

OK

>
>> +                /* End of live migration, we are sending checkpointed stream */
>> +                ctx->save.live = false;
>> +            }
>> +
>> +            rc = write_checkpoint_record(ctx);
>> +            if ( rc )
>> +                goto err;
>> +
>> +            ctx->save.callbacks->postcopy(ctx->save.callbacks->data);
>> +
>> +            rc = ctx->save.callbacks->checkpoint(ctx->save.callbacks->data);
>> +            if ( rc > 0 )
>> +                IPRINTF("Checkpointed save");
>
> This should probably be progress information , so
> xc_report_progress_single()

Will fix.

>
> Otherwise, Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
>
> (I think this code is a bit of an improvement over xc_domain_save.c)
>
>> +            else
>> +                ctx->save.checkpointed = false;
>> +        }
>> +    } while ( ctx->save.checkpointed );
>>
>>       xc_report_progress_single(xch, "End of stream");
>>
>
> .
>

-- 
Thanks,
Yang.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context
  2015-05-13 15:15   ` Andrew Cooper
@ 2015-05-14  1:09     ` Yang Hongyang
  2015-05-14  7:18       ` Andrew Cooper
  0 siblings, 1 reply; 13+ messages in thread
From: Yang Hongyang @ 2015-05-14  1:09 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: wei.liu2, ian.campbell, wency, ian.jackson, yunhong.jiang,
	eddie.dong, guijianfeng, rshriram



On 05/13/2015 11:15 PM, Andrew Cooper wrote:
> On 13/05/15 09:35, Yang Hongyang wrote:
>> add checkpointed flag to the restore context.
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> CC: Andrew Cooper <andrew.cooper3@citrix.com>
>
> This appears unused, given the new restore code.

This is used by handle_checkpoint() for the sanity check.

>
> ~Andrew
>
>> ---
>>   tools/libxc/xc_sr_common.h  | 3 +++
>>   tools/libxc/xc_sr_restore.c | 1 +
>>   2 files changed, 4 insertions(+)
>>
>> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
>> index 0ba9728..f8121e7 100644
>> --- a/tools/libxc/xc_sr_common.h
>> +++ b/tools/libxc/xc_sr_common.h
>> @@ -205,6 +205,9 @@ struct xc_sr_context
>>               uint32_t guest_type;
>>               uint32_t guest_page_size;
>>
>> +            /* Plain VM, or checkpoints over time. */
>> +            bool checkpointed;
>> +
>>               /*
>>                * Xenstore and Console parameters.
>>                * INPUT:  evtchn & domid
>> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
>> index 8022c3d..0e512ec 100644
>> --- a/tools/libxc/xc_sr_restore.c
>> +++ b/tools/libxc/xc_sr_restore.c
>> @@ -604,6 +604,7 @@ int xc_domain_restore2(xc_interface *xch, int io_fd, uint32_t dom,
>>       ctx.restore.console_domid = console_domid;
>>       ctx.restore.xenstore_evtchn = store_evtchn;
>>       ctx.restore.xenstore_domid = store_domid;
>> +    ctx.restore.checkpointed = checkpointed_stream;
>>       ctx.restore.callbacks = callbacks;
>>
>>       IPRINTF("In experimental %s", __func__);
>
> .
>

-- 
Thanks,
Yang.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore
  2015-05-13 16:16   ` Andrew Cooper
  2015-05-13 16:38     ` Andrew Cooper
@ 2015-05-14  5:42     ` Yang Hongyang
  2015-05-14  7:19       ` Andrew Cooper
  1 sibling, 1 reply; 13+ messages in thread
From: Yang Hongyang @ 2015-05-14  5:42 UTC (permalink / raw)
  To: Andrew Cooper, xen-devel
  Cc: wei.liu2, ian.campbell, wency, guijianfeng, yunhong.jiang,
	eddie.dong, rshriram, ian.jackson

On 05/14/2015 12:16 AM, Andrew Cooper wrote:
> On 13/05/15 09:35, Yang Hongyang wrote:
>> With Remus, the restore flow should be:
>> the first full migration stream -> { periodically restore stream }
>>
>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> ---
>>   tools/libxc/xc_sr_common.h  |  13 +++++
>>   tools/libxc/xc_sr_restore.c | 124 +++++++++++++++++++++++++++++++++++++++-----
>>   2 files changed, 125 insertions(+), 12 deletions(-)
>>
>> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
>> index f8121e7..3740b89 100644
>> --- a/tools/libxc/xc_sr_common.h
>> +++ b/tools/libxc/xc_sr_common.h
>> @@ -208,6 +208,19 @@ struct xc_sr_context
>>               /* Plain VM, or checkpoints over time. */
>>               bool checkpointed;
>>
>> +            /* Currently buffering records between a checkpoint */
>> +            bool buffer_all_records;
>> +
>> +/*
>> + * With Remus, we buffer the records sent by primary at checkpoint,
>
> "sent by the primary"
>
>> + * in case the primary will fail, we can recover from the last
>> + * checkpoint state.
>> + * This should be enough because primary only send dirty pages at
>> + * checkpoint.
>> + */
>> +#define MAX_BUF_RECORDS 1024
>
> As a general point, it occurs to me that this might be better as a
> linked list, rather than having a hard limit.  A burst of activity on
> the primary could potentially hit this limit

There are only few records at every checkpoint in my test, mostly under 10,
probably because I don't do much operations in the Guest. This limit can
be adjusted later by further testing.
Even with linked list, we still need a limit IMO, otherwise it will eat too
much memory.

>
>> +            struct xc_sr_record *buffered_records[MAX_BUF_RECORDS];
>
> Your data handling will be much more simple if this were struct
> xc_sr_record *buffered_records; and you do a one-time allocation of
> MAX_BUF_RECORDS * sizeof(struct xc_sr_record), although it will require
> an index integer as well.

Good point, it will avoid the alloc/free of the struct xc_sr_record, I
will add a 'buffered_rec_num' to the context also.

>
> It would probably be best to factor out setup() and clean() just like
> you did for the save side.

OK.

>
>> +
>>               /*
>>                * Xenstore and Console parameters.
>>                * INPUT:  evtchn & domid
>> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
>> index 0e512ec..85534a8 100644
>> --- a/tools/libxc/xc_sr_restore.c
[...]
>> @@ -541,7 +618,27 @@ static int restore(struct xc_sr_context *ctx)
>>       {
>>           rc = read_record(ctx, &rec);
>>           if ( rc )
>> -            goto err;
>> +        {
>> +            if ( ctx->restore.buffer_all_records )
>> +                goto err_buf;
>
> Please can we choose a label sufficiently different to "err".
>
> "resume_from_checkpoint" perhaps?

I think "remus_failover" is better? If you don't have objections, I will
use it as the label.

>
> ~Andrew
>
>> +            else
>> +                goto err;
>> +        }
>> +
>> +#ifdef XG_LIBXL_HVM_COMPAT
>> +        if ( ctx->dominfo.hvm &&
>> +             (rec.type == REC_TYPE_END || rec.type == REC_TYPE_CHECKPOINT) )
>> +        {
>> +            rc = read_qemu(ctx);
>> +            if ( rc )
>> +            {
>> +                if ( ctx->restore.buffer_all_records )
>> +                    goto err_buf;
>> +                else
>> +                    goto err;
>> +            }
>> +        }
>> +#endif
>>
>>           rc = process_record(ctx, &rec);
>>           if ( rc )
>> @@ -549,15 +646,11 @@ static int restore(struct xc_sr_context *ctx)
>>
>>       } while ( rec.type != REC_TYPE_END );
>>
>> -#ifdef XG_LIBXL_HVM_COMPAT
>> -    if ( ctx->dominfo.hvm )
>> -    {
>> -        rc = read_qemu(ctx);
>> -        if ( rc )
>> -            goto err;
>> -    }
>> -#endif
>> -
>> + err_buf:
>> +    /*
>> +     * With Remus, if we reach here, there must be some error on primary,
>> +     * failover from the last checkpoint state.
>> +     */
>>       rc = ctx->restore.ops.stream_complete(ctx);
>>       if ( rc )
>>           goto err;
>> @@ -571,6 +664,13 @@ static int restore(struct xc_sr_context *ctx)
>>       PERROR("Restore failed");
>>
>>    done:
>> +    for ( i = 0; i < MAX_BUF_RECORDS; i++)
>> +    {
>> +        if ( ctx->restore.buffered_records[i] ) {
>> +            free(ctx->restore.buffered_records[i]->data);
>> +            free(ctx->restore.buffered_records[i]);
>> +        }
>> +    }
>>       free(ctx->restore.populated_pfns);
>>       rc = ctx->restore.ops.cleanup(ctx);
>>       if ( rc )
>
> .
>

-- 
Thanks,
Yang.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context
  2015-05-14  1:09     ` Yang Hongyang
@ 2015-05-14  7:18       ` Andrew Cooper
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-05-14  7:18 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, eddie.dong, yunhong.jiang,
	ian.jackson, guijianfeng, rshriram

On 14/05/2015 02:09, Yang Hongyang wrote:
>
>
> On 05/13/2015 11:15 PM, Andrew Cooper wrote:
>> On 13/05/15 09:35, Yang Hongyang wrote:
>>> add checkpointed flag to the restore context.
>>>
>>> Signed-off-by: Yang Hongyang <yanghy@cn.fujitsu.com>
>>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>>> CC: Wei Liu <wei.liu2@citrix.com>
>>> CC: Andrew Cooper <andrew.cooper3@citrix.com>
>>
>> This appears unused, given the new restore code.
>
> This is used by handle_checkpoint() for the sanity check.

Ah yes, and I have realised that it will need to be used when I fix up
the qemu record handling in the future, so Reviewed-by: Andrew Cooper
<andrew.cooper3@citrix.com>

>
>>
>> ~Andrew
>>
>>> ---
>>>   tools/libxc/xc_sr_common.h  | 3 +++
>>>   tools/libxc/xc_sr_restore.c | 1 +
>>>   2 files changed, 4 insertions(+)
>>>
>>> diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
>>> index 0ba9728..f8121e7 100644
>>> --- a/tools/libxc/xc_sr_common.h
>>> +++ b/tools/libxc/xc_sr_common.h
>>> @@ -205,6 +205,9 @@ struct xc_sr_context
>>>               uint32_t guest_type;
>>>               uint32_t guest_page_size;
>>>
>>> +            /* Plain VM, or checkpoints over time. */
>>> +            bool checkpointed;
>>> +
>>>               /*
>>>                * Xenstore and Console parameters.
>>>                * INPUT:  evtchn & domid
>>> diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
>>> index 8022c3d..0e512ec 100644
>>> --- a/tools/libxc/xc_sr_restore.c
>>> +++ b/tools/libxc/xc_sr_restore.c
>>> @@ -604,6 +604,7 @@ int xc_domain_restore2(xc_interface *xch, int
>>> io_fd, uint32_t dom,
>>>       ctx.restore.console_domid = console_domid;
>>>       ctx.restore.xenstore_evtchn = store_evtchn;
>>>       ctx.restore.xenstore_domid = store_domid;
>>> +    ctx.restore.checkpointed = checkpointed_stream;
>>>       ctx.restore.callbacks = callbacks;
>>>
>>>       IPRINTF("In experimental %s", __func__);
>>
>> .
>>
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore
  2015-05-14  5:42     ` Yang Hongyang
@ 2015-05-14  7:19       ` Andrew Cooper
  0 siblings, 0 replies; 13+ messages in thread
From: Andrew Cooper @ 2015-05-14  7:19 UTC (permalink / raw)
  To: Yang Hongyang, xen-devel
  Cc: wei.liu2, ian.campbell, wency, guijianfeng, yunhong.jiang,
	eddie.dong, rshriram, ian.jackson

On 14/05/2015 06:42, Yang Hongyang wrote:
>
>>> @@ -541,7 +618,27 @@ static int restore(struct xc_sr_context *ctx)
>>>       {
>>>           rc = read_record(ctx, &rec);
>>>           if ( rc )
>>> -            goto err;
>>> +        {
>>> +            if ( ctx->restore.buffer_all_records )
>>> +                goto err_buf;
>>
>> Please can we choose a label sufficiently different to "err".
>>
>> "resume_from_checkpoint" perhaps?
>
> I think "remus_failover" is better? If you don't have objections, I will
> use it as the label.

Fine by me.

~Andrew

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-05-14  7:19 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-13  8:34 [PATCH Remus v3 0/3] Remus support for Migration-v2 Yang Hongyang
2015-05-13  8:34 ` [PATCH Remus v3 1/3] libxc/save: implement Remus checkpointed save Yang Hongyang
2015-05-13 15:14   ` Andrew Cooper
2015-05-14  1:08     ` Yang Hongyang
2015-05-13  8:35 ` [PATCH Remus v3 2/3] libxc/restore: add checkpointed flag to the restore context Yang Hongyang
2015-05-13 15:15   ` Andrew Cooper
2015-05-14  1:09     ` Yang Hongyang
2015-05-14  7:18       ` Andrew Cooper
2015-05-13  8:35 ` [PATCH Remus v3 3/3] libxc/restore: implement Remus checkpointed restore Yang Hongyang
2015-05-13 16:16   ` Andrew Cooper
2015-05-13 16:38     ` Andrew Cooper
2015-05-14  5:42     ` Yang Hongyang
2015-05-14  7:19       ` Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.