]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/pve/0039-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
bump version to 5.2.0-3
[pve-qemu.git] / debian / patches / pve / 0039-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 +
cfe02b3b
SR
18 migration/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
19 pve-backup.c | 1 +
20 qapi/block-core.json | 6 +++
21 softmmu/vl.c | 1 +
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
26index 34e7d75713..f83816dd3c 100644
27--- a/include/migration/misc.h
28+++ b/include/migration/misc.h
29@@ -75,4 +75,7 @@ bool migration_in_incoming_postcopy(void);
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
SR
37diff --git a/migration/meson.build b/migration/meson.build
38index e62b79b60f..b90a04aa75 100644
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',
44 'qjson.c',
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',
d95ad93e
TL
52diff --git a/migration/pbs-state.c b/migration/pbs-state.c
53new file mode 100644
cfe02b3b 54index 0000000000..29f2b3860d
d95ad93e
TL
55--- /dev/null
56+++ b/migration/pbs-state.c
cfe02b3b 57@@ -0,0 +1,106 @@
d95ad93e
TL
58+/*
59+ * PBS (dirty-bitmap) state migration
60+ */
61+
62+#include "qemu/osdep.h"
63+#include "migration/misc.h"
64+#include "qemu-file.h"
65+#include "migration/vmstate.h"
66+#include "migration/register.h"
67+#include "proxmox-backup-qemu.h"
68+
66eae0ae
TL
69+typedef struct PBSState {
70+ bool active;
71+} PBSState;
72+
cfe02b3b 73+/* state is accessed via this static variable directly, 'opaque' is NULL */
66eae0ae
TL
74+static PBSState pbs_state;
75+
d95ad93e
TL
76+static void pbs_state_save_pending(QEMUFile *f, void *opaque,
77+ uint64_t max_size,
78+ uint64_t *res_precopy_only,
79+ uint64_t *res_compatible,
80+ uint64_t *res_postcopy_only)
81+{
82+ /* we send everything in save_setup, so nothing is ever pending */
d95ad93e
TL
83+}
84+
85+/* receive PBS state via f and deserialize, called on target */
86+static int pbs_state_load(QEMUFile *f, void *opaque, int version_id)
87+{
88+ /* safe cast, we cannot migrate to target with less bits than source */
89+ size_t buf_size = (size_t)qemu_get_be64(f);
90+
91+ uint8_t *buf = (uint8_t *)malloc(buf_size);
92+ size_t read = qemu_get_buffer(f, buf, buf_size);
93+
94+ if (read < buf_size) {
95+ fprintf(stderr, "error receiving PBS state: not enough data\n");
96+ return -EIO;
97+ }
98+
99+ proxmox_import_state(buf, buf_size);
100+
101+ free(buf);
102+ return 0;
103+}
104+
105+/* serialize PBS state and send to target via f, called on source */
106+static int pbs_state_save_setup(QEMUFile *f, void *opaque)
107+{
108+ size_t buf_size;
109+ uint8_t *buf = proxmox_export_state(&buf_size);
110+
111+ /* LV encoding */
112+ qemu_put_be64(f, buf_size);
113+ qemu_put_buffer(f, buf, buf_size);
114+
115+ proxmox_free_state_buf(buf);
66eae0ae 116+ pbs_state.active = false;
d95ad93e
TL
117+ return 0;
118+}
119+
120+static bool pbs_state_is_active(void *opaque)
121+{
cfe02b3b
SR
122+ /* we need to return active exactly once, else .save_setup is never called,
123+ * but if we'd just return true the migration doesn't make progress since
124+ * it'd be waiting for us */
66eae0ae 125+ return pbs_state.active;
d95ad93e
TL
126+}
127+
128+static bool pbs_state_is_active_iterate(void *opaque)
129+{
130+ /* we don't iterate, everything is sent in save_setup */
66eae0ae 131+ return pbs_state_is_active(opaque);
d95ad93e
TL
132+}
133+
134+static bool pbs_state_has_postcopy(void *opaque)
135+{
136+ /* PBS state can't change during a migration (since that's blocking any
137+ * potential backups), so we can copy everything before the VM is stopped */
138+ return false;
139+}
140+
cfe02b3b
SR
141+static void pbs_state_save_cleanup(void *opaque)
142+{
143+ /* reset active after migration succeeds or fails */
144+ pbs_state.active = false;
145+}
146+
d95ad93e
TL
147+static SaveVMHandlers savevm_pbs_state_handlers = {
148+ .save_setup = pbs_state_save_setup,
149+ .has_postcopy = pbs_state_has_postcopy,
150+ .save_live_pending = pbs_state_save_pending,
151+ .is_active_iterate = pbs_state_is_active_iterate,
152+ .load_state = pbs_state_load,
153+ .is_active = pbs_state_is_active,
cfe02b3b 154+ .save_cleanup = pbs_state_save_cleanup,
d95ad93e
TL
155+};
156+
157+void pbs_state_mig_init(void)
158+{
66eae0ae 159+ pbs_state.active = true;
d95ad93e
TL
160+ register_savevm_live("pbs-state", 0, 1,
161+ &savevm_pbs_state_handlers,
cfe02b3b 162+ NULL);
d95ad93e
TL
163+}
164diff --git a/pve-backup.c b/pve-backup.c
817b7667 165index ded90cb822..6b25292ba1 100644
d95ad93e
TL
166--- a/pve-backup.c
167+++ b/pve-backup.c
32ee4115
SR
168@@ -1130,5 +1130,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
169 ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
d95ad93e
TL
170 ret->pbs_dirty_bitmap = true;
171 ret->query_bitmap_info = true;
172+ ret->pbs_dirty_bitmap_migration = true;
173 return ret;
174 }
175diff --git a/qapi/block-core.json b/qapi/block-core.json
817b7667 176index b90d6abe64..dee3d87efe 100644
d95ad93e
TL
177--- a/qapi/block-core.json
178+++ b/qapi/block-core.json
817b7667 179@@ -881,12 +881,18 @@
d95ad93e
TL
180 #
181 # @query-bitmap-info: True if the 'query-pbs-bitmap-info' QMP call is supported.
182 #
183+# @pbs-dirty-bitmap-migration: True if safe migration of dirty-bitmaps including
184+# PBS state is supported. Enabling 'dirty-bitmaps'
185+# migration cap if this is false/unset may lead
186+# to crashes on migration!
187+#
32ee4115
SR
188 # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
189 #
d95ad93e
TL
190 ##
191 { 'struct': 'ProxmoxSupportStatus',
32ee4115
SR
192 'data': { 'pbs-dirty-bitmap': 'bool',
193 'query-bitmap-info': 'bool',
194+ 'pbs-dirty-bitmap-migration': 'bool',
195 'pbs-library-version': 'str' } }
d95ad93e
TL
196
197 ##
d95ad93e 198diff --git a/softmmu/vl.c b/softmmu/vl.c
817b7667 199index 5b5512128e..6721889fee 100644
d95ad93e
TL
200--- a/softmmu/vl.c
201+++ b/softmmu/vl.c
817b7667 202@@ -4304,6 +4304,7 @@ void qemu_init(int argc, char **argv, char **envp)
d95ad93e
TL
203 blk_mig_init();
204 ram_mig_init();
205 dirty_bitmap_mig_init();
206+ pbs_state_mig_init();
207
208 qemu_opts_foreach(qemu_find_opts("mon"),
209 mon_init_func, NULL, &error_fatal);