aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_domain_restore.c
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2010-09-07 19:08:11 +0100
committerIan Campbell <ian.campbell@citrix.com>2010-09-07 19:08:11 +0100
commit00a4b65f8534c9e6521eab2e6ce796ae36037774 (patch)
tree6c3494e0dcb6f1e7214becfd7fe88772d0d45e17 /tools/libxc/xc_domain_restore.c
parentec7b9a1b9b2a935fa322eca98d95741ff6d162bb (diff)
downloadxen-00a4b65f8534c9e6521eab2e6ce796ae36037774.tar.gz
xen-00a4b65f8534c9e6521eab2e6ce796ae36037774.tar.bz2
xen-00a4b65f8534c9e6521eab2e6ce796ae36037774.zip
libxc: provide notification of final checkpoint to restore end
When the restore code sees this notification it will restore the currently in-progress checkpoint when it completes. This allows the restore end to finish up without waiting for a spurious timeout on the receive fd and thereby avoids unnecessary error logging in the case of a successful migration or restore. In the normal migration or restore case the first checkpoint is always the last. For a rolling checkpoint (such as Remus) the notification is currently unused but could be used in the future for example to provide a controlled failover for reasons other than error Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Acked-by: Brendan Cully <brendan@cs.ubc.ca> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxc/xc_domain_restore.c')
-rw-r--r--tools/libxc/xc_domain_restore.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 4c7aa0c1e5..6ba5c7580d 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -42,6 +42,7 @@ struct restore_ctx {
xen_pfn_t *p2m; /* A table mapping each PFN to its new MFN. */
xen_pfn_t *p2m_batch; /* A table of P2M mappings in the current region. */
int completed; /* Set when a consistent image is available */
+ int last_checkpoint; /* Set when we should commit to the current checkpoint when it completes. */
struct domain_info_context dinfo;
};
@@ -765,6 +766,11 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx,
// DPRINTF("console pfn location: %llx\n", buf->console_pfn);
return pagebuf_get_one(xch, ctx, buf, fd, dom);
+ case XC_SAVE_ID_LAST_CHECKPOINT:
+ ctx->last_checkpoint = 1;
+ // DPRINTF("last checkpoint indication received");
+ return pagebuf_get_one(xch, ctx, buf, fd, dom);
+
default:
if ( (count > MAX_BATCH_SIZE) || (count < 0) ) {
ERROR("Max batch size exceeded (%d). Giving up.", count);
@@ -1296,10 +1302,23 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
goto out;
}
ctx->completed = 1;
- /* shift into nonblocking mode for the remainder */
- if ( (flags = fcntl(io_fd, F_GETFL,0)) < 0 )
- flags = 0;
- fcntl(io_fd, F_SETFL, flags | O_NONBLOCK);
+
+ /*
+ * If more checkpoints are expected then shift into
+ * nonblocking mode for the remainder.
+ */
+ if ( !ctx->last_checkpoint )
+ {
+ if ( (flags = fcntl(io_fd, F_GETFL,0)) < 0 )
+ flags = 0;
+ fcntl(io_fd, F_SETFL, flags | O_NONBLOCK);
+ }
+ }
+
+ if ( ctx->last_checkpoint )
+ {
+ // DPRINTF("Last checkpoint, finishing\n");
+ goto finish;
}
// DPRINTF("Buffered checkpoint\n");