|
@@ -90,6 +90,7 @@ enum qemu_vm_cmd {
|
|
|
MIG_CMD_ENABLE_COLO, /* Enable COLO */
|
|
|
MIG_CMD_POSTCOPY_RESUME, /* resume postcopy on dest */
|
|
|
MIG_CMD_RECV_BITMAP, /* Request for recved bitmap on dst */
|
|
|
+ MIG_CMD_SWITCHOVER_START, /* Switchover start notification */
|
|
|
MIG_CMD_MAX
|
|
|
};
|
|
|
|
|
@@ -109,6 +110,7 @@ static struct mig_cmd_args {
|
|
|
[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_SWITCHOVER_START] = { .len = 0, .name = "SWITCHOVER_START" },
|
|
|
[MIG_CMD_MAX] = { .len = -1, .name = "MAX" },
|
|
|
};
|
|
|
|
|
@@ -1201,6 +1203,19 @@ void qemu_savevm_send_recv_bitmap(QEMUFile *f, char *block_name)
|
|
|
qemu_savevm_command_send(f, MIG_CMD_RECV_BITMAP, len + 1, (uint8_t *)buf);
|
|
|
}
|
|
|
|
|
|
+static void qemu_savevm_send_switchover_start(QEMUFile *f)
|
|
|
+{
|
|
|
+ trace_savevm_send_switchover_start();
|
|
|
+ qemu_savevm_command_send(f, MIG_CMD_SWITCHOVER_START, 0, NULL);
|
|
|
+}
|
|
|
+
|
|
|
+void qemu_savevm_maybe_send_switchover_start(QEMUFile *f)
|
|
|
+{
|
|
|
+ if (migrate_send_switchover_start()) {
|
|
|
+ qemu_savevm_send_switchover_start(f);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
bool qemu_savevm_state_blocked(Error **errp)
|
|
|
{
|
|
|
SaveStateEntry *se;
|
|
@@ -1687,6 +1702,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
|
|
|
|
|
|
ret = qemu_file_get_error(f);
|
|
|
if (ret == 0) {
|
|
|
+ qemu_savevm_maybe_send_switchover_start(f);
|
|
|
qemu_savevm_state_complete_precopy(f, false);
|
|
|
ret = qemu_file_get_error(f);
|
|
|
}
|
|
@@ -2383,6 +2399,26 @@ static int loadvm_process_enable_colo(MigrationIncomingState *mis)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int loadvm_postcopy_handle_switchover_start(void)
|
|
|
+{
|
|
|
+ SaveStateEntry *se;
|
|
|
+
|
|
|
+ QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (!se->ops || !se->ops->switchover_start) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = se->ops->switchover_start(se->opaque);
|
|
|
+ if (ret < 0) {
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Process an incoming 'QEMU_VM_COMMAND'
|
|
|
* 0 just a normal return
|
|
@@ -2481,6 +2517,9 @@ static int loadvm_process_command(QEMUFile *f)
|
|
|
|
|
|
case MIG_CMD_ENABLE_COLO:
|
|
|
return loadvm_process_enable_colo(mis);
|
|
|
+
|
|
|
+ case MIG_CMD_SWITCHOVER_START:
|
|
|
+ return loadvm_postcopy_handle_switchover_start();
|
|
|
}
|
|
|
|
|
|
return 0;
|