]>
Commit | Line | Data |
---|---|---|
83faa3fe TL |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Stefan Reiter <s.reiter@proxmox.com> | |
3 | Date: Wed, 8 Apr 2020 15:29:03 +0200 | |
4 | Subject: [PATCH] PVE: savevm-async: set up migration state | |
5 | ||
6 | code mostly adapted from upstream savevm.c | |
7 | ||
8 | Signed-off-by: Stefan Reiter <s.reiter@proxmox.com> | |
9 | --- | |
10 | savevm-async.c | 30 ++++++++++++++++++++++++++++-- | |
11 | 1 file changed, 28 insertions(+), 2 deletions(-) | |
12 | ||
13 | diff --git a/savevm-async.c b/savevm-async.c | |
14 | index 790e27ae37..a38b15d652 100644 | |
15 | --- a/savevm-async.c | |
16 | +++ b/savevm-async.c | |
17 | @@ -225,6 +225,7 @@ static void *process_savevm_thread(void *opaque) | |
18 | { | |
19 | int ret; | |
20 | int64_t maxlen; | |
21 | + MigrationState *ms = migrate_get_current(); | |
22 | ||
23 | rcu_register_thread(); | |
24 | ||
25 | @@ -234,8 +235,7 @@ static void *process_savevm_thread(void *opaque) | |
26 | ||
27 | if (ret < 0) { | |
28 | save_snapshot_error("qemu_savevm_state_setup failed"); | |
29 | - rcu_unregister_thread(); | |
30 | - return NULL; | |
31 | + goto out; | |
32 | } | |
33 | ||
34 | while (snap_state.state == SAVE_STATE_ACTIVE) { | |
35 | @@ -287,6 +287,12 @@ static void *process_savevm_thread(void *opaque) | |
36 | qemu_bh_schedule(snap_state.cleanup_bh); | |
37 | qemu_mutex_unlock_iothread(); | |
38 | ||
39 | +out: | |
40 | + /* set migration state accordingly and clear soon-to-be stale file */ | |
41 | + migrate_set_state(&ms->state, MIGRATION_STATUS_SETUP, | |
42 | + ret ? MIGRATION_STATUS_FAILED : MIGRATION_STATUS_COMPLETED); | |
43 | + ms->to_dst_file = NULL; | |
44 | + | |
45 | rcu_unregister_thread(); | |
46 | return NULL; | |
47 | } | |
48 | @@ -294,6 +300,7 @@ static void *process_savevm_thread(void *opaque) | |
49 | void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp) | |
50 | { | |
51 | Error *local_err = NULL; | |
52 | + MigrationState *ms = migrate_get_current(); | |
53 | ||
54 | int bdrv_oflags = BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH; | |
55 | ||
56 | @@ -303,6 +310,17 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp) | |
57 | return; | |
58 | } | |
59 | ||
60 | + if (migration_is_running(ms->state)) { | |
61 | + error_set(errp, ERROR_CLASS_GENERIC_ERROR, QERR_MIGRATION_ACTIVE); | |
62 | + return; | |
63 | + } | |
64 | + | |
65 | + if (migrate_use_block()) { | |
66 | + error_set(errp, ERROR_CLASS_GENERIC_ERROR, | |
67 | + "Block migration and snapshots are incompatible"); | |
68 | + return; | |
69 | + } | |
70 | + | |
71 | /* initialize snapshot info */ | |
72 | snap_state.saved_vm_running = runstate_is_running(); | |
73 | snap_state.bs_pos = 0; | |
74 | @@ -341,6 +359,14 @@ void qmp_savevm_start(bool has_statefile, const char *statefile, Error **errp) | |
75 | goto restart; | |
76 | } | |
77 | ||
78 | + /* | |
79 | + * qemu_savevm_* paths use migration code and expect a migration state. | |
80 | + * State is cleared in process_savevm_thread, but has to be initialized | |
81 | + * here (blocking main thread, from QMP) to avoid race conditions. | |
82 | + */ | |
83 | + migrate_init(ms); | |
84 | + memset(&ram_counters, 0, sizeof(ram_counters)); | |
85 | + ms->to_dst_file = snap_state.file; | |
86 | ||
87 | error_setg(&snap_state.blocker, "block device is in use by savevm"); | |
88 | blk_op_block_all(snap_state.target, snap_state.blocker); |