]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0038-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
bump version to 6.0.0-4
[pve-qemu.git] / debian / patches / pve / 0038-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
CommitLineData
d95ad93e
TL
1From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2From: Stefan Reiter <s.reiter@proxmox.com>
3Date: Thu, 22 Oct 2020 17:34:18 +0200
4Subject: [PATCH] PVE: Migrate dirty bitmap state via savevm
5
6QEMU provides 'savevm' registrations as a mechanism for arbitrary state
7to be migrated along with a VM. Use this to send a serialized version of
8dirty bitmap state data from proxmox-backup-qemu, and restore it on the
9target node.
10
11Also add a flag to query-proxmox-support so qemu-server can determine if
12safe migration is possible and makes sense.
13
14Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
15---
cfe02b3b 16 include/migration/misc.h | 3 ++
817b7667 17 migration/meson.build | 2 +
8dca018b 18 migration/migration.c | 1 +
cfe02b3b
SR
19 migration/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
20 pve-backup.c | 1 +
21 qapi/block-core.json | 6 +++
817b7667 22 6 files changed, 119 insertions(+)
d95ad93e
TL
23 create mode 100644 migration/pbs-state.c
24
25diff --git a/include/migration/misc.h b/include/migration/misc.h
8dca018b 26index 738675ef52..2b89db4b8e 100644
d95ad93e
TL
27--- a/include/migration/misc.h
28+++ b/include/migration/misc.h
8dca018b 29@@ -76,4 +76,7 @@ bool migration_in_bg_snapshot(void);
d95ad93e
TL
30 /* migration/block-dirty-bitmap.c */
31 void dirty_bitmap_mig_init(void);
32
33+/* migration/pbs-state.c */
34+void pbs_state_mig_init(void);
35+
36 #endif
817b7667 37diff --git a/migration/meson.build b/migration/meson.build
8dca018b 38index c8ae813a48..49108c79ef 100644
817b7667
SR
39--- a/migration/meson.build
40+++ b/migration/meson.build
41@@ -7,8 +7,10 @@ migration_files = files(
42 'qemu-file-channel.c',
43 'qemu-file.c',
8dca018b 44 'yank_functions.c',
817b7667
SR
45+ 'pbs-state.c',
46 )
47 softmmu_ss.add(migration_files)
48+softmmu_ss.add(libproxmox_backup_qemu)
d95ad93e 49
817b7667
SR
50 softmmu_ss.add(files(
51 'block-dirty-bitmap.c',
8dca018b
SR
52diff --git a/migration/migration.c b/migration/migration.c
53index 8ca034136b..a5ce875685 100644
54--- a/migration/migration.c
55+++ b/migration/migration.c
56@@ -221,6 +221,7 @@ void migration_object_init(void)
57 blk_mig_init();
58 ram_mig_init();
59 dirty_bitmap_mig_init();
60+ pbs_state_mig_init();
61 }
62
63 void migration_shutdown(void)
d95ad93e
TL
64diff --git a/migration/pbs-state.c b/migration/pbs-state.c
65new file mode 100644
cfe02b3b 66index 0000000000..29f2b3860d
d95ad93e
TL
67--- /dev/null
68+++ b/migration/pbs-state.c
cfe02b3b 69@@ -0,0 +1,106 @@
d95ad93e
TL
70+/*
71+ * PBS (dirty-bitmap) state migration
72+ */
73+
74+#include "qemu/osdep.h"
75+#include "migration/misc.h"
76+#include "qemu-file.h"
77+#include "migration/vmstate.h"
78+#include "migration/register.h"
79+#include "proxmox-backup-qemu.h"
80+
66eae0ae
TL
81+typedef struct PBSState {
82+ bool active;
83+} PBSState;
84+
cfe02b3b 85+/* state is accessed via this static variable directly, 'opaque' is NULL */
66eae0ae
TL
86+static PBSState pbs_state;
87+
d95ad93e
TL
88+static void pbs_state_save_pending(QEMUFile *f, void *opaque,
89+ uint64_t max_size,
90+ uint64_t *res_precopy_only,
91+ uint64_t *res_compatible,
92+ uint64_t *res_postcopy_only)
93+{
94+ /* we send everything in save_setup, so nothing is ever pending */
d95ad93e
TL
95+}
96+
97+/* receive PBS state via f and deserialize, called on target */
98+static int pbs_state_load(QEMUFile *f, void *opaque, int version_id)
99+{
100+ /* safe cast, we cannot migrate to target with less bits than source */
101+ size_t buf_size = (size_t)qemu_get_be64(f);
102+
103+ uint8_t *buf = (uint8_t *)malloc(buf_size);
104+ size_t read = qemu_get_buffer(f, buf, buf_size);
105+
106+ if (read < buf_size) {
107+ fprintf(stderr, "error receiving PBS state: not enough data\n");
108+ return -EIO;
109+ }
110+
111+ proxmox_import_state(buf, buf_size);
112+
113+ free(buf);
114+ return 0;
115+}
116+
117+/* serialize PBS state and send to target via f, called on source */
118+static int pbs_state_save_setup(QEMUFile *f, void *opaque)
119+{
120+ size_t buf_size;
121+ uint8_t *buf = proxmox_export_state(&buf_size);
122+
123+ /* LV encoding */
124+ qemu_put_be64(f, buf_size);
125+ qemu_put_buffer(f, buf, buf_size);
126+
127+ proxmox_free_state_buf(buf);
66eae0ae 128+ pbs_state.active = false;
d95ad93e
TL
129+ return 0;
130+}
131+
132+static bool pbs_state_is_active(void *opaque)
133+{
cfe02b3b
SR
134+ /* we need to return active exactly once, else .save_setup is never called,
135+ * but if we'd just return true the migration doesn't make progress since
136+ * it'd be waiting for us */
66eae0ae 137+ return pbs_state.active;
d95ad93e
TL
138+}
139+
140+static bool pbs_state_is_active_iterate(void *opaque)
141+{
142+ /* we don't iterate, everything is sent in save_setup */
66eae0ae 143+ return pbs_state_is_active(opaque);
d95ad93e
TL
144+}
145+
146+static bool pbs_state_has_postcopy(void *opaque)
147+{
148+ /* PBS state can't change during a migration (since that's blocking any
149+ * potential backups), so we can copy everything before the VM is stopped */
150+ return false;
151+}
152+
cfe02b3b
SR
153+static void pbs_state_save_cleanup(void *opaque)
154+{
155+ /* reset active after migration succeeds or fails */
156+ pbs_state.active = false;
157+}
158+
d95ad93e
TL
159+static SaveVMHandlers savevm_pbs_state_handlers = {
160+ .save_setup = pbs_state_save_setup,
161+ .has_postcopy = pbs_state_has_postcopy,
162+ .save_live_pending = pbs_state_save_pending,
163+ .is_active_iterate = pbs_state_is_active_iterate,
164+ .load_state = pbs_state_load,
165+ .is_active = pbs_state_is_active,
cfe02b3b 166+ .save_cleanup = pbs_state_save_cleanup,
d95ad93e
TL
167+};
168+
169+void pbs_state_mig_init(void)
170+{
66eae0ae 171+ pbs_state.active = true;
d95ad93e
TL
172+ register_savevm_live("pbs-state", 0, 1,
173+ &savevm_pbs_state_handlers,
cfe02b3b 174+ NULL);
d95ad93e
TL
175+}
176diff --git a/pve-backup.c b/pve-backup.c
277d3345 177index 9c20ef3a5e..59ccb38ceb 100644
d95ad93e
TL
178--- a/pve-backup.c
179+++ b/pve-backup.c
8dca018b 180@@ -1132,6 +1132,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
32ee4115 181 ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
d95ad93e 182 ret->pbs_dirty_bitmap = true;
e9b36665 183 ret->pbs_dirty_bitmap_savevm = true;
d95ad93e 184+ ret->pbs_dirty_bitmap_migration = true;
e9b36665 185 ret->query_bitmap_info = true;
d95ad93e
TL
186 return ret;
187 }
188diff --git a/qapi/block-core.json b/qapi/block-core.json
8dca018b 189index 710b8dfb2d..cf3cbf2a56 100644
d95ad93e
TL
190--- a/qapi/block-core.json
191+++ b/qapi/block-core.json
8dca018b 192@@ -822,6 +822,11 @@
e9b36665
SR
193 # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
194 # safely be set for savevm-async.
d95ad93e
TL
195 #
196+# @pbs-dirty-bitmap-migration: True if safe migration of dirty-bitmaps including
197+# PBS state is supported. Enabling 'dirty-bitmaps'
198+# migration cap if this is false/unset may lead
199+# to crashes on migration!
200+#
32ee4115
SR
201 # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
202 #
d95ad93e 203 ##
8dca018b 204@@ -829,6 +834,7 @@
32ee4115
SR
205 'data': { 'pbs-dirty-bitmap': 'bool',
206 'query-bitmap-info': 'bool',
e9b36665 207 'pbs-dirty-bitmap-savevm': 'bool',
32ee4115
SR
208+ 'pbs-dirty-bitmap-migration': 'bool',
209 'pbs-library-version': 'str' } }
d95ad93e
TL
210
211 ##