MIG_CMD_POSTCOPY_RAM_DISCARD, /* A list of pages to discard that
were previously sent during
precopy but are dirty. */
+ MIG_CMD_POSTCOPY_RESUME, /* resume postcopy on dest */
MIG_CMD_PACKAGED, /* Send a wrapped stream within this stream */
MIG_CMD_RECV_BITMAP, /* Request for recved bitmap on dst */
MIG_CMD_MAX
[MIG_CMD_POSTCOPY_RUN] = { .len = 0, .name = "POSTCOPY_RUN" },
[MIG_CMD_POSTCOPY_RAM_DISCARD] = {
.len = -1, .name = "POSTCOPY_RAM_DISCARD" },
+ [MIG_CMD_POSTCOPY_RESUME] = { .len = 0, .name = "POSTCOPY_RESUME" },
[MIG_CMD_PACKAGED] = { .len = 4, .name = "PACKAGED" },
[MIG_CMD_RECV_BITMAP] = { .len = -1, .name = "RECV_BITMAP" },
[MIG_CMD_MAX] = { .len = -1, .name = "MAX" },
qemu_savevm_command_send(f, MIG_CMD_POSTCOPY_RUN, 0, NULL);
}
+void qemu_savevm_send_postcopy_resume(QEMUFile *f)
+{
+ trace_savevm_send_postcopy_resume();
+ qemu_savevm_command_send(f, MIG_CMD_POSTCOPY_RESUME, 0, NULL);
+}
+
void qemu_savevm_send_recv_bitmap(QEMUFile *f, char *block_name)
{
size_t len;
return LOADVM_QUIT;
}
+static int loadvm_postcopy_handle_resume(MigrationIncomingState *mis)
+{
+ if (mis->state != MIGRATION_STATUS_POSTCOPY_RECOVER) {
+ error_report("%s: illegal resume received", __func__);
+ /* Don't fail the load, only for this. */
+ return 0;
+ }
+
+ /*
+ * This means source VM is ready to resume the postcopy migration.
+ * It's time to switch state and release the fault thread to
+ * continue service page faults.
+ */
+ migrate_set_state(&mis->state, MIGRATION_STATUS_POSTCOPY_RECOVER,
+ MIGRATION_STATUS_POSTCOPY_ACTIVE);
+ qemu_sem_post(&mis->postcopy_pause_sem_fault);
+
+ trace_loadvm_postcopy_handle_resume();
+
+ /* TODO: Tell source that "we are ready" */
+
+ return 0;
+}
+
/**
* Immediately following this command is a blob of data containing an embedded
* chunk of migration stream; read it and load it.
case MIG_CMD_POSTCOPY_RAM_DISCARD:
return loadvm_postcopy_ram_handle_discard(mis, len);
+ case MIG_CMD_POSTCOPY_RESUME:
+ return loadvm_postcopy_handle_resume(mis);
+
case MIG_CMD_RECV_BITMAP:
return loadvm_handle_recv_bitmap(mis, len);
}
loadvm_postcopy_handle_run(void) ""
loadvm_postcopy_handle_run_cpu_sync(void) ""
loadvm_postcopy_handle_run_vmstart(void) ""
+loadvm_postcopy_handle_resume(void) ""
loadvm_postcopy_ram_handle_discard(void) ""
loadvm_postcopy_ram_handle_discard_end(void) ""
loadvm_postcopy_ram_handle_discard_header(const char *ramid, uint16_t len) "%s: %ud"
savevm_send_ping(uint32_t val) "0x%x"
savevm_send_postcopy_listen(void) ""
savevm_send_postcopy_run(void) ""
+savevm_send_postcopy_resume(void) ""
savevm_send_recv_bitmap(char *name) "%s"
savevm_state_setup(void) ""
savevm_state_header(void) ""