mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
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>
This commit is contained in:
1 parent
ec7b9a1b9b
commit
00a4b65f85
3 files changed
+38
-4
No files matched your search
@@ -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");
|
||||
|
||||
@@ -1616,6 +1616,20 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
|
||||
}
|
||||
}
|
||||
|
||||
if ( !callbacks->checkpoint )
|
||||
{
|
||||
/*
|
||||
* If this is not a checkpointed save then this must be the first and
|
||||
* last checkpoint.
|
||||
*/
|
||||
i = XC_SAVE_ID_LAST_CHECKPOINT;
|
||||
if ( wrexact(io_fd, &i, sizeof(int)) )
|
||||
{
|
||||
PERROR("Error when writing last checkpoint chunk");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Zero terminate */
|
||||
i = 0;
|
||||
if ( wrexact(io_fd, &i, sizeof(int)) )
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
#define XC_SAVE_ID_TMEM_EXTRA -6
|
||||
#define XC_SAVE_ID_TSC_INFO -7
|
||||
#define XC_SAVE_ID_HVM_CONSOLE_PFN -8 /* (HVM-only) */
|
||||
#define XC_SAVE_ID_LAST_CHECKPOINT -9 /* Commit to restoring after completion of current iteration. */
|
||||
|
||||
/*
|
||||
** We process save/restore/migrate in batches of pages; the below
|
||||
|
||||