]> git.proxmox.com Git - pve-qemu.git/blob - debian/patches/pve/0040-PVE-Migrate-dirty-bitmap-state-via-savevm.patch
update submodule and patches to 7.2.0
[pve-qemu.git] / debian / patches / pve / 0040-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 Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 ---
17 include/migration/misc.h | 3 ++
18 migration/meson.build | 2 +
19 migration/migration.c | 1 +
20 migration/pbs-state.c | 106 +++++++++++++++++++++++++++++++++++++++
21 pve-backup.c | 1 +
22 qapi/block-core.json | 6 +++
23 6 files changed, 119 insertions(+)
24 create mode 100644 migration/pbs-state.c
25
26 diff --git a/include/migration/misc.h b/include/migration/misc.h
27 index 465906710d..4f0aeceb6f 100644
28 --- a/include/migration/misc.h
29 +++ b/include/migration/misc.h
30 @@ -75,4 +75,7 @@ bool migration_in_bg_snapshot(void);
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
38 diff --git a/migration/meson.build b/migration/meson.build
39 index 0842d00cd2..d012f4d8d3 100644
40 --- a/migration/meson.build
41 +++ b/migration/meson.build
42 @@ -6,8 +6,10 @@ migration_files = files(
43 'vmstate.c',
44 'qemu-file.c',
45 'yank_functions.c',
46 + 'pbs-state.c',
47 )
48 softmmu_ss.add(migration_files)
49 +softmmu_ss.add(libproxmox_backup_qemu)
50
51 softmmu_ss.add(files(
52 'block-dirty-bitmap.c',
53 diff --git a/migration/migration.c b/migration/migration.c
54 index f485eea5fb..89b287180f 100644
55 --- a/migration/migration.c
56 +++ b/migration/migration.c
57 @@ -229,6 +229,7 @@ void migration_object_init(void)
58 blk_mig_init();
59 ram_mig_init();
60 dirty_bitmap_mig_init();
61 + pbs_state_mig_init();
62 }
63
64 void migration_cancel(const Error *error)
65 diff --git a/migration/pbs-state.c b/migration/pbs-state.c
66 new file mode 100644
67 index 0000000000..29f2b3860d
68 --- /dev/null
69 +++ b/migration/pbs-state.c
70 @@ -0,0 +1,106 @@
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 +
82 +typedef struct PBSState {
83 + bool active;
84 +} PBSState;
85 +
86 +/* state is accessed via this static variable directly, 'opaque' is NULL */
87 +static PBSState pbs_state;
88 +
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 */
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);
129 + pbs_state.active = false;
130 + return 0;
131 +}
132 +
133 +static bool pbs_state_is_active(void *opaque)
134 +{
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 */
138 + return pbs_state.active;
139 +}
140 +
141 +static bool pbs_state_is_active_iterate(void *opaque)
142 +{
143 + /* we don't iterate, everything is sent in save_setup */
144 + return pbs_state_is_active(opaque);
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 +
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 +
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,
167 + .save_cleanup = pbs_state_save_cleanup,
168 +};
169 +
170 +void pbs_state_mig_init(void)
171 +{
172 + pbs_state.active = true;
173 + register_savevm_live("pbs-state", 0, 1,
174 + &savevm_pbs_state_handlers,
175 + NULL);
176 +}
177 diff --git a/pve-backup.c b/pve-backup.c
178 index 88268bb586..fa9c6c4493 100644
179 --- a/pve-backup.c
180 +++ b/pve-backup.c
181 @@ -1128,6 +1128,7 @@ ProxmoxSupportStatus *qmp_query_proxmox_support(Error **errp)
182 ret->pbs_library_version = g_strdup(proxmox_backup_qemu_version());
183 ret->pbs_dirty_bitmap = true;
184 ret->pbs_dirty_bitmap_savevm = true;
185 + ret->pbs_dirty_bitmap_migration = true;
186 ret->query_bitmap_info = true;
187 return ret;
188 }
189 diff --git a/qapi/block-core.json b/qapi/block-core.json
190 index bf559c6d52..24f30260c8 100644
191 --- a/qapi/block-core.json
192 +++ b/qapi/block-core.json
193 @@ -879,6 +879,11 @@
194 # @pbs-dirty-bitmap-savevm: True if 'dirty-bitmaps' migration capability can
195 # safely be set for savevm-async.
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 +#
202 # @pbs-library-version: Running version of libproxmox-backup-qemu0 library.
203 #
204 ##
205 @@ -886,6 +891,7 @@
206 'data': { 'pbs-dirty-bitmap': 'bool',
207 'query-bitmap-info': 'bool',
208 'pbs-dirty-bitmap-savevm': 'bool',
209 + 'pbs-dirty-bitmap-migration': 'bool',
210 'pbs-library-version': 'str' } }
211
212 ##