89 lines
2.9 KiB
Diff
89 lines
2.9 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Stefan Reiter <s.reiter@proxmox.com>
|
||
|
Date: Wed, 8 Apr 2020 15:29:03 +0200
|
||
|
Subject: [PATCH] PVE: savevm-async: set up migration state
|
||
|
|
||
|
code mostly adapted from upstream savevm.c
|
||
|
|
||
|
Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
|
||
|
---
|
||
|
savevm-async.c | 30 ++++++++++++++++++++++++++++--
|
||
|
1 file changed, 28 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/savevm-async.c b/savevm-async.c
|
||
|
index 790e27ae37..a38b15d652 100644
|
||
|
--- a/savevm-async.c
|
||
|
+++ b/savevm-async.c
|
||
|
@@ -225,6 +225,7 @@ static void *process_savevm_thread(void *opaque)
|
||
|
{
|
||
|
int ret;
|
||
|
int64_t maxlen;
|
||
|
+ MigrationState *ms = migrate_get_current();
|
||
|
|
||
|
rcu_register_thread();
|
||
|
|
||
|
@@ -234,8 +235,7 @@ static void *process_savevm_thread(void *opaque)
|
||
|
|
||
|
if (ret < 0) {
|
||
|
save_snapshot_error("qemu_savevm_state_setup failed");
|
||
|
- rcu_unregister_thread();
|
||
|
- return NULL;
|
||
|
+ goto out;
|
||
|
}
|
||
|
|
||
|
while (snap_state.state == SAVE_STATE_ACTIVE) {
|
||
|
@@ -287,6 +287,12 @@ static void *process_savevm_thread(void *opaque)
|
||
|
qemu_bh_schedule(snap_state.cleanup_bh);
|
||
|
qemu_mutex_unlock_iothread();
|
||
|
|
||
|
+out:
|
||
|
+ /* set migration state accordingly and clear soon-to-be stale file */
|
||
|
+ migrate_set_state(&ms->state, MIGRATION_STATUS_SETUP,
|
||
|
+ ret ? MIGRATION_STATUS_FAILED : MIGRATION_STATUS_COMPLETED);
|
||
|
+ ms->to_dst_file = NULL;
|
||
|
+
|
||
|
rcu_unregister_thread();
|
||
|
return NULL;
|
||
|
}
|
||
|
@@ -294,6 +300,7 @@ static void *process_savevm_thread(void *opaque)
|
||
|
void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||
|
{
|
||
|
Error *local_err = NULL;
|
||
|
+ MigrationState *ms = migrate_get_current();
|
||
|
|
||
|
int bdrv_oflags = BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH;
|
||
|
|
||
|
@@ -303,6 +310,17 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
+ if (migration_is_running(ms->state)) {
|
||
|
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR, QERR_MIGRATION_ACTIVE);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (migrate_use_block()) {
|
||
|
+ error_set(errp, ERROR_CLASS_GENERIC_ERROR,
|
||
|
+ "Block migration and snapshots are incompatible");
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
/* initialize snapshot info */
|
||
|
snap_state.saved_vm_running = runstate_is_running();
|
||
|
snap_state.bs_pos = 0;
|
||
|
@@ -341,6 +359,14 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp)
|
||
|
goto restart;
|
||
|
}
|
||
|
|
||
|
+ /*
|
||
|
+ * qemu_savevm_* paths use migration code and expect a migration state.
|
||
|
+ * State is cleared in process_savevm_thread, but has to be initialized
|
||
|
+ * here (blocking main thread, from QMP) to avoid race conditions.
|
||
|
+ */
|
||
|
+ migrate_init(ms);
|
||
|
+ memset(&ram_counters, 0, sizeof(ram_counters));
|
||
|
+ ms->to_dst_file = snap_state.file;
|
||
|
|
||
|
error_setg(&snap_state.blocker, "block device is in use by savevm");
|
||
|
blk_op_block_all(snap_state.target, snap_state.blocker);
|