]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0039-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
udpate and rebase to QEMU v6.0.0
[pve-qemu.git] / debian / patches / pve / 0039-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Stefan Reiter <s.reiter@proxmox.com>
3 Date: Thu, 22 Oct 2020 17:34:18 +0200
4 Subject: [PATCH] PVE: Migrate dirty bitmap state via savevm
5
6 QEMU provides 'savevm' registrations as a mechanism for arbitrary state
7 to be migrated along with a VM. Use this to send a serialized version of
8 dirty bitmap state data from proxmox-backup-qemu, and restore it on the
9 target node.
10
11 Also add a flag to query-proxmox-support so qemu-server can determine if
12 safe migration is possible and makes sense.
13
14 Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
15 ---
16 include/migration/misc.h | 3 ++
17 migration/meson.build | 2 +
18 migration/migration.c | 1 +
19 migration/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
20 pve-backup.c | 1 +
21 qapi/block-core.json | 6 +++
22 6 files changed, 119 insertions(+)
23 create mode 100644 migration/pbs-state.c
24
25 diff --git a/include/migration/misc.h b/include/migration/misc.h
26 index 738675ef52..2b89db4b8e 100644
27 --- a/include/migration/misc.h
28 +++ b/include/migration/misc.h
29 @@ -76,4 +76,7 @@ bool migration_in_bg_snapshot(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
37 diff --git a/migration/meson.build b/migration/meson.build
38 index c8ae813a48..49108c79ef 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 'yank_functions.c',
45 + 'pbs-state.c',
46 )
47 softmmu_ss.add(migration_files)
48 +softmmu_ss.add(libproxmox_backup_qemu)
49
50 softmmu_ss.add(files(
51 'block-dirty-bitmap.c',
52 diff --git a/migration/migration.c b/migration/migration.c
53 index 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)
64 diff --git a/migration/pbs-state.c b/migration/pbs-state.c
65 new file mode 100644
66 index 0000000000..29f2b3860d
67 --- /dev/null
68 +++ b/migration/pbs-state.c
69 @@ -0,0 +1,106 @@
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 +
81 +typedef struct PBSState {
82 + bool active;
83 +} PBSState;
84 +
85 +/* state is accessed via this static variable directly, 'opaque' is NULL */
86 +static PBSState pbs_state;
87 +
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 */
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);
128 + pbs_state.active = false;
129 + return 0;
130 +}
131 +
132 +static bool pbs_state_is_active(void *opaque)
133 +{
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 */
137 + return pbs_state.active;
138 +}
139 +
140 +static bool pbs_state_is_active_iterate(void *opaque)
141 +{
142 + /* we don't iterate, everything is sent in save_setup */
143 + return pbs_state_is_active(opaque);
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 +
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 +
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,
166 + .save_cleanup = pbs_state_save_cleanup,
167 +};
168 +
169 +void pbs_state_mig_init(void)
170 +{
171 + pbs_state.active = true;
172 + register_savevm_live("pbs-state", 0, 1,
173 + &savevm_pbs_state_handlers,
174 + NULL);
175 +}
176 diff --git a/pve-backup.c b/pve-backup.c
177 index 59b4034871..ecff792760 100644
178 --- a/pve-backup.c
179 +++ b/pve-backup.c
180 @@ -1132,6 +1132,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
181 ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
182 ret->pbs_dirty_bitmap = true;
183 ret->pbs_dirty_bitmap_savevm = true;
184 + ret->pbs_dirty_bitmap_migration = true;
185 ret->query_bitmap_info = true;
186 return ret;
187 }
188 diff --git a/qapi/block-core.json b/qapi/block-core.json
189 index 710b8dfb2d..cf3cbf2a56 100644
190 --- a/qapi/block-core.json
191 +++ b/qapi/block-core.json
192 @@ -822,6 +822,11 @@
193 # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
194 # safely be set for savevm-async.
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 +#
201 # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
202 #
203 ##
204 @@ -829,6 +834,7 @@
205 'data': { 'pbs-dirty-bitmap': 'bool',
206 'query-bitmap-info': 'bool',
207 'pbs-dirty-bitmap-savevm': 'bool',
208 + 'pbs-dirty-bitmap-migration': 'bool',
209 'pbs-library-version': 'str' } }
210
211 ##