]>
Commit | Line | Data |
---|---|---|
b35ebdf0 VSO |
1 | /* |
2 | * Block dirty bitmap postcopy migration | |
3 | * | |
4 | * Copyright IBM, Corp. 2009 | |
5 | * Copyright (c) 2016-2017 Virtuozzo International GmbH. All rights reserved. | |
6 | * | |
7 | * Authors: | |
8 | * Liran Schour <lirans@il.ibm.com> | |
9 | * Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> | |
10 | * | |
11 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
12 | * the COPYING file in the top-level directory. | |
13 | * This file is derived from migration/block.c, so it's author and IBM copyright | |
14 | * are here, although content is quite different. | |
15 | * | |
16 | * Contributions after 2012-01-13 are licensed under the terms of the | |
17 | * GNU GPL, version 2 or (at your option) any later version. | |
18 | * | |
19 | * *** | |
20 | * | |
21 | * Here postcopy migration of dirty bitmaps is realized. Only QMP-addressable | |
22 | * bitmaps are migrated. | |
23 | * | |
24 | * Bitmap migration implies creating bitmap with the same name and granularity | |
25 | * in destination QEMU. If the bitmap with the same name (for the same node) | |
26 | * already exists on destination an error will be generated. | |
27 | * | |
28 | * format of migration: | |
29 | * | |
30 | * # Header (shared for different chunk types) | |
31 | * 1, 2 or 4 bytes: flags (see qemu_{put,put}_flags) | |
31e4c354 HR |
32 | * [ 1 byte: node alias size ] \ flags & DEVICE_NAME |
33 | * [ n bytes: node alias ] / | |
34 | * [ 1 byte: bitmap alias size ] \ flags & BITMAP_NAME | |
35 | * [ n bytes: bitmap alias ] / | |
b35ebdf0 VSO |
36 | * |
37 | * # Start of bitmap migration (flags & START) | |
38 | * header | |
39 | * be64: granularity | |
40 | * 1 byte: bitmap flags (corresponds to BdrvDirtyBitmap) | |
41 | * bit 0 - bitmap is enabled | |
42 | * bit 1 - bitmap is persistent | |
43 | * bit 2 - bitmap is autoloading | |
44 | * bits 3-7 - reserved, must be zero | |
45 | * | |
46 | * # Complete of bitmap migration (flags & COMPLETE) | |
47 | * header | |
48 | * | |
49 | * # Data chunk of bitmap migration | |
50 | * header | |
51 | * be64: start sector | |
52 | * be32: number of sectors | |
53 | * [ be64: buffer size ] \ ! (flags & ZEROES) | |
54 | * [ n bytes: buffer ] / | |
55 | * | |
56 | * The last chunk in stream should contain flags & EOS. The chunk may skip | |
57 | * device and/or bitmap names, assuming them to be the same with the previous | |
58 | * chunk. | |
59 | */ | |
60 | ||
61 | #include "qemu/osdep.h" | |
62 | #include "block/block.h" | |
63 | #include "block/block_int.h" | |
e2c1c34f | 64 | #include "block/dirty-bitmap.h" |
b35ebdf0 | 65 | #include "sysemu/block-backend.h" |
54d31236 | 66 | #include "sysemu/runstate.h" |
b35ebdf0 VSO |
67 | #include "qemu/main-loop.h" |
68 | #include "qemu/error-report.h" | |
69 | #include "migration/misc.h" | |
70 | #include "migration/migration.h" | |
53d37d36 | 71 | #include "qemu-file.h" |
b35ebdf0 VSO |
72 | #include "migration/vmstate.h" |
73 | #include "migration/register.h" | |
74 | #include "qemu/hbitmap.h" | |
b35ebdf0 | 75 | #include "qemu/cutils.h" |
31e4c354 | 76 | #include "qemu/id.h" |
b35ebdf0 | 77 | #include "qapi/error.h" |
31e4c354 | 78 | #include "qapi/qapi-commands-migration.h" |
0d1e450c PK |
79 | #include "qapi/qapi-visit-migration.h" |
80 | #include "qapi/clone-visitor.h" | |
b35ebdf0 | 81 | #include "trace.h" |
1f0776f1 | 82 | #include "options.h" |
b35ebdf0 VSO |
83 | |
84 | #define CHUNK_SIZE (1 << 10) | |
85 | ||
86 | /* Flags occupy one, two or four bytes (Big Endian). The size is determined as | |
87 | * follows: | |
88 | * in first (most significant) byte bit 8 is clear --> one byte | |
89 | * in first byte bit 8 is set --> two or four bytes, depending on second | |
90 | * byte: | |
91 | * | in second byte bit 8 is clear --> two bytes | |
92 | * | in second byte bit 8 is set --> four bytes | |
93 | */ | |
94 | #define DIRTY_BITMAP_MIG_FLAG_EOS 0x01 | |
95 | #define DIRTY_BITMAP_MIG_FLAG_ZEROES 0x02 | |
96 | #define DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME 0x04 | |
97 | #define DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME 0x08 | |
98 | #define DIRTY_BITMAP_MIG_FLAG_START 0x10 | |
99 | #define DIRTY_BITMAP_MIG_FLAG_COMPLETE 0x20 | |
100 | #define DIRTY_BITMAP_MIG_FLAG_BITS 0x40 | |
101 | ||
102 | #define DIRTY_BITMAP_MIG_EXTRA_FLAGS 0x80 | |
103 | ||
104 | #define DIRTY_BITMAP_MIG_START_FLAG_ENABLED 0x01 | |
105 | #define DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT 0x02 | |
37931e00 | 106 | /* 0x04 was "AUTOLOAD" flags on older versions, now it is ignored */ |
b35ebdf0 VSO |
107 | #define DIRTY_BITMAP_MIG_START_FLAG_RESERVED_MASK 0xf8 |
108 | ||
fbbc6b14 VSO |
109 | /* State of one bitmap during save process */ |
110 | typedef struct SaveBitmapState { | |
b35ebdf0 VSO |
111 | /* Written during setup phase. */ |
112 | BlockDriverState *bs; | |
31e4c354 HR |
113 | char *node_alias; |
114 | char *bitmap_alias; | |
b35ebdf0 VSO |
115 | BdrvDirtyBitmap *bitmap; |
116 | uint64_t total_sectors; | |
117 | uint64_t sectors_per_chunk; | |
fbbc6b14 | 118 | QSIMPLEQ_ENTRY(SaveBitmapState) entry; |
b35ebdf0 VSO |
119 | uint8_t flags; |
120 | ||
121 | /* For bulk phase. */ | |
122 | bool bulk_completed; | |
123 | uint64_t cur_sector; | |
fbbc6b14 | 124 | } SaveBitmapState; |
b35ebdf0 | 125 | |
fbbc6b14 VSO |
126 | /* State of the dirty bitmap migration (DBM) during save process */ |
127 | typedef struct DBMSaveState { | |
128 | QSIMPLEQ_HEAD(, SaveBitmapState) dbms_list; | |
b35ebdf0 VSO |
129 | |
130 | bool bulk_completed; | |
131 | bool no_bitmaps; | |
132 | ||
133 | /* for send_bitmap_bits() */ | |
134 | BlockDriverState *prev_bs; | |
135 | BdrvDirtyBitmap *prev_bitmap; | |
fbbc6b14 | 136 | } DBMSaveState; |
b35ebdf0 | 137 | |
3b52726e VSO |
138 | typedef struct LoadBitmapState { |
139 | BlockDriverState *bs; | |
140 | BdrvDirtyBitmap *bitmap; | |
141 | bool migrated; | |
0a47190a | 142 | bool enabled; |
3b52726e VSO |
143 | } LoadBitmapState; |
144 | ||
fbbc6b14 VSO |
145 | /* State of the dirty bitmap migration (DBM) during load process */ |
146 | typedef struct DBMLoadState { | |
b35ebdf0 | 147 | uint32_t flags; |
31e4c354 HR |
148 | char node_alias[256]; |
149 | char bitmap_alias[256]; | |
150 | char bitmap_name[BDRV_BITMAP_MAX_NAME_SIZE + 1]; | |
b35ebdf0 VSO |
151 | BlockDriverState *bs; |
152 | BdrvDirtyBitmap *bitmap; | |
3b52726e | 153 | |
0a47190a | 154 | bool before_vm_start_handled; /* set in dirty_bitmap_mig_before_vm_start */ |
6e9f21a2 | 155 | BitmapMigrationBitmapAlias *bmap_inner; |
0a47190a | 156 | |
b91f33b8 VSO |
157 | /* |
158 | * cancelled | |
159 | * Incoming migration is cancelled for some reason. That means that we | |
160 | * still should read our chunks from migration stream, to not affect other | |
161 | * migration objects (like RAM), but just ignore them and do not touch any | |
162 | * bitmaps or nodes. | |
163 | */ | |
164 | bool cancelled; | |
165 | ||
0a47190a VSO |
166 | GSList *bitmaps; |
167 | QemuMutex lock; /* protect bitmaps */ | |
fbbc6b14 | 168 | } DBMLoadState; |
b35ebdf0 | 169 | |
3b52726e VSO |
170 | typedef struct DBMState { |
171 | DBMSaveState save; | |
172 | DBMLoadState load; | |
173 | } DBMState; | |
b35ebdf0 | 174 | |
3b52726e | 175 | static DBMState dbm_state; |
b35ebdf0 | 176 | |
31e4c354 HR |
177 | /* For hash tables that map node/bitmap names to aliases */ |
178 | typedef struct AliasMapInnerNode { | |
179 | char *string; | |
180 | GHashTable *subtree; | |
181 | } AliasMapInnerNode; | |
182 | ||
183 | static void free_alias_map_inner_node(void *amin_ptr) | |
184 | { | |
185 | AliasMapInnerNode *amin = amin_ptr; | |
186 | ||
187 | g_free(amin->string); | |
188 | g_hash_table_unref(amin->subtree); | |
189 | g_free(amin); | |
190 | } | |
191 | ||
192 | /** | |
193 | * Construct an alias map based on the given QMP structure. | |
194 | * | |
195 | * (Note that we cannot store such maps in the MigrationParameters | |
196 | * object, because that struct is defined by the QAPI schema, which | |
197 | * makes it basically impossible to have dicts with arbitrary keys. | |
198 | * Therefore, we instead have to construct these maps when migration | |
199 | * starts.) | |
200 | * | |
201 | * @bbm is the block_bitmap_mapping from the migration parameters. | |
202 | * | |
203 | * If @name_to_alias is true, the returned hash table will map node | |
204 | * and bitmap names to their respective aliases (for outgoing | |
205 | * migration). | |
206 | * | |
207 | * If @name_to_alias is false, the returned hash table will map node | |
208 | * and bitmap aliases to their respective names (for incoming | |
209 | * migration). | |
210 | * | |
211 | * The hash table maps node names/aliases to AliasMapInnerNode | |
212 | * objects, whose .string is the respective node alias/name, and whose | |
213 | * .subtree table maps bitmap names/aliases to the respective bitmap | |
214 | * alias/name. | |
215 | */ | |
216 | static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm, | |
217 | bool name_to_alias, | |
218 | Error **errp) | |
219 | { | |
220 | GHashTable *alias_map; | |
221 | size_t max_node_name_len = sizeof_field(BlockDriverState, node_name) - 1; | |
222 | ||
223 | alias_map = g_hash_table_new_full(g_str_hash, g_str_equal, | |
224 | g_free, free_alias_map_inner_node); | |
225 | ||
226 | for (; bbm; bbm = bbm->next) { | |
227 | const BitmapMigrationNodeAlias *bmna = bbm->value; | |
228 | const BitmapMigrationBitmapAliasList *bmbal; | |
229 | AliasMapInnerNode *amin; | |
230 | GHashTable *bitmaps_map; | |
231 | const char *node_map_from, *node_map_to; | |
0d1e450c | 232 | GDestroyNotify gdn; |
31e4c354 HR |
233 | |
234 | if (!id_wellformed(bmna->alias)) { | |
235 | error_setg(errp, "The node alias '%s' is not well-formed", | |
236 | bmna->alias); | |
237 | goto fail; | |
238 | } | |
239 | ||
240 | if (strlen(bmna->alias) > UINT8_MAX) { | |
241 | error_setg(errp, "The node alias '%s' is longer than %u bytes", | |
242 | bmna->alias, UINT8_MAX); | |
243 | goto fail; | |
244 | } | |
245 | ||
246 | if (strlen(bmna->node_name) > max_node_name_len) { | |
247 | error_setg(errp, "The node name '%s' is longer than %zu bytes", | |
248 | bmna->node_name, max_node_name_len); | |
249 | goto fail; | |
250 | } | |
251 | ||
252 | if (name_to_alias) { | |
253 | if (g_hash_table_contains(alias_map, bmna->node_name)) { | |
254 | error_setg(errp, "The node name '%s' is mapped twice", | |
255 | bmna->node_name); | |
256 | goto fail; | |
257 | } | |
258 | ||
259 | node_map_from = bmna->node_name; | |
260 | node_map_to = bmna->alias; | |
261 | } else { | |
262 | if (g_hash_table_contains(alias_map, bmna->alias)) { | |
263 | error_setg(errp, "The node alias '%s' is used twice", | |
264 | bmna->alias); | |
265 | goto fail; | |
266 | } | |
267 | ||
268 | node_map_from = bmna->alias; | |
269 | node_map_to = bmna->node_name; | |
270 | } | |
271 | ||
0d1e450c PK |
272 | gdn = (GDestroyNotify) qapi_free_BitmapMigrationBitmapAlias; |
273 | bitmaps_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
274 | gdn); | |
31e4c354 HR |
275 | |
276 | amin = g_new(AliasMapInnerNode, 1); | |
277 | *amin = (AliasMapInnerNode){ | |
278 | .string = g_strdup(node_map_to), | |
279 | .subtree = bitmaps_map, | |
280 | }; | |
281 | ||
282 | g_hash_table_insert(alias_map, g_strdup(node_map_from), amin); | |
283 | ||
284 | for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) { | |
285 | const BitmapMigrationBitmapAlias *bmba = bmbal->value; | |
0d1e450c | 286 | const char *bmap_map_from; |
31e4c354 HR |
287 | |
288 | if (strlen(bmba->alias) > UINT8_MAX) { | |
289 | error_setg(errp, | |
290 | "The bitmap alias '%s' is longer than %u bytes", | |
291 | bmba->alias, UINT8_MAX); | |
292 | goto fail; | |
293 | } | |
294 | ||
295 | if (strlen(bmba->name) > BDRV_BITMAP_MAX_NAME_SIZE) { | |
296 | error_setg(errp, "The bitmap name '%s' is longer than %d bytes", | |
297 | bmba->name, BDRV_BITMAP_MAX_NAME_SIZE); | |
298 | goto fail; | |
299 | } | |
300 | ||
301 | if (name_to_alias) { | |
302 | bmap_map_from = bmba->name; | |
31e4c354 HR |
303 | |
304 | if (g_hash_table_contains(bitmaps_map, bmba->name)) { | |
305 | error_setg(errp, "The bitmap '%s'/'%s' is mapped twice", | |
306 | bmna->node_name, bmba->name); | |
307 | goto fail; | |
308 | } | |
309 | } else { | |
310 | bmap_map_from = bmba->alias; | |
31e4c354 HR |
311 | |
312 | if (g_hash_table_contains(bitmaps_map, bmba->alias)) { | |
313 | error_setg(errp, "The bitmap alias '%s'/'%s' is used twice", | |
314 | bmna->alias, bmba->alias); | |
315 | goto fail; | |
316 | } | |
317 | } | |
318 | ||
0d1e450c PK |
319 | g_hash_table_insert(bitmaps_map, g_strdup(bmap_map_from), |
320 | QAPI_CLONE(BitmapMigrationBitmapAlias, bmba)); | |
31e4c354 HR |
321 | } |
322 | } | |
323 | ||
324 | return alias_map; | |
325 | ||
326 | fail: | |
327 | g_hash_table_destroy(alias_map); | |
328 | return NULL; | |
329 | } | |
330 | ||
331 | /** | |
332 | * Run construct_alias_map() in both directions to check whether @bbm | |
333 | * is valid. | |
334 | * (This function is to be used by migration/migration.c to validate | |
335 | * the user-specified block-bitmap-mapping migration parameter.) | |
336 | * | |
337 | * Returns true if and only if the mapping is valid. | |
338 | */ | |
339 | bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm, | |
340 | Error **errp) | |
341 | { | |
342 | GHashTable *alias_map; | |
343 | ||
344 | alias_map = construct_alias_map(bbm, true, errp); | |
345 | if (!alias_map) { | |
346 | return false; | |
347 | } | |
348 | g_hash_table_destroy(alias_map); | |
349 | ||
350 | alias_map = construct_alias_map(bbm, false, errp); | |
351 | if (!alias_map) { | |
352 | return false; | |
353 | } | |
354 | g_hash_table_destroy(alias_map); | |
355 | ||
356 | return true; | |
357 | } | |
358 | ||
b35ebdf0 VSO |
359 | static uint32_t qemu_get_bitmap_flags(QEMUFile *f) |
360 | { | |
361 | uint8_t flags = qemu_get_byte(f); | |
362 | if (flags & DIRTY_BITMAP_MIG_EXTRA_FLAGS) { | |
363 | flags = flags << 8 | qemu_get_byte(f); | |
364 | if (flags & DIRTY_BITMAP_MIG_EXTRA_FLAGS) { | |
365 | flags = flags << 16 | qemu_get_be16(f); | |
366 | } | |
367 | } | |
368 | ||
369 | return flags; | |
370 | } | |
371 | ||
372 | static void qemu_put_bitmap_flags(QEMUFile *f, uint32_t flags) | |
373 | { | |
37931e00 | 374 | /* The code currently does not send flags as more than one byte */ |
b35ebdf0 VSO |
375 | assert(!(flags & (0xffffff00 | DIRTY_BITMAP_MIG_EXTRA_FLAGS))); |
376 | ||
377 | qemu_put_byte(f, flags); | |
378 | } | |
379 | ||
3b52726e VSO |
380 | static void send_bitmap_header(QEMUFile *f, DBMSaveState *s, |
381 | SaveBitmapState *dbms, uint32_t additional_flags) | |
b35ebdf0 VSO |
382 | { |
383 | BlockDriverState *bs = dbms->bs; | |
384 | BdrvDirtyBitmap *bitmap = dbms->bitmap; | |
385 | uint32_t flags = additional_flags; | |
386 | trace_send_bitmap_header_enter(); | |
387 | ||
3b52726e VSO |
388 | if (bs != s->prev_bs) { |
389 | s->prev_bs = bs; | |
b35ebdf0 VSO |
390 | flags |= DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME; |
391 | } | |
392 | ||
3b52726e VSO |
393 | if (bitmap != s->prev_bitmap) { |
394 | s->prev_bitmap = bitmap; | |
b35ebdf0 VSO |
395 | flags |= DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME; |
396 | } | |
397 | ||
398 | qemu_put_bitmap_flags(f, flags); | |
399 | ||
400 | if (flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) { | |
31e4c354 | 401 | qemu_put_counted_string(f, dbms->node_alias); |
b35ebdf0 VSO |
402 | } |
403 | ||
404 | if (flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) { | |
31e4c354 | 405 | qemu_put_counted_string(f, dbms->bitmap_alias); |
b35ebdf0 VSO |
406 | } |
407 | } | |
408 | ||
3b52726e VSO |
409 | static void send_bitmap_start(QEMUFile *f, DBMSaveState *s, |
410 | SaveBitmapState *dbms) | |
b35ebdf0 | 411 | { |
3b52726e | 412 | send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_START); |
b35ebdf0 VSO |
413 | qemu_put_be32(f, bdrv_dirty_bitmap_granularity(dbms->bitmap)); |
414 | qemu_put_byte(f, dbms->flags); | |
415 | } | |
416 | ||
3b52726e VSO |
417 | static void send_bitmap_complete(QEMUFile *f, DBMSaveState *s, |
418 | SaveBitmapState *dbms) | |
b35ebdf0 | 419 | { |
3b52726e | 420 | send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_COMPLETE); |
b35ebdf0 VSO |
421 | } |
422 | ||
3b52726e VSO |
423 | static void send_bitmap_bits(QEMUFile *f, DBMSaveState *s, |
424 | SaveBitmapState *dbms, | |
b35ebdf0 VSO |
425 | uint64_t start_sector, uint32_t nr_sectors) |
426 | { | |
427 | /* align for buffer_is_zero() */ | |
428 | uint64_t align = 4 * sizeof(long); | |
429 | uint64_t unaligned_size = | |
430 | bdrv_dirty_bitmap_serialization_size( | |
431 | dbms->bitmap, start_sector << BDRV_SECTOR_BITS, | |
432 | (uint64_t)nr_sectors << BDRV_SECTOR_BITS); | |
433 | uint64_t buf_size = QEMU_ALIGN_UP(unaligned_size, align); | |
434 | uint8_t *buf = g_malloc0(buf_size); | |
435 | uint32_t flags = DIRTY_BITMAP_MIG_FLAG_BITS; | |
436 | ||
437 | bdrv_dirty_bitmap_serialize_part( | |
438 | dbms->bitmap, buf, start_sector << BDRV_SECTOR_BITS, | |
439 | (uint64_t)nr_sectors << BDRV_SECTOR_BITS); | |
440 | ||
441 | if (buffer_is_zero(buf, buf_size)) { | |
442 | g_free(buf); | |
443 | buf = NULL; | |
444 | flags |= DIRTY_BITMAP_MIG_FLAG_ZEROES; | |
445 | } | |
446 | ||
447 | trace_send_bitmap_bits(flags, start_sector, nr_sectors, buf_size); | |
448 | ||
3b52726e | 449 | send_bitmap_header(f, s, dbms, flags); |
b35ebdf0 VSO |
450 | |
451 | qemu_put_be64(f, start_sector); | |
452 | qemu_put_be32(f, nr_sectors); | |
453 | ||
454 | /* if a block is zero we need to flush here since the network | |
455 | * bandwidth is now a lot higher than the storage device bandwidth. | |
456 | * thus if we queue zero blocks we slow down the migration. */ | |
457 | if (flags & DIRTY_BITMAP_MIG_FLAG_ZEROES) { | |
458 | qemu_fflush(f); | |
459 | } else { | |
460 | qemu_put_be64(f, buf_size); | |
461 | qemu_put_buffer(f, buf, buf_size); | |
462 | } | |
463 | ||
464 | g_free(buf); | |
465 | } | |
466 | ||
a4a411fb | 467 | /* Called with the BQL taken. */ |
3b52726e | 468 | static void dirty_bitmap_do_save_cleanup(DBMSaveState *s) |
b35ebdf0 | 469 | { |
fbbc6b14 | 470 | SaveBitmapState *dbms; |
b35ebdf0 | 471 | |
3b52726e VSO |
472 | while ((dbms = QSIMPLEQ_FIRST(&s->dbms_list)) != NULL) { |
473 | QSIMPLEQ_REMOVE_HEAD(&s->dbms_list, entry); | |
27a1b301 | 474 | bdrv_dirty_bitmap_set_busy(dbms->bitmap, false); |
b35ebdf0 | 475 | bdrv_unref(dbms->bs); |
31e4c354 HR |
476 | g_free(dbms->node_alias); |
477 | g_free(dbms->bitmap_alias); | |
b35ebdf0 VSO |
478 | g_free(dbms); |
479 | } | |
480 | } | |
481 | ||
a4a411fb | 482 | /* Called with the BQL taken. */ |
3b52726e | 483 | static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, |
31e4c354 | 484 | const char *bs_name, GHashTable *alias_map) |
b35ebdf0 | 485 | { |
b35ebdf0 | 486 | BdrvDirtyBitmap *bitmap; |
fbbc6b14 | 487 | SaveBitmapState *dbms; |
31e4c354 HR |
488 | GHashTable *bitmap_aliases; |
489 | const char *node_alias, *bitmap_name, *bitmap_alias; | |
3ae96d66 | 490 | Error *local_err = NULL; |
b35ebdf0 | 491 | |
31e4c354 HR |
492 | /* When an alias map is given, @bs_name must be @bs's node name */ |
493 | assert(!alias_map || !strcmp(bs_name, bdrv_get_node_name(bs))); | |
494 | ||
7cb01519 VSO |
495 | FOR_EACH_DIRTY_BITMAP(bs, bitmap) { |
496 | if (bdrv_dirty_bitmap_name(bitmap)) { | |
497 | break; | |
498 | } | |
499 | } | |
82640edb VSO |
500 | if (!bitmap) { |
501 | return 0; | |
502 | } | |
503 | ||
31e4c354 HR |
504 | bitmap_name = bdrv_dirty_bitmap_name(bitmap); |
505 | ||
82640edb VSO |
506 | if (!bs_name || strcmp(bs_name, "") == 0) { |
507 | error_report("Bitmap '%s' in unnamed node can't be migrated", | |
31e4c354 | 508 | bitmap_name); |
82640edb VSO |
509 | return -1; |
510 | } | |
511 | ||
31e4c354 HR |
512 | if (alias_map) { |
513 | const AliasMapInnerNode *amin = g_hash_table_lookup(alias_map, bs_name); | |
514 | ||
515 | if (!amin) { | |
516 | /* Skip bitmaps on nodes with no alias */ | |
517 | return 0; | |
518 | } | |
519 | ||
520 | node_alias = amin->string; | |
521 | bitmap_aliases = amin->subtree; | |
522 | } else { | |
523 | node_alias = bs_name; | |
524 | bitmap_aliases = NULL; | |
525 | } | |
526 | ||
527 | if (node_alias[0] == '#') { | |
4ff5cc12 VSO |
528 | error_report("Bitmap '%s' in a node with auto-generated " |
529 | "name '%s' can't be migrated", | |
31e4c354 | 530 | bitmap_name, node_alias); |
4ff5cc12 VSO |
531 | return -1; |
532 | } | |
533 | ||
38908bbc | 534 | FOR_EACH_DIRTY_BITMAP(bs, bitmap) { |
6e9f21a2 | 535 | BitmapMigrationBitmapAliasTransform *bitmap_transform = NULL; |
31e4c354 HR |
536 | bitmap_name = bdrv_dirty_bitmap_name(bitmap); |
537 | if (!bitmap_name) { | |
38908bbc VSO |
538 | continue; |
539 | } | |
540 | ||
38908bbc VSO |
541 | if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) { |
542 | error_report_err(local_err); | |
543 | return -1; | |
544 | } | |
545 | ||
31e4c354 | 546 | if (bitmap_aliases) { |
0d1e450c PK |
547 | BitmapMigrationBitmapAlias *bmap_inner; |
548 | ||
549 | bmap_inner = g_hash_table_lookup(bitmap_aliases, bitmap_name); | |
550 | if (!bmap_inner) { | |
31e4c354 HR |
551 | /* Skip bitmaps with no alias */ |
552 | continue; | |
553 | } | |
0d1e450c PK |
554 | |
555 | bitmap_alias = bmap_inner->alias; | |
720a252c | 556 | if (bmap_inner->transform) { |
6e9f21a2 PK |
557 | bitmap_transform = bmap_inner->transform; |
558 | } | |
31e4c354 HR |
559 | } else { |
560 | if (strlen(bitmap_name) > UINT8_MAX) { | |
561 | error_report("Cannot migrate bitmap '%s' on node '%s': " | |
562 | "Name is longer than %u bytes", | |
563 | bitmap_name, bs_name, UINT8_MAX); | |
564 | return -1; | |
565 | } | |
566 | bitmap_alias = bitmap_name; | |
567 | } | |
568 | ||
38908bbc VSO |
569 | bdrv_ref(bs); |
570 | bdrv_dirty_bitmap_set_busy(bitmap, true); | |
571 | ||
fbbc6b14 | 572 | dbms = g_new0(SaveBitmapState, 1); |
38908bbc | 573 | dbms->bs = bs; |
31e4c354 HR |
574 | dbms->node_alias = g_strdup(node_alias); |
575 | dbms->bitmap_alias = g_strdup(bitmap_alias); | |
38908bbc VSO |
576 | dbms->bitmap = bitmap; |
577 | dbms->total_sectors = bdrv_nb_sectors(bs); | |
ed7b70c2 SR |
578 | dbms->sectors_per_chunk = CHUNK_SIZE * 8LLU * |
579 | (bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS); | |
580 | assert(dbms->sectors_per_chunk != 0); | |
38908bbc VSO |
581 | if (bdrv_dirty_bitmap_enabled(bitmap)) { |
582 | dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED; | |
583 | } | |
6e9f21a2 PK |
584 | if (bitmap_transform && |
585 | bitmap_transform->has_persistent) { | |
586 | if (bitmap_transform->persistent) { | |
587 | dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; | |
588 | } | |
589 | } else { | |
590 | if (bdrv_dirty_bitmap_get_persistence(bitmap)) { | |
591 | dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; | |
592 | } | |
38908bbc VSO |
593 | } |
594 | ||
3b52726e | 595 | QSIMPLEQ_INSERT_TAIL(&s->dbms_list, dbms, entry); |
38908bbc VSO |
596 | } |
597 | ||
598 | return 0; | |
599 | } | |
600 | ||
a4a411fb | 601 | /* Called with the BQL taken. */ |
3b52726e | 602 | static int init_dirty_bitmap_migration(DBMSaveState *s) |
38908bbc VSO |
603 | { |
604 | BlockDriverState *bs; | |
fbbc6b14 | 605 | SaveBitmapState *dbms; |
107cfb72 VSO |
606 | GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL); |
607 | BlockBackend *blk; | |
31e4c354 HR |
608 | GHashTable *alias_map = NULL; |
609 | ||
a4a411fb | 610 | /* Runs in the migration thread, but holds the BQL */ |
f5a3a270 KW |
611 | GLOBAL_STATE_CODE(); |
612 | GRAPH_RDLOCK_GUARD_MAINLOOP(); | |
613 | ||
3cba22c9 JQ |
614 | if (migrate_has_block_bitmap_mapping()) { |
615 | alias_map = construct_alias_map(migrate_block_bitmap_mapping(), true, | |
31e4c354 HR |
616 | &error_abort); |
617 | } | |
38908bbc | 618 | |
3b52726e VSO |
619 | s->bulk_completed = false; |
620 | s->prev_bs = NULL; | |
621 | s->prev_bitmap = NULL; | |
622 | s->no_bitmaps = false; | |
b35ebdf0 | 623 | |
31e4c354 HR |
624 | if (!alias_map) { |
625 | /* | |
626 | * Use blockdevice name for direct (or filtered) children of named block | |
627 | * backends. | |
628 | */ | |
629 | for (blk = blk_next(NULL); blk; blk = blk_next(blk)) { | |
630 | const char *name = blk_name(blk); | |
107cfb72 | 631 | |
31e4c354 HR |
632 | if (!name || strcmp(name, "") == 0) { |
633 | continue; | |
634 | } | |
107cfb72 | 635 | |
31e4c354 HR |
636 | bs = blk_bs(blk); |
637 | ||
638 | /* Skip filters without bitmaps */ | |
639 | while (bs && bs->drv && bs->drv->is_filter && | |
640 | !bdrv_has_named_bitmaps(bs)) | |
641 | { | |
93393e69 | 642 | bs = bdrv_filter_bs(bs); |
107cfb72 | 643 | } |
107cfb72 | 644 | |
31e4c354 HR |
645 | if (bs && bs->drv && !bs->drv->is_filter) { |
646 | if (add_bitmaps_to_list(s, bs, name, NULL)) { | |
647 | goto fail; | |
648 | } | |
649 | g_hash_table_add(handled_by_blk, bs); | |
107cfb72 | 650 | } |
107cfb72 VSO |
651 | } |
652 | } | |
653 | ||
592203e7 | 654 | for (bs = bdrv_next_all_states(NULL); bs; bs = bdrv_next_all_states(bs)) { |
107cfb72 VSO |
655 | if (g_hash_table_contains(handled_by_blk, bs)) { |
656 | continue; | |
657 | } | |
658 | ||
31e4c354 | 659 | if (add_bitmaps_to_list(s, bs, bdrv_get_node_name(bs), alias_map)) { |
38908bbc | 660 | goto fail; |
b35ebdf0 VSO |
661 | } |
662 | } | |
663 | ||
9c98f145 | 664 | /* unset migration flags here, to not roll back it */ |
3b52726e | 665 | QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) { |
c4e4b0fa | 666 | bdrv_dirty_bitmap_skip_store(dbms->bitmap, true); |
b35ebdf0 VSO |
667 | } |
668 | ||
3b52726e VSO |
669 | if (QSIMPLEQ_EMPTY(&s->dbms_list)) { |
670 | s->no_bitmaps = true; | |
b35ebdf0 VSO |
671 | } |
672 | ||
107cfb72 | 673 | g_hash_table_destroy(handled_by_blk); |
31e4c354 HR |
674 | if (alias_map) { |
675 | g_hash_table_destroy(alias_map); | |
676 | } | |
107cfb72 | 677 | |
b35ebdf0 VSO |
678 | return 0; |
679 | ||
680 | fail: | |
107cfb72 | 681 | g_hash_table_destroy(handled_by_blk); |
31e4c354 HR |
682 | if (alias_map) { |
683 | g_hash_table_destroy(alias_map); | |
684 | } | |
3b52726e | 685 | dirty_bitmap_do_save_cleanup(s); |
b35ebdf0 VSO |
686 | |
687 | return -1; | |
688 | } | |
689 | ||
690 | /* Called with no lock taken. */ | |
3b52726e VSO |
691 | static void bulk_phase_send_chunk(QEMUFile *f, DBMSaveState *s, |
692 | SaveBitmapState *dbms) | |
b35ebdf0 VSO |
693 | { |
694 | uint32_t nr_sectors = MIN(dbms->total_sectors - dbms->cur_sector, | |
695 | dbms->sectors_per_chunk); | |
696 | ||
3b52726e | 697 | send_bitmap_bits(f, s, dbms, dbms->cur_sector, nr_sectors); |
b35ebdf0 VSO |
698 | |
699 | dbms->cur_sector += nr_sectors; | |
700 | if (dbms->cur_sector >= dbms->total_sectors) { | |
701 | dbms->bulk_completed = true; | |
702 | } | |
703 | } | |
704 | ||
705 | /* Called with no lock taken. */ | |
3b52726e | 706 | static void bulk_phase(QEMUFile *f, DBMSaveState *s, bool limit) |
b35ebdf0 | 707 | { |
fbbc6b14 | 708 | SaveBitmapState *dbms; |
b35ebdf0 | 709 | |
3b52726e | 710 | QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) { |
b35ebdf0 | 711 | while (!dbms->bulk_completed) { |
3b52726e | 712 | bulk_phase_send_chunk(f, s, dbms); |
e1fde0e0 | 713 | if (limit && migration_rate_exceeded(f)) { |
b35ebdf0 VSO |
714 | return; |
715 | } | |
716 | } | |
717 | } | |
718 | ||
3b52726e | 719 | s->bulk_completed = true; |
b35ebdf0 VSO |
720 | } |
721 | ||
722 | /* for SaveVMHandlers */ | |
723 | static void dirty_bitmap_save_cleanup(void *opaque) | |
724 | { | |
3b52726e VSO |
725 | DBMSaveState *s = &((DBMState *)opaque)->save; |
726 | ||
727 | dirty_bitmap_do_save_cleanup(s); | |
b35ebdf0 VSO |
728 | } |
729 | ||
730 | static int dirty_bitmap_save_iterate(QEMUFile *f, void *opaque) | |
731 | { | |
3b52726e VSO |
732 | DBMSaveState *s = &((DBMState *)opaque)->save; |
733 | ||
b35ebdf0 VSO |
734 | trace_dirty_bitmap_save_iterate(migration_in_postcopy()); |
735 | ||
3b52726e VSO |
736 | if (migration_in_postcopy() && !s->bulk_completed) { |
737 | bulk_phase(f, s, true); | |
b35ebdf0 VSO |
738 | } |
739 | ||
740 | qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS); | |
741 | ||
3b52726e | 742 | return s->bulk_completed; |
b35ebdf0 VSO |
743 | } |
744 | ||
a4a411fb | 745 | /* Called with the BQL taken. */ |
b35ebdf0 VSO |
746 | |
747 | static int dirty_bitmap_save_complete(QEMUFile *f, void *opaque) | |
748 | { | |
3b52726e | 749 | DBMSaveState *s = &((DBMState *)opaque)->save; |
fbbc6b14 | 750 | SaveBitmapState *dbms; |
b35ebdf0 VSO |
751 | trace_dirty_bitmap_save_complete_enter(); |
752 | ||
3b52726e VSO |
753 | if (!s->bulk_completed) { |
754 | bulk_phase(f, s, false); | |
b35ebdf0 VSO |
755 | } |
756 | ||
3b52726e VSO |
757 | QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) { |
758 | send_bitmap_complete(f, s, dbms); | |
b35ebdf0 VSO |
759 | } |
760 | ||
761 | qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS); | |
762 | ||
763 | trace_dirty_bitmap_save_complete_finish(); | |
764 | ||
3b52726e | 765 | dirty_bitmap_save_cleanup(opaque); |
b35ebdf0 VSO |
766 | return 0; |
767 | } | |
768 | ||
c8df4a7a | 769 | static void dirty_bitmap_state_pending(void *opaque, |
24beea4e JQ |
770 | uint64_t *must_precopy, |
771 | uint64_t *can_postcopy) | |
b35ebdf0 | 772 | { |
3b52726e | 773 | DBMSaveState *s = &((DBMState *)opaque)->save; |
fbbc6b14 | 774 | SaveBitmapState *dbms; |
b35ebdf0 VSO |
775 | uint64_t pending = 0; |
776 | ||
195801d7 | 777 | bql_lock(); |
b35ebdf0 | 778 | |
3b52726e | 779 | QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) { |
b35ebdf0 VSO |
780 | uint64_t gran = bdrv_dirty_bitmap_granularity(dbms->bitmap); |
781 | uint64_t sectors = dbms->bulk_completed ? 0 : | |
782 | dbms->total_sectors - dbms->cur_sector; | |
783 | ||
784 | pending += DIV_ROUND_UP(sectors * BDRV_SECTOR_SIZE, gran); | |
785 | } | |
786 | ||
195801d7 | 787 | bql_unlock(); |
b35ebdf0 | 788 | |
c8df4a7a | 789 | trace_dirty_bitmap_state_pending(pending); |
b35ebdf0 | 790 | |
24beea4e | 791 | *can_postcopy += pending; |
b35ebdf0 VSO |
792 | } |
793 | ||
794 | /* First occurrence of this bitmap. It should be created if doesn't exist */ | |
fbbc6b14 | 795 | static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) |
b35ebdf0 VSO |
796 | { |
797 | Error *local_err = NULL; | |
798 | uint32_t granularity = qemu_get_be32(f); | |
799 | uint8_t flags = qemu_get_byte(f); | |
0a47190a | 800 | LoadBitmapState *b; |
6e9f21a2 | 801 | bool persistent; |
b35ebdf0 | 802 | |
b91f33b8 VSO |
803 | if (s->cancelled) { |
804 | return 0; | |
805 | } | |
806 | ||
b35ebdf0 VSO |
807 | if (s->bitmap) { |
808 | error_report("Bitmap with the same name ('%s') already exists on " | |
809 | "destination", bdrv_dirty_bitmap_name(s->bitmap)); | |
810 | return -EINVAL; | |
811 | } else { | |
812 | s->bitmap = bdrv_create_dirty_bitmap(s->bs, granularity, | |
813 | s->bitmap_name, &local_err); | |
814 | if (!s->bitmap) { | |
815 | error_report_err(local_err); | |
816 | return -EINVAL; | |
817 | } | |
818 | } | |
819 | ||
820 | if (flags & DIRTY_BITMAP_MIG_START_FLAG_RESERVED_MASK) { | |
821 | error_report("Unknown flags in migrated dirty bitmap header: %x", | |
822 | flags); | |
823 | return -EINVAL; | |
824 | } | |
825 | ||
6e9f21a2 | 826 | if (s->bmap_inner && |
720a252c | 827 | s->bmap_inner->transform && |
6e9f21a2 PK |
828 | s->bmap_inner->transform->has_persistent) { |
829 | persistent = s->bmap_inner->transform->persistent; | |
830 | } else { | |
831 | persistent = flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; | |
832 | } | |
833 | ||
834 | if (persistent) { | |
796a3798 | 835 | bdrv_dirty_bitmap_set_persistence(s->bitmap, true); |
b35ebdf0 VSO |
836 | } |
837 | ||
838 | bdrv_disable_dirty_bitmap(s->bitmap); | |
839 | if (flags & DIRTY_BITMAP_MIG_START_FLAG_ENABLED) { | |
5deb6cbd | 840 | bdrv_dirty_bitmap_create_successor(s->bitmap, &local_err); |
b35ebdf0 VSO |
841 | if (local_err) { |
842 | error_report_err(local_err); | |
843 | return -EINVAL; | |
844 | } | |
4290b483 VSO |
845 | } else { |
846 | bdrv_dirty_bitmap_set_busy(s->bitmap, true); | |
b35ebdf0 VSO |
847 | } |
848 | ||
0a47190a VSO |
849 | b = g_new(LoadBitmapState, 1); |
850 | b->bs = s->bs; | |
851 | b->bitmap = s->bitmap; | |
852 | b->migrated = false; | |
853 | b->enabled = flags & DIRTY_BITMAP_MIG_START_FLAG_ENABLED; | |
854 | ||
855 | s->bitmaps = g_slist_prepend(s->bitmaps, b); | |
856 | ||
b35ebdf0 VSO |
857 | return 0; |
858 | } | |
859 | ||
0a47190a VSO |
860 | /* |
861 | * before_vm_start_handle_item | |
862 | * | |
863 | * g_slist_foreach helper | |
864 | * | |
865 | * item is LoadBitmapState* | |
866 | * opaque is DBMLoadState* | |
867 | */ | |
868 | static void before_vm_start_handle_item(void *item, void *opaque) | |
b35ebdf0 | 869 | { |
0a47190a VSO |
870 | DBMLoadState *s = opaque; |
871 | LoadBitmapState *b = item; | |
b35ebdf0 | 872 | |
0a47190a | 873 | if (b->enabled) { |
b35ebdf0 | 874 | if (b->migrated) { |
e6ce5e92 | 875 | bdrv_enable_dirty_bitmap(b->bitmap); |
b35ebdf0 VSO |
876 | } else { |
877 | bdrv_dirty_bitmap_enable_successor(b->bitmap); | |
878 | } | |
0a47190a | 879 | } |
b35ebdf0 | 880 | |
0a47190a VSO |
881 | if (b->migrated) { |
882 | s->bitmaps = g_slist_remove(s->bitmaps, b); | |
b35ebdf0 VSO |
883 | g_free(b); |
884 | } | |
0a47190a | 885 | } |
b35ebdf0 | 886 | |
0a47190a VSO |
887 | void dirty_bitmap_mig_before_vm_start(void) |
888 | { | |
889 | DBMLoadState *s = &dbm_state.load; | |
890 | qemu_mutex_lock(&s->lock); | |
891 | ||
892 | assert(!s->before_vm_start_handled); | |
893 | g_slist_foreach(s->bitmaps, before_vm_start_handle_item, s); | |
894 | s->before_vm_start_handled = true; | |
b35ebdf0 | 895 | |
89491216 | 896 | qemu_mutex_unlock(&s->lock); |
b35ebdf0 VSO |
897 | } |
898 | ||
b91f33b8 VSO |
899 | static void cancel_incoming_locked(DBMLoadState *s) |
900 | { | |
901 | GSList *item; | |
902 | ||
903 | if (s->cancelled) { | |
904 | return; | |
905 | } | |
906 | ||
907 | s->cancelled = true; | |
908 | s->bs = NULL; | |
909 | s->bitmap = NULL; | |
910 | ||
911 | /* Drop all unfinished bitmaps */ | |
912 | for (item = s->bitmaps; item; item = g_slist_next(item)) { | |
913 | LoadBitmapState *b = item->data; | |
914 | ||
915 | /* | |
916 | * Bitmap must be unfinished, as finished bitmaps should already be | |
917 | * removed from the list. | |
918 | */ | |
919 | assert(!s->before_vm_start_handled || !b->migrated); | |
920 | if (bdrv_dirty_bitmap_has_successor(b->bitmap)) { | |
921 | bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort); | |
4290b483 VSO |
922 | } else { |
923 | bdrv_dirty_bitmap_set_busy(b->bitmap, false); | |
b91f33b8 VSO |
924 | } |
925 | bdrv_release_dirty_bitmap(b->bitmap); | |
926 | } | |
927 | ||
928 | g_slist_free_full(s->bitmaps, g_free); | |
929 | s->bitmaps = NULL; | |
930 | } | |
931 | ||
1499ab09 VSO |
932 | void dirty_bitmap_mig_cancel_outgoing(void) |
933 | { | |
934 | dirty_bitmap_do_save_cleanup(&dbm_state.save); | |
935 | } | |
936 | ||
937 | void dirty_bitmap_mig_cancel_incoming(void) | |
938 | { | |
939 | DBMLoadState *s = &dbm_state.load; | |
940 | ||
941 | qemu_mutex_lock(&s->lock); | |
942 | ||
943 | cancel_incoming_locked(s); | |
944 | ||
945 | qemu_mutex_unlock(&s->lock); | |
946 | } | |
947 | ||
fbbc6b14 | 948 | static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s) |
b35ebdf0 VSO |
949 | { |
950 | GSList *item; | |
951 | trace_dirty_bitmap_load_complete(); | |
b35ebdf0 | 952 | |
b91f33b8 VSO |
953 | if (s->cancelled) { |
954 | return; | |
955 | } | |
956 | ||
957 | bdrv_dirty_bitmap_deserialize_finish(s->bitmap); | |
b35ebdf0 | 958 | |
f3045b9a VSO |
959 | if (bdrv_dirty_bitmap_has_successor(s->bitmap)) { |
960 | bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort); | |
4290b483 VSO |
961 | } else { |
962 | bdrv_dirty_bitmap_set_busy(s->bitmap, false); | |
f3045b9a VSO |
963 | } |
964 | ||
0a47190a | 965 | for (item = s->bitmaps; item; item = g_slist_next(item)) { |
fbbc6b14 | 966 | LoadBitmapState *b = item->data; |
b35ebdf0 VSO |
967 | |
968 | if (b->bitmap == s->bitmap) { | |
969 | b->migrated = true; | |
0a47190a VSO |
970 | if (s->before_vm_start_handled) { |
971 | s->bitmaps = g_slist_remove(s->bitmaps, b); | |
972 | g_free(b); | |
973 | } | |
b35ebdf0 VSO |
974 | break; |
975 | } | |
976 | } | |
b35ebdf0 VSO |
977 | } |
978 | ||
fbbc6b14 | 979 | static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s) |
b35ebdf0 VSO |
980 | { |
981 | uint64_t first_byte = qemu_get_be64(f) << BDRV_SECTOR_BITS; | |
982 | uint64_t nr_bytes = (uint64_t)qemu_get_be32(f) << BDRV_SECTOR_BITS; | |
983 | trace_dirty_bitmap_load_bits_enter(first_byte >> BDRV_SECTOR_BITS, | |
984 | nr_bytes >> BDRV_SECTOR_BITS); | |
985 | ||
986 | if (s->flags & DIRTY_BITMAP_MIG_FLAG_ZEROES) { | |
987 | trace_dirty_bitmap_load_bits_zeroes(); | |
b91f33b8 VSO |
988 | if (!s->cancelled) { |
989 | bdrv_dirty_bitmap_deserialize_zeroes(s->bitmap, first_byte, | |
990 | nr_bytes, false); | |
991 | } | |
b35ebdf0 VSO |
992 | } else { |
993 | size_t ret; | |
b91f33b8 | 994 | g_autofree uint8_t *buf = NULL; |
b35ebdf0 | 995 | uint64_t buf_size = qemu_get_be64(f); |
b91f33b8 VSO |
996 | uint64_t needed_size; |
997 | ||
998 | /* | |
999 | * The actual check for buf_size is done a bit later. We can't do it in | |
1000 | * cancelled mode as we don't have the bitmap to check the constraints | |
1001 | * (so, we allocate a buffer and read prior to the check). On the other | |
1002 | * hand, we shouldn't blindly g_malloc the number from the stream. | |
1003 | * Actually one chunk should not be larger than CHUNK_SIZE. Let's allow | |
1004 | * a bit larger (which means that bitmap migration will fail anyway and | |
1005 | * the whole migration will most probably fail soon due to broken | |
1006 | * stream). | |
1007 | */ | |
1008 | if (buf_size > 10 * CHUNK_SIZE) { | |
1009 | error_report("Bitmap migration stream buffer allocation request " | |
1010 | "is too large"); | |
1011 | return -EIO; | |
1012 | } | |
1013 | ||
1014 | buf = g_malloc(buf_size); | |
1015 | ret = qemu_get_buffer(f, buf, buf_size); | |
1016 | if (ret != buf_size) { | |
1017 | error_report("Failed to read bitmap bits"); | |
1018 | return -EIO; | |
1019 | } | |
1020 | ||
1021 | if (s->cancelled) { | |
1022 | return 0; | |
1023 | } | |
1024 | ||
1025 | needed_size = bdrv_dirty_bitmap_serialization_size(s->bitmap, | |
1026 | first_byte, | |
1027 | nr_bytes); | |
b35ebdf0 VSO |
1028 | |
1029 | if (needed_size > buf_size || | |
1030 | buf_size > QEMU_ALIGN_UP(needed_size, 4 * sizeof(long)) | |
1031 | /* Here used same alignment as in send_bitmap_bits */ | |
1032 | ) { | |
1033 | error_report("Migrated bitmap granularity doesn't " | |
1034 | "match the destination bitmap '%s' granularity", | |
1035 | bdrv_dirty_bitmap_name(s->bitmap)); | |
b91f33b8 VSO |
1036 | cancel_incoming_locked(s); |
1037 | return 0; | |
b35ebdf0 VSO |
1038 | } |
1039 | ||
1040 | bdrv_dirty_bitmap_deserialize_part(s->bitmap, buf, first_byte, nr_bytes, | |
1041 | false); | |
b35ebdf0 VSO |
1042 | } |
1043 | ||
1044 | return 0; | |
1045 | } | |
1046 | ||
31e4c354 HR |
1047 | static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, |
1048 | GHashTable *alias_map) | |
b35ebdf0 | 1049 | { |
31e4c354 | 1050 | GHashTable *bitmap_alias_map = NULL; |
b35ebdf0 VSO |
1051 | Error *local_err = NULL; |
1052 | bool nothing; | |
1053 | s->flags = qemu_get_bitmap_flags(f); | |
1054 | trace_dirty_bitmap_load_header(s->flags); | |
1055 | ||
1056 | nothing = s->flags == (s->flags & DIRTY_BITMAP_MIG_FLAG_EOS); | |
1057 | ||
1058 | if (s->flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) { | |
31e4c354 HR |
1059 | if (!qemu_get_counted_string(f, s->node_alias)) { |
1060 | error_report("Unable to read node alias string"); | |
b35ebdf0 VSO |
1061 | return -EINVAL; |
1062 | } | |
31e4c354 | 1063 | |
b91f33b8 | 1064 | if (!s->cancelled) { |
31e4c354 HR |
1065 | if (alias_map) { |
1066 | const AliasMapInnerNode *amin; | |
1067 | ||
1068 | amin = g_hash_table_lookup(alias_map, s->node_alias); | |
1069 | if (!amin) { | |
1070 | error_setg(&local_err, "Error: Unknown node alias '%s'", | |
1071 | s->node_alias); | |
1072 | s->bs = NULL; | |
1073 | } else { | |
1074 | bitmap_alias_map = amin->subtree; | |
1075 | s->bs = bdrv_lookup_bs(NULL, amin->string, &local_err); | |
1076 | } | |
1077 | } else { | |
1078 | s->bs = bdrv_lookup_bs(s->node_alias, s->node_alias, | |
1079 | &local_err); | |
1080 | } | |
b91f33b8 VSO |
1081 | if (!s->bs) { |
1082 | error_report_err(local_err); | |
1083 | cancel_incoming_locked(s); | |
1084 | } | |
b35ebdf0 | 1085 | } |
31e4c354 HR |
1086 | } else if (s->bs) { |
1087 | if (alias_map) { | |
1088 | const AliasMapInnerNode *amin; | |
1089 | ||
1090 | /* Must be present in the map, or s->bs would not be set */ | |
1091 | amin = g_hash_table_lookup(alias_map, s->node_alias); | |
1092 | assert(amin != NULL); | |
1093 | ||
1094 | bitmap_alias_map = amin->subtree; | |
1095 | } | |
1096 | } else if (!nothing && !s->cancelled) { | |
b35ebdf0 | 1097 | error_report("Error: block device name is not set"); |
b91f33b8 | 1098 | cancel_incoming_locked(s); |
b35ebdf0 VSO |
1099 | } |
1100 | ||
31e4c354 HR |
1101 | assert(nothing || s->cancelled || !!alias_map == !!bitmap_alias_map); |
1102 | ||
b35ebdf0 | 1103 | if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) { |
31e4c354 HR |
1104 | const char *bitmap_name; |
1105 | ||
1106 | if (!qemu_get_counted_string(f, s->bitmap_alias)) { | |
1107 | error_report("Unable to read bitmap alias string"); | |
b35ebdf0 VSO |
1108 | return -EINVAL; |
1109 | } | |
31e4c354 | 1110 | |
a024890a CQ |
1111 | bitmap_name = s->bitmap_alias; |
1112 | if (!s->cancelled && bitmap_alias_map) { | |
0d1e450c PK |
1113 | BitmapMigrationBitmapAlias *bmap_inner; |
1114 | ||
1115 | bmap_inner = g_hash_table_lookup(bitmap_alias_map, s->bitmap_alias); | |
1116 | if (!bmap_inner) { | |
a024890a CQ |
1117 | error_report("Error: Unknown bitmap alias '%s' on node " |
1118 | "'%s' (alias '%s')", s->bitmap_alias, | |
1119 | s->bs->node_name, s->node_alias); | |
1120 | cancel_incoming_locked(s); | |
0d1e450c PK |
1121 | } else { |
1122 | bitmap_name = bmap_inner->name; | |
31e4c354 | 1123 | } |
6e9f21a2 PK |
1124 | |
1125 | s->bmap_inner = bmap_inner; | |
31e4c354 HR |
1126 | } |
1127 | ||
1128 | if (!s->cancelled) { | |
1129 | g_strlcpy(s->bitmap_name, bitmap_name, sizeof(s->bitmap_name)); | |
b91f33b8 VSO |
1130 | s->bitmap = bdrv_find_dirty_bitmap(s->bs, s->bitmap_name); |
1131 | ||
1132 | /* | |
1133 | * bitmap may be NULL here, it wouldn't be an error if it is the | |
1134 | * first occurrence of the bitmap | |
1135 | */ | |
1136 | if (!s->bitmap && !(s->flags & DIRTY_BITMAP_MIG_FLAG_START)) { | |
1137 | error_report("Error: unknown dirty bitmap " | |
1138 | "'%s' for block device '%s'", | |
31e4c354 | 1139 | s->bitmap_name, s->bs->node_name); |
b91f33b8 VSO |
1140 | cancel_incoming_locked(s); |
1141 | } | |
b35ebdf0 | 1142 | } |
b91f33b8 | 1143 | } else if (!s->bitmap && !nothing && !s->cancelled) { |
b35ebdf0 | 1144 | error_report("Error: block device name is not set"); |
b91f33b8 | 1145 | cancel_incoming_locked(s); |
b35ebdf0 VSO |
1146 | } |
1147 | ||
1148 | return 0; | |
1149 | } | |
1150 | ||
b91f33b8 VSO |
1151 | /* |
1152 | * dirty_bitmap_load | |
1153 | * | |
1154 | * Load sequence of dirty bitmap chunks. Return error only on fatal io stream | |
1155 | * violations. On other errors just cancel bitmaps incoming migration and return | |
1156 | * 0. | |
1157 | * | |
1158 | * Note, than when incoming bitmap migration is canceled, we still must read all | |
1159 | * our chunks (and just ignore them), to not affect other migration objects. | |
1160 | */ | |
b35ebdf0 VSO |
1161 | static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id) |
1162 | { | |
31e4c354 | 1163 | GHashTable *alias_map = NULL; |
3b52726e | 1164 | DBMLoadState *s = &((DBMState *)opaque)->load; |
b35ebdf0 VSO |
1165 | int ret = 0; |
1166 | ||
1167 | trace_dirty_bitmap_load_enter(); | |
1168 | ||
1169 | if (version_id != 1) { | |
b91f33b8 VSO |
1170 | QEMU_LOCK_GUARD(&s->lock); |
1171 | cancel_incoming_locked(s); | |
b35ebdf0 VSO |
1172 | return -EINVAL; |
1173 | } | |
1174 | ||
3cba22c9 JQ |
1175 | if (migrate_has_block_bitmap_mapping()) { |
1176 | alias_map = construct_alias_map(migrate_block_bitmap_mapping(), false, | |
1177 | &error_abort); | |
31e4c354 HR |
1178 | } |
1179 | ||
b35ebdf0 | 1180 | do { |
b91f33b8 VSO |
1181 | QEMU_LOCK_GUARD(&s->lock); |
1182 | ||
31e4c354 | 1183 | ret = dirty_bitmap_load_header(f, s, alias_map); |
a36f6ff4 | 1184 | if (ret < 0) { |
b91f33b8 | 1185 | cancel_incoming_locked(s); |
31e4c354 | 1186 | goto fail; |
a36f6ff4 | 1187 | } |
b35ebdf0 | 1188 | |
3b52726e VSO |
1189 | if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) { |
1190 | ret = dirty_bitmap_load_start(f, s); | |
1191 | } else if (s->flags & DIRTY_BITMAP_MIG_FLAG_COMPLETE) { | |
1192 | dirty_bitmap_load_complete(f, s); | |
1193 | } else if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITS) { | |
1194 | ret = dirty_bitmap_load_bits(f, s); | |
b35ebdf0 VSO |
1195 | } |
1196 | ||
1197 | if (!ret) { | |
1198 | ret = qemu_file_get_error(f); | |
1199 | } | |
1200 | ||
1201 | if (ret) { | |
b91f33b8 | 1202 | cancel_incoming_locked(s); |
31e4c354 | 1203 | goto fail; |
b35ebdf0 | 1204 | } |
3b52726e | 1205 | } while (!(s->flags & DIRTY_BITMAP_MIG_FLAG_EOS)); |
b35ebdf0 VSO |
1206 | |
1207 | trace_dirty_bitmap_load_success(); | |
31e4c354 HR |
1208 | ret = 0; |
1209 | fail: | |
1210 | if (alias_map) { | |
1211 | g_hash_table_destroy(alias_map); | |
1212 | } | |
1213 | return ret; | |
b35ebdf0 VSO |
1214 | } |
1215 | ||
1216 | static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque) | |
1217 | { | |
3b52726e | 1218 | DBMSaveState *s = &((DBMState *)opaque)->save; |
fbbc6b14 | 1219 | SaveBitmapState *dbms = NULL; |
3c158eba | 1220 | |
3b52726e | 1221 | if (init_dirty_bitmap_migration(s) < 0) { |
b35ebdf0 VSO |
1222 | return -1; |
1223 | } | |
1224 | ||
3b52726e VSO |
1225 | QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) { |
1226 | send_bitmap_start(f, s, dbms); | |
b35ebdf0 VSO |
1227 | } |
1228 | qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS); | |
b35ebdf0 VSO |
1229 | return 0; |
1230 | } | |
1231 | ||
1232 | static bool dirty_bitmap_is_active(void *opaque) | |
1233 | { | |
3b52726e VSO |
1234 | DBMSaveState *s = &((DBMState *)opaque)->save; |
1235 | ||
1236 | return migrate_dirty_bitmaps() && !s->no_bitmaps; | |
b35ebdf0 VSO |
1237 | } |
1238 | ||
1239 | static bool dirty_bitmap_is_active_iterate(void *opaque) | |
1240 | { | |
1241 | return dirty_bitmap_is_active(opaque) && !runstate_is_running(); | |
1242 | } | |
1243 | ||
1244 | static bool dirty_bitmap_has_postcopy(void *opaque) | |
1245 | { | |
1246 | return true; | |
1247 | } | |
1248 | ||
1249 | static SaveVMHandlers savevm_dirty_bitmap_handlers = { | |
1250 | .save_setup = dirty_bitmap_save_setup, | |
1251 | .save_live_complete_postcopy = dirty_bitmap_save_complete, | |
1252 | .save_live_complete_precopy = dirty_bitmap_save_complete, | |
1253 | .has_postcopy = dirty_bitmap_has_postcopy, | |
c8df4a7a JQ |
1254 | .state_pending_exact = dirty_bitmap_state_pending, |
1255 | .state_pending_estimate = dirty_bitmap_state_pending, | |
b35ebdf0 VSO |
1256 | .save_live_iterate = dirty_bitmap_save_iterate, |
1257 | .is_active_iterate = dirty_bitmap_is_active_iterate, | |
1258 | .load_state = dirty_bitmap_load, | |
1259 | .save_cleanup = dirty_bitmap_save_cleanup, | |
1260 | .is_active = dirty_bitmap_is_active, | |
1261 | }; | |
1262 | ||
1263 | void dirty_bitmap_mig_init(void) | |
1264 | { | |
3b52726e | 1265 | QSIMPLEQ_INIT(&dbm_state.save.dbms_list); |
89491216 | 1266 | qemu_mutex_init(&dbm_state.load.lock); |
b35ebdf0 | 1267 | |
ce62df53 | 1268 | register_savevm_live("dirty-bitmap", 0, 1, |
b35ebdf0 | 1269 | &savevm_dirty_bitmap_handlers, |
3b52726e | 1270 | &dbm_state); |
b35ebdf0 | 1271 | } |