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