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