]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0039-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
move bitmap-mirror patches to seperate folder
[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/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
19 pve-backup.c | 1 +
20 qapi/block-core.json | 6 +++
21 softmmu/vl.c | 1 +
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 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
37 diff --git a/migration/meson.build b/migration/meson.build
38 index 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)
49
50 softmmu_ss.add(files(
51 'block-dirty-bitmap.c',
52 diff --git a/migration/pbs-state.c b/migration/pbs-state.c
53 new file mode 100644
54 index 0000000000..29f2b3860d
55 --- /dev/null
56 +++ b/migration/pbs-state.c
57 @@ -0,0 +1,106 @@
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 +
69 +typedef struct PBSState {
70 + bool active;
71 +} PBSState;
72 +
73 +/* state is accessed via this static variable directly, 'opaque' is NULL */
74 +static PBSState pbs_state;
75 +
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 */
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);
116 + pbs_state.active = false;
117 + return 0;
118 +}
119 +
120 +static bool pbs_state_is_active(void *opaque)
121 +{
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 */
125 + return pbs_state.active;
126 +}
127 +
128 +static bool pbs_state_is_active_iterate(void *opaque)
129 +{
130 + /* we don't iterate, everything is sent in save_setup */
131 + return pbs_state_is_active(opaque);
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 +
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 +
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,
154 + .save_cleanup = pbs_state_save_cleanup,
155 +};
156 +
157 +void pbs_state_mig_init(void)
158 +{
159 + pbs_state.active = true;
160 + register_savevm_live("pbs-state", 0, 1,
161 + &savevm_pbs_state_handlers,
162 + NULL);
163 +}
164 diff --git a/pve-backup.c b/pve-backup.c
165 index ded90cb822..6b25292ba1 100644
166 --- a/pve-backup.c
167 +++ b/pve-backup.c
168 @@ -1130,5 +1130,6 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
169 ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
170 ret->pbs_dirty_bitmap = true;
171 ret->query_bitmap_info = true;
172 + ret->pbs_dirty_bitmap_migration = true;
173 return ret;
174 }
175 diff --git a/qapi/block-core.json b/qapi/block-core.json
176 index b90d6abe64..dee3d87efe 100644
177 --- a/qapi/block-core.json
178 +++ b/qapi/block-core.json
179 @@ -881,12 +881,18 @@
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 +#
188 # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
189 #
190 ##
191 { 'struct': 'ProxmoxSupportStatus',
192 'data': { 'pbs-dirty-bitmap': 'bool',
193 'query-bitmap-info': 'bool',
194 + 'pbs-dirty-bitmap-migration': 'bool',
195 'pbs-library-version': 'str' } }
196
197 ##
198 diff --git a/softmmu/vl.c b/softmmu/vl.c
199 index 5b5512128e..6721889fee 100644
200 --- a/softmmu/vl.c
201 +++ b/softmmu/vl.c
202 @@ -4304,6 +4304,7 @@ void qemu_init(int argc, char **argv, char **envp)
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);