xref: /qemu/migration/block-dirty-bitmap.c (revision dd031677)
1b35ebdf0SVladimir Sementsov-Ogievskiy /*
2b35ebdf0SVladimir Sementsov-Ogievskiy  * Block dirty bitmap postcopy migration
3b35ebdf0SVladimir Sementsov-Ogievskiy  *
4b35ebdf0SVladimir Sementsov-Ogievskiy  * Copyright IBM, Corp. 2009
5b35ebdf0SVladimir Sementsov-Ogievskiy  * Copyright (c) 2016-2017 Virtuozzo International GmbH. All rights reserved.
6b35ebdf0SVladimir Sementsov-Ogievskiy  *
7b35ebdf0SVladimir Sementsov-Ogievskiy  * Authors:
8b35ebdf0SVladimir Sementsov-Ogievskiy  *  Liran Schour   <lirans@il.ibm.com>
9b35ebdf0SVladimir Sementsov-Ogievskiy  *  Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10b35ebdf0SVladimir Sementsov-Ogievskiy  *
11b35ebdf0SVladimir Sementsov-Ogievskiy  * This work is licensed under the terms of the GNU GPL, version 2.  See
12b35ebdf0SVladimir Sementsov-Ogievskiy  * the COPYING file in the top-level directory.
13b35ebdf0SVladimir Sementsov-Ogievskiy  * This file is derived from migration/block.c, so it's author and IBM copyright
14b35ebdf0SVladimir Sementsov-Ogievskiy  * are here, although content is quite different.
15b35ebdf0SVladimir Sementsov-Ogievskiy  *
16b35ebdf0SVladimir Sementsov-Ogievskiy  * Contributions after 2012-01-13 are licensed under the terms of the
17b35ebdf0SVladimir Sementsov-Ogievskiy  * GNU GPL, version 2 or (at your option) any later version.
18b35ebdf0SVladimir Sementsov-Ogievskiy  *
19b35ebdf0SVladimir Sementsov-Ogievskiy  *                                ***
20b35ebdf0SVladimir Sementsov-Ogievskiy  *
21b35ebdf0SVladimir Sementsov-Ogievskiy  * Here postcopy migration of dirty bitmaps is realized. Only QMP-addressable
22b35ebdf0SVladimir Sementsov-Ogievskiy  * bitmaps are migrated.
23b35ebdf0SVladimir Sementsov-Ogievskiy  *
24b35ebdf0SVladimir Sementsov-Ogievskiy  * Bitmap migration implies creating bitmap with the same name and granularity
25b35ebdf0SVladimir Sementsov-Ogievskiy  * in destination QEMU. If the bitmap with the same name (for the same node)
26b35ebdf0SVladimir Sementsov-Ogievskiy  * already exists on destination an error will be generated.
27b35ebdf0SVladimir Sementsov-Ogievskiy  *
28b35ebdf0SVladimir Sementsov-Ogievskiy  * format of migration:
29b35ebdf0SVladimir Sementsov-Ogievskiy  *
30b35ebdf0SVladimir Sementsov-Ogievskiy  * # Header (shared for different chunk types)
31b35ebdf0SVladimir Sementsov-Ogievskiy  * 1, 2 or 4 bytes: flags (see qemu_{put,put}_flags)
3231e4c354SMax Reitz  * [ 1 byte: node alias size ] \  flags & DEVICE_NAME
3331e4c354SMax Reitz  * [ n bytes: node alias     ] /
3431e4c354SMax Reitz  * [ 1 byte: bitmap alias size ] \  flags & BITMAP_NAME
3531e4c354SMax Reitz  * [ n bytes: bitmap alias     ] /
36b35ebdf0SVladimir Sementsov-Ogievskiy  *
37b35ebdf0SVladimir Sementsov-Ogievskiy  * # Start of bitmap migration (flags & START)
38b35ebdf0SVladimir Sementsov-Ogievskiy  * header
39b35ebdf0SVladimir Sementsov-Ogievskiy  * be64: granularity
40b35ebdf0SVladimir Sementsov-Ogievskiy  * 1 byte: bitmap flags (corresponds to BdrvDirtyBitmap)
41b35ebdf0SVladimir Sementsov-Ogievskiy  *   bit 0    -  bitmap is enabled
42b35ebdf0SVladimir Sementsov-Ogievskiy  *   bit 1    -  bitmap is persistent
43b35ebdf0SVladimir Sementsov-Ogievskiy  *   bit 2    -  bitmap is autoloading
44b35ebdf0SVladimir Sementsov-Ogievskiy  *   bits 3-7 - reserved, must be zero
45b35ebdf0SVladimir Sementsov-Ogievskiy  *
46b35ebdf0SVladimir Sementsov-Ogievskiy  * # Complete of bitmap migration (flags & COMPLETE)
47b35ebdf0SVladimir Sementsov-Ogievskiy  * header
48b35ebdf0SVladimir Sementsov-Ogievskiy  *
49b35ebdf0SVladimir Sementsov-Ogievskiy  * # Data chunk of bitmap migration
50b35ebdf0SVladimir Sementsov-Ogievskiy  * header
51b35ebdf0SVladimir Sementsov-Ogievskiy  * be64: start sector
52b35ebdf0SVladimir Sementsov-Ogievskiy  * be32: number of sectors
53b35ebdf0SVladimir Sementsov-Ogievskiy  * [ be64: buffer size  ] \ ! (flags & ZEROES)
54b35ebdf0SVladimir Sementsov-Ogievskiy  * [ n bytes: buffer    ] /
55b35ebdf0SVladimir Sementsov-Ogievskiy  *
56b35ebdf0SVladimir Sementsov-Ogievskiy  * The last chunk in stream should contain flags & EOS. The chunk may skip
57b35ebdf0SVladimir Sementsov-Ogievskiy  * device and/or bitmap names, assuming them to be the same with the previous
58b35ebdf0SVladimir Sementsov-Ogievskiy  * chunk.
59b35ebdf0SVladimir Sementsov-Ogievskiy  */
60b35ebdf0SVladimir Sementsov-Ogievskiy 
61b35ebdf0SVladimir Sementsov-Ogievskiy #include "qemu/osdep.h"
62b35ebdf0SVladimir Sementsov-Ogievskiy #include "block/block.h"
63b35ebdf0SVladimir Sementsov-Ogievskiy #include "block/block_int.h"
64e2c1c34fSMarkus Armbruster #include "block/dirty-bitmap.h"
65b35ebdf0SVladimir Sementsov-Ogievskiy #include "sysemu/block-backend.h"
6654d31236SMarkus Armbruster #include "sysemu/runstate.h"
67b35ebdf0SVladimir Sementsov-Ogievskiy #include "qemu/main-loop.h"
68b35ebdf0SVladimir Sementsov-Ogievskiy #include "qemu/error-report.h"
69b35ebdf0SVladimir Sementsov-Ogievskiy #include "migration/misc.h"
70b35ebdf0SVladimir Sementsov-Ogievskiy #include "migration/migration.h"
7153d37d36SMichael S. Tsirkin #include "qemu-file.h"
72b35ebdf0SVladimir Sementsov-Ogievskiy #include "migration/vmstate.h"
73b35ebdf0SVladimir Sementsov-Ogievskiy #include "migration/register.h"
74b35ebdf0SVladimir Sementsov-Ogievskiy #include "qemu/hbitmap.h"
75b35ebdf0SVladimir Sementsov-Ogievskiy #include "qemu/cutils.h"
7631e4c354SMax Reitz #include "qemu/id.h"
77b35ebdf0SVladimir Sementsov-Ogievskiy #include "qapi/error.h"
7831e4c354SMax Reitz #include "qapi/qapi-commands-migration.h"
790d1e450cSPeter Krempa #include "qapi/qapi-visit-migration.h"
800d1e450cSPeter Krempa #include "qapi/clone-visitor.h"
81b35ebdf0SVladimir Sementsov-Ogievskiy #include "trace.h"
821f0776f1SJuan Quintela #include "options.h"
83b35ebdf0SVladimir Sementsov-Ogievskiy 
84b35ebdf0SVladimir Sementsov-Ogievskiy #define CHUNK_SIZE     (1 << 10)
85b35ebdf0SVladimir Sementsov-Ogievskiy 
86b35ebdf0SVladimir Sementsov-Ogievskiy /* Flags occupy one, two or four bytes (Big Endian). The size is determined as
87b35ebdf0SVladimir Sementsov-Ogievskiy  * follows:
88b35ebdf0SVladimir Sementsov-Ogievskiy  * in first (most significant) byte bit 8 is clear  -->  one byte
89b35ebdf0SVladimir Sementsov-Ogievskiy  * in first byte bit 8 is set    -->  two or four bytes, depending on second
90b35ebdf0SVladimir Sementsov-Ogievskiy  *                                    byte:
91b35ebdf0SVladimir Sementsov-Ogievskiy  *    | in second byte bit 8 is clear  -->  two bytes
92b35ebdf0SVladimir Sementsov-Ogievskiy  *    | in second byte bit 8 is set    -->  four bytes
93b35ebdf0SVladimir Sementsov-Ogievskiy  */
94b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_EOS           0x01
95b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_ZEROES        0x02
96b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME   0x04
97b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME   0x08
98b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_START         0x10
99b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_COMPLETE      0x20
100b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_FLAG_BITS          0x40
101b35ebdf0SVladimir Sementsov-Ogievskiy 
102b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_EXTRA_FLAGS        0x80
103b35ebdf0SVladimir Sementsov-Ogievskiy 
104b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_START_FLAG_ENABLED          0x01
105b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT       0x02
10637931e00SEric Blake /* 0x04 was "AUTOLOAD" flags on older versions, now it is ignored */
107b35ebdf0SVladimir Sementsov-Ogievskiy #define DIRTY_BITMAP_MIG_START_FLAG_RESERVED_MASK    0xf8
108b35ebdf0SVladimir Sementsov-Ogievskiy 
109fbbc6b14SVladimir Sementsov-Ogievskiy /* State of one bitmap during save process */
110fbbc6b14SVladimir Sementsov-Ogievskiy typedef struct SaveBitmapState {
111b35ebdf0SVladimir Sementsov-Ogievskiy     /* Written during setup phase. */
112b35ebdf0SVladimir Sementsov-Ogievskiy     BlockDriverState *bs;
11331e4c354SMax Reitz     char *node_alias;
11431e4c354SMax Reitz     char *bitmap_alias;
115b35ebdf0SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bitmap;
116b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t total_sectors;
117b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t sectors_per_chunk;
118fbbc6b14SVladimir Sementsov-Ogievskiy     QSIMPLEQ_ENTRY(SaveBitmapState) entry;
119b35ebdf0SVladimir Sementsov-Ogievskiy     uint8_t flags;
120b35ebdf0SVladimir Sementsov-Ogievskiy 
121b35ebdf0SVladimir Sementsov-Ogievskiy     /* For bulk phase. */
122b35ebdf0SVladimir Sementsov-Ogievskiy     bool bulk_completed;
123b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t cur_sector;
124fbbc6b14SVladimir Sementsov-Ogievskiy } SaveBitmapState;
125b35ebdf0SVladimir Sementsov-Ogievskiy 
126fbbc6b14SVladimir Sementsov-Ogievskiy /* State of the dirty bitmap migration (DBM) during save process */
127fbbc6b14SVladimir Sementsov-Ogievskiy typedef struct DBMSaveState {
128fbbc6b14SVladimir Sementsov-Ogievskiy     QSIMPLEQ_HEAD(, SaveBitmapState) dbms_list;
129b35ebdf0SVladimir Sementsov-Ogievskiy 
130b35ebdf0SVladimir Sementsov-Ogievskiy     bool bulk_completed;
131b35ebdf0SVladimir Sementsov-Ogievskiy     bool no_bitmaps;
132b35ebdf0SVladimir Sementsov-Ogievskiy 
133b35ebdf0SVladimir Sementsov-Ogievskiy     /* for send_bitmap_bits() */
134b35ebdf0SVladimir Sementsov-Ogievskiy     BlockDriverState *prev_bs;
135b35ebdf0SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *prev_bitmap;
136fbbc6b14SVladimir Sementsov-Ogievskiy } DBMSaveState;
137b35ebdf0SVladimir Sementsov-Ogievskiy 
1383b52726eSVladimir Sementsov-Ogievskiy typedef struct LoadBitmapState {
1393b52726eSVladimir Sementsov-Ogievskiy     BlockDriverState *bs;
1403b52726eSVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bitmap;
1413b52726eSVladimir Sementsov-Ogievskiy     bool migrated;
1420a47190aSVladimir Sementsov-Ogievskiy     bool enabled;
1433b52726eSVladimir Sementsov-Ogievskiy } LoadBitmapState;
1443b52726eSVladimir Sementsov-Ogievskiy 
145fbbc6b14SVladimir Sementsov-Ogievskiy /* State of the dirty bitmap migration (DBM) during load process */
146fbbc6b14SVladimir Sementsov-Ogievskiy typedef struct DBMLoadState {
147b35ebdf0SVladimir Sementsov-Ogievskiy     uint32_t flags;
14831e4c354SMax Reitz     char node_alias[256];
14931e4c354SMax Reitz     char bitmap_alias[256];
15031e4c354SMax Reitz     char bitmap_name[BDRV_BITMAP_MAX_NAME_SIZE + 1];
151b35ebdf0SVladimir Sementsov-Ogievskiy     BlockDriverState *bs;
152b35ebdf0SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bitmap;
1533b52726eSVladimir Sementsov-Ogievskiy 
1540a47190aSVladimir Sementsov-Ogievskiy     bool before_vm_start_handled; /* set in dirty_bitmap_mig_before_vm_start */
1556e9f21a2SPeter Krempa     BitmapMigrationBitmapAlias *bmap_inner;
1560a47190aSVladimir Sementsov-Ogievskiy 
157b91f33b8SVladimir Sementsov-Ogievskiy     /*
158b91f33b8SVladimir Sementsov-Ogievskiy      * cancelled
159b91f33b8SVladimir Sementsov-Ogievskiy      * Incoming migration is cancelled for some reason. That means that we
160b91f33b8SVladimir Sementsov-Ogievskiy      * still should read our chunks from migration stream, to not affect other
161b91f33b8SVladimir Sementsov-Ogievskiy      * migration objects (like RAM), but just ignore them and do not touch any
162b91f33b8SVladimir Sementsov-Ogievskiy      * bitmaps or nodes.
163b91f33b8SVladimir Sementsov-Ogievskiy      */
164b91f33b8SVladimir Sementsov-Ogievskiy     bool cancelled;
165b91f33b8SVladimir Sementsov-Ogievskiy 
1660a47190aSVladimir Sementsov-Ogievskiy     GSList *bitmaps;
1670a47190aSVladimir Sementsov-Ogievskiy     QemuMutex lock; /* protect bitmaps */
168fbbc6b14SVladimir Sementsov-Ogievskiy } DBMLoadState;
169b35ebdf0SVladimir Sementsov-Ogievskiy 
1703b52726eSVladimir Sementsov-Ogievskiy typedef struct DBMState {
1713b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState save;
1723b52726eSVladimir Sementsov-Ogievskiy     DBMLoadState load;
1733b52726eSVladimir Sementsov-Ogievskiy } DBMState;
174b35ebdf0SVladimir Sementsov-Ogievskiy 
1753b52726eSVladimir Sementsov-Ogievskiy static DBMState dbm_state;
176b35ebdf0SVladimir Sementsov-Ogievskiy 
17731e4c354SMax Reitz /* For hash tables that map node/bitmap names to aliases */
17831e4c354SMax Reitz typedef struct AliasMapInnerNode {
17931e4c354SMax Reitz     char *string;
18031e4c354SMax Reitz     GHashTable *subtree;
18131e4c354SMax Reitz } AliasMapInnerNode;
18231e4c354SMax Reitz 
free_alias_map_inner_node(void * amin_ptr)18331e4c354SMax Reitz static void free_alias_map_inner_node(void *amin_ptr)
18431e4c354SMax Reitz {
18531e4c354SMax Reitz     AliasMapInnerNode *amin = amin_ptr;
18631e4c354SMax Reitz 
18731e4c354SMax Reitz     g_free(amin->string);
18831e4c354SMax Reitz     g_hash_table_unref(amin->subtree);
18931e4c354SMax Reitz     g_free(amin);
19031e4c354SMax Reitz }
19131e4c354SMax Reitz 
19231e4c354SMax Reitz /**
19331e4c354SMax Reitz  * Construct an alias map based on the given QMP structure.
19431e4c354SMax Reitz  *
19531e4c354SMax Reitz  * (Note that we cannot store such maps in the MigrationParameters
19631e4c354SMax Reitz  * object, because that struct is defined by the QAPI schema, which
19731e4c354SMax Reitz  * makes it basically impossible to have dicts with arbitrary keys.
19831e4c354SMax Reitz  * Therefore, we instead have to construct these maps when migration
19931e4c354SMax Reitz  * starts.)
20031e4c354SMax Reitz  *
20131e4c354SMax Reitz  * @bbm is the block_bitmap_mapping from the migration parameters.
20231e4c354SMax Reitz  *
20331e4c354SMax Reitz  * If @name_to_alias is true, the returned hash table will map node
20431e4c354SMax Reitz  * and bitmap names to their respective aliases (for outgoing
20531e4c354SMax Reitz  * migration).
20631e4c354SMax Reitz  *
20731e4c354SMax Reitz  * If @name_to_alias is false, the returned hash table will map node
20831e4c354SMax Reitz  * and bitmap aliases to their respective names (for incoming
20931e4c354SMax Reitz  * migration).
21031e4c354SMax Reitz  *
21131e4c354SMax Reitz  * The hash table maps node names/aliases to AliasMapInnerNode
21231e4c354SMax Reitz  * objects, whose .string is the respective node alias/name, and whose
21331e4c354SMax Reitz  * .subtree table maps bitmap names/aliases to the respective bitmap
21431e4c354SMax Reitz  * alias/name.
21531e4c354SMax Reitz  */
construct_alias_map(const BitmapMigrationNodeAliasList * bbm,bool name_to_alias,Error ** errp)21631e4c354SMax Reitz static GHashTable *construct_alias_map(const BitmapMigrationNodeAliasList *bbm,
21731e4c354SMax Reitz                                        bool name_to_alias,
21831e4c354SMax Reitz                                        Error **errp)
21931e4c354SMax Reitz {
22031e4c354SMax Reitz     GHashTable *alias_map;
22131e4c354SMax Reitz     size_t max_node_name_len = sizeof_field(BlockDriverState, node_name) - 1;
22231e4c354SMax Reitz 
22331e4c354SMax Reitz     alias_map = g_hash_table_new_full(g_str_hash, g_str_equal,
22431e4c354SMax Reitz                                       g_free, free_alias_map_inner_node);
22531e4c354SMax Reitz 
22631e4c354SMax Reitz     for (; bbm; bbm = bbm->next) {
22731e4c354SMax Reitz         const BitmapMigrationNodeAlias *bmna = bbm->value;
22831e4c354SMax Reitz         const BitmapMigrationBitmapAliasList *bmbal;
22931e4c354SMax Reitz         AliasMapInnerNode *amin;
23031e4c354SMax Reitz         GHashTable *bitmaps_map;
23131e4c354SMax Reitz         const char *node_map_from, *node_map_to;
2320d1e450cSPeter Krempa         GDestroyNotify gdn;
23331e4c354SMax Reitz 
23431e4c354SMax Reitz         if (!id_wellformed(bmna->alias)) {
23531e4c354SMax Reitz             error_setg(errp, "The node alias '%s' is not well-formed",
23631e4c354SMax Reitz                        bmna->alias);
23731e4c354SMax Reitz             goto fail;
23831e4c354SMax Reitz         }
23931e4c354SMax Reitz 
24031e4c354SMax Reitz         if (strlen(bmna->alias) > UINT8_MAX) {
24131e4c354SMax Reitz             error_setg(errp, "The node alias '%s' is longer than %u bytes",
24231e4c354SMax Reitz                        bmna->alias, UINT8_MAX);
24331e4c354SMax Reitz             goto fail;
24431e4c354SMax Reitz         }
24531e4c354SMax Reitz 
24631e4c354SMax Reitz         if (strlen(bmna->node_name) > max_node_name_len) {
24731e4c354SMax Reitz             error_setg(errp, "The node name '%s' is longer than %zu bytes",
24831e4c354SMax Reitz                        bmna->node_name, max_node_name_len);
24931e4c354SMax Reitz             goto fail;
25031e4c354SMax Reitz         }
25131e4c354SMax Reitz 
25231e4c354SMax Reitz         if (name_to_alias) {
25331e4c354SMax Reitz             if (g_hash_table_contains(alias_map, bmna->node_name)) {
25431e4c354SMax Reitz                 error_setg(errp, "The node name '%s' is mapped twice",
25531e4c354SMax Reitz                            bmna->node_name);
25631e4c354SMax Reitz                 goto fail;
25731e4c354SMax Reitz             }
25831e4c354SMax Reitz 
25931e4c354SMax Reitz             node_map_from = bmna->node_name;
26031e4c354SMax Reitz             node_map_to = bmna->alias;
26131e4c354SMax Reitz         } else {
26231e4c354SMax Reitz             if (g_hash_table_contains(alias_map, bmna->alias)) {
26331e4c354SMax Reitz                 error_setg(errp, "The node alias '%s' is used twice",
26431e4c354SMax Reitz                            bmna->alias);
26531e4c354SMax Reitz                 goto fail;
26631e4c354SMax Reitz             }
26731e4c354SMax Reitz 
26831e4c354SMax Reitz             node_map_from = bmna->alias;
26931e4c354SMax Reitz             node_map_to = bmna->node_name;
27031e4c354SMax Reitz         }
27131e4c354SMax Reitz 
2720d1e450cSPeter Krempa         gdn = (GDestroyNotify) qapi_free_BitmapMigrationBitmapAlias;
2730d1e450cSPeter Krempa         bitmaps_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
2740d1e450cSPeter Krempa                                             gdn);
27531e4c354SMax Reitz 
27631e4c354SMax Reitz         amin = g_new(AliasMapInnerNode, 1);
27731e4c354SMax Reitz         *amin = (AliasMapInnerNode){
27831e4c354SMax Reitz             .string = g_strdup(node_map_to),
27931e4c354SMax Reitz             .subtree = bitmaps_map,
28031e4c354SMax Reitz         };
28131e4c354SMax Reitz 
28231e4c354SMax Reitz         g_hash_table_insert(alias_map, g_strdup(node_map_from), amin);
28331e4c354SMax Reitz 
28431e4c354SMax Reitz         for (bmbal = bmna->bitmaps; bmbal; bmbal = bmbal->next) {
28531e4c354SMax Reitz             const BitmapMigrationBitmapAlias *bmba = bmbal->value;
2860d1e450cSPeter Krempa             const char *bmap_map_from;
28731e4c354SMax Reitz 
28831e4c354SMax Reitz             if (strlen(bmba->alias) > UINT8_MAX) {
28931e4c354SMax Reitz                 error_setg(errp,
29031e4c354SMax Reitz                            "The bitmap alias '%s' is longer than %u bytes",
29131e4c354SMax Reitz                            bmba->alias, UINT8_MAX);
29231e4c354SMax Reitz                 goto fail;
29331e4c354SMax Reitz             }
29431e4c354SMax Reitz 
29531e4c354SMax Reitz             if (strlen(bmba->name) > BDRV_BITMAP_MAX_NAME_SIZE) {
29631e4c354SMax Reitz                 error_setg(errp, "The bitmap name '%s' is longer than %d bytes",
29731e4c354SMax Reitz                            bmba->name, BDRV_BITMAP_MAX_NAME_SIZE);
29831e4c354SMax Reitz                 goto fail;
29931e4c354SMax Reitz             }
30031e4c354SMax Reitz 
30131e4c354SMax Reitz             if (name_to_alias) {
30231e4c354SMax Reitz                 bmap_map_from = bmba->name;
30331e4c354SMax Reitz 
30431e4c354SMax Reitz                 if (g_hash_table_contains(bitmaps_map, bmba->name)) {
30531e4c354SMax Reitz                     error_setg(errp, "The bitmap '%s'/'%s' is mapped twice",
30631e4c354SMax Reitz                                bmna->node_name, bmba->name);
30731e4c354SMax Reitz                     goto fail;
30831e4c354SMax Reitz                 }
30931e4c354SMax Reitz             } else {
31031e4c354SMax Reitz                 bmap_map_from = bmba->alias;
31131e4c354SMax Reitz 
31231e4c354SMax Reitz                 if (g_hash_table_contains(bitmaps_map, bmba->alias)) {
31331e4c354SMax Reitz                     error_setg(errp, "The bitmap alias '%s'/'%s' is used twice",
31431e4c354SMax Reitz                                bmna->alias, bmba->alias);
31531e4c354SMax Reitz                     goto fail;
31631e4c354SMax Reitz                 }
31731e4c354SMax Reitz             }
31831e4c354SMax Reitz 
3190d1e450cSPeter Krempa             g_hash_table_insert(bitmaps_map, g_strdup(bmap_map_from),
3200d1e450cSPeter Krempa                                 QAPI_CLONE(BitmapMigrationBitmapAlias, bmba));
32131e4c354SMax Reitz         }
32231e4c354SMax Reitz     }
32331e4c354SMax Reitz 
32431e4c354SMax Reitz     return alias_map;
32531e4c354SMax Reitz 
32631e4c354SMax Reitz fail:
32731e4c354SMax Reitz     g_hash_table_destroy(alias_map);
32831e4c354SMax Reitz     return NULL;
32931e4c354SMax Reitz }
33031e4c354SMax Reitz 
33131e4c354SMax Reitz /**
33231e4c354SMax Reitz  * Run construct_alias_map() in both directions to check whether @bbm
33331e4c354SMax Reitz  * is valid.
33431e4c354SMax Reitz  * (This function is to be used by migration/migration.c to validate
33531e4c354SMax Reitz  * the user-specified block-bitmap-mapping migration parameter.)
33631e4c354SMax Reitz  *
33731e4c354SMax Reitz  * Returns true if and only if the mapping is valid.
33831e4c354SMax Reitz  */
check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList * bbm,Error ** errp)33931e4c354SMax Reitz bool check_dirty_bitmap_mig_alias_map(const BitmapMigrationNodeAliasList *bbm,
34031e4c354SMax Reitz                                       Error **errp)
34131e4c354SMax Reitz {
34231e4c354SMax Reitz     GHashTable *alias_map;
34331e4c354SMax Reitz 
34431e4c354SMax Reitz     alias_map = construct_alias_map(bbm, true, errp);
34531e4c354SMax Reitz     if (!alias_map) {
34631e4c354SMax Reitz         return false;
34731e4c354SMax Reitz     }
34831e4c354SMax Reitz     g_hash_table_destroy(alias_map);
34931e4c354SMax Reitz 
35031e4c354SMax Reitz     alias_map = construct_alias_map(bbm, false, errp);
35131e4c354SMax Reitz     if (!alias_map) {
35231e4c354SMax Reitz         return false;
35331e4c354SMax Reitz     }
35431e4c354SMax Reitz     g_hash_table_destroy(alias_map);
35531e4c354SMax Reitz 
35631e4c354SMax Reitz     return true;
35731e4c354SMax Reitz }
35831e4c354SMax Reitz 
qemu_get_bitmap_flags(QEMUFile * f)359b35ebdf0SVladimir Sementsov-Ogievskiy static uint32_t qemu_get_bitmap_flags(QEMUFile *f)
360b35ebdf0SVladimir Sementsov-Ogievskiy {
361b35ebdf0SVladimir Sementsov-Ogievskiy     uint8_t flags = qemu_get_byte(f);
362b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_EXTRA_FLAGS) {
363b35ebdf0SVladimir Sementsov-Ogievskiy         flags = flags << 8 | qemu_get_byte(f);
364b35ebdf0SVladimir Sementsov-Ogievskiy         if (flags & DIRTY_BITMAP_MIG_EXTRA_FLAGS) {
365b35ebdf0SVladimir Sementsov-Ogievskiy             flags = flags << 16 | qemu_get_be16(f);
366b35ebdf0SVladimir Sementsov-Ogievskiy         }
367b35ebdf0SVladimir Sementsov-Ogievskiy     }
368b35ebdf0SVladimir Sementsov-Ogievskiy 
369b35ebdf0SVladimir Sementsov-Ogievskiy     return flags;
370b35ebdf0SVladimir Sementsov-Ogievskiy }
371b35ebdf0SVladimir Sementsov-Ogievskiy 
qemu_put_bitmap_flags(QEMUFile * f,uint32_t flags)372b35ebdf0SVladimir Sementsov-Ogievskiy static void qemu_put_bitmap_flags(QEMUFile *f, uint32_t flags)
373b35ebdf0SVladimir Sementsov-Ogievskiy {
37437931e00SEric Blake     /* The code currently does not send flags as more than one byte */
375b35ebdf0SVladimir Sementsov-Ogievskiy     assert(!(flags & (0xffffff00 | DIRTY_BITMAP_MIG_EXTRA_FLAGS)));
376b35ebdf0SVladimir Sementsov-Ogievskiy 
377b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_byte(f, flags);
378b35ebdf0SVladimir Sementsov-Ogievskiy }
379b35ebdf0SVladimir Sementsov-Ogievskiy 
send_bitmap_header(QEMUFile * f,DBMSaveState * s,SaveBitmapState * dbms,uint32_t additional_flags)3803b52726eSVladimir Sementsov-Ogievskiy static void send_bitmap_header(QEMUFile *f, DBMSaveState *s,
3813b52726eSVladimir Sementsov-Ogievskiy                                SaveBitmapState *dbms, uint32_t additional_flags)
382b35ebdf0SVladimir Sementsov-Ogievskiy {
383b35ebdf0SVladimir Sementsov-Ogievskiy     BlockDriverState *bs = dbms->bs;
384b35ebdf0SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bitmap = dbms->bitmap;
385b35ebdf0SVladimir Sementsov-Ogievskiy     uint32_t flags = additional_flags;
386b35ebdf0SVladimir Sementsov-Ogievskiy     trace_send_bitmap_header_enter();
387b35ebdf0SVladimir Sementsov-Ogievskiy 
3883b52726eSVladimir Sementsov-Ogievskiy     if (bs != s->prev_bs) {
3893b52726eSVladimir Sementsov-Ogievskiy         s->prev_bs = bs;
390b35ebdf0SVladimir Sementsov-Ogievskiy         flags |= DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME;
391b35ebdf0SVladimir Sementsov-Ogievskiy     }
392b35ebdf0SVladimir Sementsov-Ogievskiy 
3933b52726eSVladimir Sementsov-Ogievskiy     if (bitmap != s->prev_bitmap) {
3943b52726eSVladimir Sementsov-Ogievskiy         s->prev_bitmap = bitmap;
395b35ebdf0SVladimir Sementsov-Ogievskiy         flags |= DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME;
396b35ebdf0SVladimir Sementsov-Ogievskiy     }
397b35ebdf0SVladimir Sementsov-Ogievskiy 
398b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_bitmap_flags(f, flags);
399b35ebdf0SVladimir Sementsov-Ogievskiy 
400b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) {
40131e4c354SMax Reitz         qemu_put_counted_string(f, dbms->node_alias);
402b35ebdf0SVladimir Sementsov-Ogievskiy     }
403b35ebdf0SVladimir Sementsov-Ogievskiy 
404b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
40531e4c354SMax Reitz         qemu_put_counted_string(f, dbms->bitmap_alias);
406b35ebdf0SVladimir Sementsov-Ogievskiy     }
407b35ebdf0SVladimir Sementsov-Ogievskiy }
408b35ebdf0SVladimir Sementsov-Ogievskiy 
send_bitmap_start(QEMUFile * f,DBMSaveState * s,SaveBitmapState * dbms)4093b52726eSVladimir Sementsov-Ogievskiy static void send_bitmap_start(QEMUFile *f, DBMSaveState *s,
4103b52726eSVladimir Sementsov-Ogievskiy                               SaveBitmapState *dbms)
411b35ebdf0SVladimir Sementsov-Ogievskiy {
4123b52726eSVladimir Sementsov-Ogievskiy     send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_START);
413b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_be32(f, bdrv_dirty_bitmap_granularity(dbms->bitmap));
414b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_byte(f, dbms->flags);
415b35ebdf0SVladimir Sementsov-Ogievskiy }
416b35ebdf0SVladimir Sementsov-Ogievskiy 
send_bitmap_complete(QEMUFile * f,DBMSaveState * s,SaveBitmapState * dbms)4173b52726eSVladimir Sementsov-Ogievskiy static void send_bitmap_complete(QEMUFile *f, DBMSaveState *s,
4183b52726eSVladimir Sementsov-Ogievskiy                                  SaveBitmapState *dbms)
419b35ebdf0SVladimir Sementsov-Ogievskiy {
4203b52726eSVladimir Sementsov-Ogievskiy     send_bitmap_header(f, s, dbms, DIRTY_BITMAP_MIG_FLAG_COMPLETE);
421b35ebdf0SVladimir Sementsov-Ogievskiy }
422b35ebdf0SVladimir Sementsov-Ogievskiy 
send_bitmap_bits(QEMUFile * f,DBMSaveState * s,SaveBitmapState * dbms,uint64_t start_sector,uint32_t nr_sectors)4233b52726eSVladimir Sementsov-Ogievskiy static void send_bitmap_bits(QEMUFile *f, DBMSaveState *s,
4243b52726eSVladimir Sementsov-Ogievskiy                              SaveBitmapState *dbms,
425b35ebdf0SVladimir Sementsov-Ogievskiy                              uint64_t start_sector, uint32_t nr_sectors)
426b35ebdf0SVladimir Sementsov-Ogievskiy {
427b35ebdf0SVladimir Sementsov-Ogievskiy     /* align for buffer_is_zero() */
428b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t align = 4 * sizeof(long);
429b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t unaligned_size =
430b35ebdf0SVladimir Sementsov-Ogievskiy         bdrv_dirty_bitmap_serialization_size(
431b35ebdf0SVladimir Sementsov-Ogievskiy             dbms->bitmap, start_sector << BDRV_SECTOR_BITS,
432b35ebdf0SVladimir Sementsov-Ogievskiy             (uint64_t)nr_sectors << BDRV_SECTOR_BITS);
433b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t buf_size = QEMU_ALIGN_UP(unaligned_size, align);
434b35ebdf0SVladimir Sementsov-Ogievskiy     uint8_t *buf = g_malloc0(buf_size);
435b35ebdf0SVladimir Sementsov-Ogievskiy     uint32_t flags = DIRTY_BITMAP_MIG_FLAG_BITS;
436b35ebdf0SVladimir Sementsov-Ogievskiy 
437b35ebdf0SVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_serialize_part(
438b35ebdf0SVladimir Sementsov-Ogievskiy         dbms->bitmap, buf, start_sector << BDRV_SECTOR_BITS,
439b35ebdf0SVladimir Sementsov-Ogievskiy         (uint64_t)nr_sectors << BDRV_SECTOR_BITS);
440b35ebdf0SVladimir Sementsov-Ogievskiy 
441b35ebdf0SVladimir Sementsov-Ogievskiy     if (buffer_is_zero(buf, buf_size)) {
442b35ebdf0SVladimir Sementsov-Ogievskiy         g_free(buf);
443b35ebdf0SVladimir Sementsov-Ogievskiy         buf = NULL;
444b35ebdf0SVladimir Sementsov-Ogievskiy         flags |= DIRTY_BITMAP_MIG_FLAG_ZEROES;
445b35ebdf0SVladimir Sementsov-Ogievskiy     }
446b35ebdf0SVladimir Sementsov-Ogievskiy 
447b35ebdf0SVladimir Sementsov-Ogievskiy     trace_send_bitmap_bits(flags, start_sector, nr_sectors, buf_size);
448b35ebdf0SVladimir Sementsov-Ogievskiy 
4493b52726eSVladimir Sementsov-Ogievskiy     send_bitmap_header(f, s, dbms, flags);
450b35ebdf0SVladimir Sementsov-Ogievskiy 
451b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_be64(f, start_sector);
452b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_be32(f, nr_sectors);
453b35ebdf0SVladimir Sementsov-Ogievskiy 
454b35ebdf0SVladimir Sementsov-Ogievskiy     /* if a block is zero we need to flush here since the network
455b35ebdf0SVladimir Sementsov-Ogievskiy      * bandwidth is now a lot higher than the storage device bandwidth.
456b35ebdf0SVladimir Sementsov-Ogievskiy      * thus if we queue zero blocks we slow down the migration. */
457b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_FLAG_ZEROES) {
458b35ebdf0SVladimir Sementsov-Ogievskiy         qemu_fflush(f);
459b35ebdf0SVladimir Sementsov-Ogievskiy     } else {
460b35ebdf0SVladimir Sementsov-Ogievskiy         qemu_put_be64(f, buf_size);
461b35ebdf0SVladimir Sementsov-Ogievskiy         qemu_put_buffer(f, buf, buf_size);
462b35ebdf0SVladimir Sementsov-Ogievskiy     }
463b35ebdf0SVladimir Sementsov-Ogievskiy 
464b35ebdf0SVladimir Sementsov-Ogievskiy     g_free(buf);
465b35ebdf0SVladimir Sementsov-Ogievskiy }
466b35ebdf0SVladimir Sementsov-Ogievskiy 
467a4a411fbSStefan Hajnoczi /* Called with the BQL taken.  */
dirty_bitmap_do_save_cleanup(DBMSaveState * s)4683b52726eSVladimir Sementsov-Ogievskiy static void dirty_bitmap_do_save_cleanup(DBMSaveState *s)
469b35ebdf0SVladimir Sementsov-Ogievskiy {
470fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
471b35ebdf0SVladimir Sementsov-Ogievskiy 
4723b52726eSVladimir Sementsov-Ogievskiy     while ((dbms = QSIMPLEQ_FIRST(&s->dbms_list)) != NULL) {
4733b52726eSVladimir Sementsov-Ogievskiy         QSIMPLEQ_REMOVE_HEAD(&s->dbms_list, entry);
47427a1b301SJohn Snow         bdrv_dirty_bitmap_set_busy(dbms->bitmap, false);
475b35ebdf0SVladimir Sementsov-Ogievskiy         bdrv_unref(dbms->bs);
47631e4c354SMax Reitz         g_free(dbms->node_alias);
47731e4c354SMax Reitz         g_free(dbms->bitmap_alias);
478b35ebdf0SVladimir Sementsov-Ogievskiy         g_free(dbms);
479b35ebdf0SVladimir Sementsov-Ogievskiy     }
480b35ebdf0SVladimir Sementsov-Ogievskiy }
481b35ebdf0SVladimir Sementsov-Ogievskiy 
482a4a411fbSStefan Hajnoczi /* Called with the BQL taken. */
add_bitmaps_to_list(DBMSaveState * s,BlockDriverState * bs,const char * bs_name,GHashTable * alias_map,Error ** errp)4833b52726eSVladimir Sementsov-Ogievskiy static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs,
484dd031677SCédric Le Goater                                const char *bs_name, GHashTable *alias_map,
485dd031677SCédric Le Goater                                Error **errp)
486b35ebdf0SVladimir Sementsov-Ogievskiy {
487b35ebdf0SVladimir Sementsov-Ogievskiy     BdrvDirtyBitmap *bitmap;
488fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
48931e4c354SMax Reitz     GHashTable *bitmap_aliases;
49031e4c354SMax Reitz     const char *node_alias, *bitmap_name, *bitmap_alias;
491b35ebdf0SVladimir Sementsov-Ogievskiy 
49231e4c354SMax Reitz     /* When an alias map is given, @bs_name must be @bs's node name */
49331e4c354SMax Reitz     assert(!alias_map || !strcmp(bs_name, bdrv_get_node_name(bs)));
49431e4c354SMax Reitz 
4957cb01519SVladimir Sementsov-Ogievskiy     FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
4967cb01519SVladimir Sementsov-Ogievskiy         if (bdrv_dirty_bitmap_name(bitmap)) {
4977cb01519SVladimir Sementsov-Ogievskiy             break;
4987cb01519SVladimir Sementsov-Ogievskiy         }
4997cb01519SVladimir Sementsov-Ogievskiy     }
50082640edbSVladimir Sementsov-Ogievskiy     if (!bitmap) {
50182640edbSVladimir Sementsov-Ogievskiy         return 0;
502b35ebdf0SVladimir Sementsov-Ogievskiy     }
503b35ebdf0SVladimir Sementsov-Ogievskiy 
50431e4c354SMax Reitz     bitmap_name = bdrv_dirty_bitmap_name(bitmap);
50531e4c354SMax Reitz 
50638908bbcSVladimir Sementsov-Ogievskiy     if (!bs_name || strcmp(bs_name, "") == 0) {
507dd031677SCédric Le Goater         error_setg(errp, "Bitmap '%s' in unnamed node can't be migrated",
50831e4c354SMax Reitz                    bitmap_name);
50938908bbcSVladimir Sementsov-Ogievskiy         return -1;
510b35ebdf0SVladimir Sementsov-Ogievskiy     }
511b35ebdf0SVladimir Sementsov-Ogievskiy 
51231e4c354SMax Reitz     if (alias_map) {
51331e4c354SMax Reitz         const AliasMapInnerNode *amin = g_hash_table_lookup(alias_map, bs_name);
51431e4c354SMax Reitz 
51531e4c354SMax Reitz         if (!amin) {
51631e4c354SMax Reitz             /* Skip bitmaps on nodes with no alias */
51731e4c354SMax Reitz             return 0;
51831e4c354SMax Reitz         }
51931e4c354SMax Reitz 
52031e4c354SMax Reitz         node_alias = amin->string;
52131e4c354SMax Reitz         bitmap_aliases = amin->subtree;
52231e4c354SMax Reitz     } else {
52331e4c354SMax Reitz         node_alias = bs_name;
52431e4c354SMax Reitz         bitmap_aliases = NULL;
52531e4c354SMax Reitz     }
52631e4c354SMax Reitz 
52731e4c354SMax Reitz     if (node_alias[0] == '#') {
528dd031677SCédric Le Goater         error_setg(errp, "Bitmap '%s' in a node with auto-generated "
5294ff5cc12SVladimir Sementsov-Ogievskiy                    "name '%s' can't be migrated",
53031e4c354SMax Reitz                    bitmap_name, node_alias);
5314ff5cc12SVladimir Sementsov-Ogievskiy         return -1;
5324ff5cc12SVladimir Sementsov-Ogievskiy     }
5334ff5cc12SVladimir Sementsov-Ogievskiy 
53482640edbSVladimir Sementsov-Ogievskiy     FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
5356e9f21a2SPeter Krempa         BitmapMigrationBitmapAliasTransform *bitmap_transform = NULL;
53631e4c354SMax Reitz         bitmap_name = bdrv_dirty_bitmap_name(bitmap);
53731e4c354SMax Reitz         if (!bitmap_name) {
53882640edbSVladimir Sementsov-Ogievskiy             continue;
53982640edbSVladimir Sementsov-Ogievskiy         }
54082640edbSVladimir Sementsov-Ogievskiy 
541dd031677SCédric Le Goater         if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
54238908bbcSVladimir Sementsov-Ogievskiy             return -1;
5439c98f145SVladimir Sementsov-Ogievskiy         }
5449c98f145SVladimir Sementsov-Ogievskiy 
54531e4c354SMax Reitz         if (bitmap_aliases) {
5460d1e450cSPeter Krempa             BitmapMigrationBitmapAlias *bmap_inner;
5470d1e450cSPeter Krempa 
5480d1e450cSPeter Krempa             bmap_inner = g_hash_table_lookup(bitmap_aliases, bitmap_name);
5490d1e450cSPeter Krempa             if (!bmap_inner) {
55031e4c354SMax Reitz                 /* Skip bitmaps with no alias */
55131e4c354SMax Reitz                 continue;
55231e4c354SMax Reitz             }
5530d1e450cSPeter Krempa 
5540d1e450cSPeter Krempa             bitmap_alias = bmap_inner->alias;
555720a252cSMarkus Armbruster             if (bmap_inner->transform) {
5566e9f21a2SPeter Krempa                 bitmap_transform = bmap_inner->transform;
5576e9f21a2SPeter Krempa             }
55831e4c354SMax Reitz         } else {
55931e4c354SMax Reitz             if (strlen(bitmap_name) > UINT8_MAX) {
560dd031677SCédric Le Goater                 error_setg(errp, "Cannot migrate bitmap '%s' on node '%s': "
56131e4c354SMax Reitz                            "Name is longer than %u bytes",
56231e4c354SMax Reitz                            bitmap_name, bs_name, UINT8_MAX);
56331e4c354SMax Reitz                 return -1;
56431e4c354SMax Reitz             }
56531e4c354SMax Reitz             bitmap_alias = bitmap_name;
56631e4c354SMax Reitz         }
56731e4c354SMax Reitz 
568b35ebdf0SVladimir Sementsov-Ogievskiy         bdrv_ref(bs);
56927a1b301SJohn Snow         bdrv_dirty_bitmap_set_busy(bitmap, true);
570b35ebdf0SVladimir Sementsov-Ogievskiy 
571fbbc6b14SVladimir Sementsov-Ogievskiy         dbms = g_new0(SaveBitmapState, 1);
572b35ebdf0SVladimir Sementsov-Ogievskiy         dbms->bs = bs;
57331e4c354SMax Reitz         dbms->node_alias = g_strdup(node_alias);
57431e4c354SMax Reitz         dbms->bitmap_alias = g_strdup(bitmap_alias);
575b35ebdf0SVladimir Sementsov-Ogievskiy         dbms->bitmap = bitmap;
576b35ebdf0SVladimir Sementsov-Ogievskiy         dbms->total_sectors = bdrv_nb_sectors(bs);
577ed7b70c2SStefan Reiter         dbms->sectors_per_chunk = CHUNK_SIZE * 8LLU *
578ed7b70c2SStefan Reiter             (bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS);
579ed7b70c2SStefan Reiter         assert(dbms->sectors_per_chunk != 0);
580b35ebdf0SVladimir Sementsov-Ogievskiy         if (bdrv_dirty_bitmap_enabled(bitmap)) {
581b35ebdf0SVladimir Sementsov-Ogievskiy             dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED;
582b35ebdf0SVladimir Sementsov-Ogievskiy         }
5836e9f21a2SPeter Krempa         if (bitmap_transform &&
5846e9f21a2SPeter Krempa             bitmap_transform->has_persistent) {
5856e9f21a2SPeter Krempa             if (bitmap_transform->persistent) {
5866e9f21a2SPeter Krempa                 dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT;
5876e9f21a2SPeter Krempa             }
5886e9f21a2SPeter Krempa         } else {
589796a3798SEric Blake             if (bdrv_dirty_bitmap_get_persistence(bitmap)) {
590b35ebdf0SVladimir Sementsov-Ogievskiy                 dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT;
591b35ebdf0SVladimir Sementsov-Ogievskiy             }
5926e9f21a2SPeter Krempa         }
593b35ebdf0SVladimir Sementsov-Ogievskiy 
5943b52726eSVladimir Sementsov-Ogievskiy         QSIMPLEQ_INSERT_TAIL(&s->dbms_list, dbms, entry);
595b35ebdf0SVladimir Sementsov-Ogievskiy     }
59638908bbcSVladimir Sementsov-Ogievskiy 
59738908bbcSVladimir Sementsov-Ogievskiy     return 0;
59838908bbcSVladimir Sementsov-Ogievskiy }
59938908bbcSVladimir Sementsov-Ogievskiy 
600a4a411fbSStefan Hajnoczi /* Called with the BQL taken. */
init_dirty_bitmap_migration(DBMSaveState * s,Error ** errp)601dd031677SCédric Le Goater static int init_dirty_bitmap_migration(DBMSaveState *s, Error **errp)
60238908bbcSVladimir Sementsov-Ogievskiy {
60338908bbcSVladimir Sementsov-Ogievskiy     BlockDriverState *bs;
604fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
605107cfb72SVladimir Sementsov-Ogievskiy     GHashTable *handled_by_blk = g_hash_table_new(NULL, NULL);
606107cfb72SVladimir Sementsov-Ogievskiy     BlockBackend *blk;
60731e4c354SMax Reitz     GHashTable *alias_map = NULL;
60831e4c354SMax Reitz 
609a4a411fbSStefan Hajnoczi     /* Runs in the migration thread, but holds the BQL */
610f5a3a270SKevin Wolf     GLOBAL_STATE_CODE();
611f5a3a270SKevin Wolf     GRAPH_RDLOCK_GUARD_MAINLOOP();
612f5a3a270SKevin Wolf 
6133cba22c9SJuan Quintela     if (migrate_has_block_bitmap_mapping()) {
6143cba22c9SJuan Quintela         alias_map = construct_alias_map(migrate_block_bitmap_mapping(), true,
61531e4c354SMax Reitz                                         &error_abort);
61631e4c354SMax Reitz     }
61738908bbcSVladimir Sementsov-Ogievskiy 
6183b52726eSVladimir Sementsov-Ogievskiy     s->bulk_completed = false;
6193b52726eSVladimir Sementsov-Ogievskiy     s->prev_bs = NULL;
6203b52726eSVladimir Sementsov-Ogievskiy     s->prev_bitmap = NULL;
6213b52726eSVladimir Sementsov-Ogievskiy     s->no_bitmaps = false;
62238908bbcSVladimir Sementsov-Ogievskiy 
62331e4c354SMax Reitz     if (!alias_map) {
624107cfb72SVladimir Sementsov-Ogievskiy         /*
625107cfb72SVladimir Sementsov-Ogievskiy          * Use blockdevice name for direct (or filtered) children of named block
626107cfb72SVladimir Sementsov-Ogievskiy          * backends.
627107cfb72SVladimir Sementsov-Ogievskiy          */
628107cfb72SVladimir Sementsov-Ogievskiy         for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
629107cfb72SVladimir Sementsov-Ogievskiy             const char *name = blk_name(blk);
630107cfb72SVladimir Sementsov-Ogievskiy 
631107cfb72SVladimir Sementsov-Ogievskiy             if (!name || strcmp(name, "") == 0) {
632107cfb72SVladimir Sementsov-Ogievskiy                 continue;
633107cfb72SVladimir Sementsov-Ogievskiy             }
634107cfb72SVladimir Sementsov-Ogievskiy 
635107cfb72SVladimir Sementsov-Ogievskiy             bs = blk_bs(blk);
636107cfb72SVladimir Sementsov-Ogievskiy 
637107cfb72SVladimir Sementsov-Ogievskiy             /* Skip filters without bitmaps */
638107cfb72SVladimir Sementsov-Ogievskiy             while (bs && bs->drv && bs->drv->is_filter &&
639107cfb72SVladimir Sementsov-Ogievskiy                    !bdrv_has_named_bitmaps(bs))
640107cfb72SVladimir Sementsov-Ogievskiy             {
64193393e69SMax Reitz                 bs = bdrv_filter_bs(bs);
642107cfb72SVladimir Sementsov-Ogievskiy             }
643107cfb72SVladimir Sementsov-Ogievskiy 
644107cfb72SVladimir Sementsov-Ogievskiy             if (bs && bs->drv && !bs->drv->is_filter) {
645dd031677SCédric Le Goater                 if (add_bitmaps_to_list(s, bs, name, NULL, errp)) {
646107cfb72SVladimir Sementsov-Ogievskiy                     goto fail;
647107cfb72SVladimir Sementsov-Ogievskiy                 }
648107cfb72SVladimir Sementsov-Ogievskiy                 g_hash_table_add(handled_by_blk, bs);
649107cfb72SVladimir Sementsov-Ogievskiy             }
650107cfb72SVladimir Sementsov-Ogievskiy         }
65131e4c354SMax Reitz     }
652107cfb72SVladimir Sementsov-Ogievskiy 
65338908bbcSVladimir Sementsov-Ogievskiy     for (bs = bdrv_next_all_states(NULL); bs; bs = bdrv_next_all_states(bs)) {
654107cfb72SVladimir Sementsov-Ogievskiy         if (g_hash_table_contains(handled_by_blk, bs)) {
655107cfb72SVladimir Sementsov-Ogievskiy             continue;
656107cfb72SVladimir Sementsov-Ogievskiy         }
657107cfb72SVladimir Sementsov-Ogievskiy 
658dd031677SCédric Le Goater         if (add_bitmaps_to_list(s, bs, bdrv_get_node_name(bs), alias_map,
659dd031677SCédric Le Goater                                 errp)) {
66038908bbcSVladimir Sementsov-Ogievskiy             goto fail;
66138908bbcSVladimir Sementsov-Ogievskiy         }
662b35ebdf0SVladimir Sementsov-Ogievskiy     }
663b35ebdf0SVladimir Sementsov-Ogievskiy 
6649c98f145SVladimir Sementsov-Ogievskiy     /* unset migration flags here, to not roll back it */
6653b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
666c4e4b0faSJohn Snow         bdrv_dirty_bitmap_skip_store(dbms->bitmap, true);
667b35ebdf0SVladimir Sementsov-Ogievskiy     }
668b35ebdf0SVladimir Sementsov-Ogievskiy 
6693b52726eSVladimir Sementsov-Ogievskiy     if (QSIMPLEQ_EMPTY(&s->dbms_list)) {
6703b52726eSVladimir Sementsov-Ogievskiy         s->no_bitmaps = true;
671b35ebdf0SVladimir Sementsov-Ogievskiy     }
672b35ebdf0SVladimir Sementsov-Ogievskiy 
673107cfb72SVladimir Sementsov-Ogievskiy     g_hash_table_destroy(handled_by_blk);
67431e4c354SMax Reitz     if (alias_map) {
67531e4c354SMax Reitz         g_hash_table_destroy(alias_map);
67631e4c354SMax Reitz     }
677107cfb72SVladimir Sementsov-Ogievskiy 
678b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
679b35ebdf0SVladimir Sementsov-Ogievskiy 
680b35ebdf0SVladimir Sementsov-Ogievskiy fail:
681107cfb72SVladimir Sementsov-Ogievskiy     g_hash_table_destroy(handled_by_blk);
68231e4c354SMax Reitz     if (alias_map) {
68331e4c354SMax Reitz         g_hash_table_destroy(alias_map);
68431e4c354SMax Reitz     }
6853b52726eSVladimir Sementsov-Ogievskiy     dirty_bitmap_do_save_cleanup(s);
686b35ebdf0SVladimir Sementsov-Ogievskiy 
687b35ebdf0SVladimir Sementsov-Ogievskiy     return -1;
688b35ebdf0SVladimir Sementsov-Ogievskiy }
689b35ebdf0SVladimir Sementsov-Ogievskiy 
690b35ebdf0SVladimir Sementsov-Ogievskiy /* Called with no lock taken.  */
bulk_phase_send_chunk(QEMUFile * f,DBMSaveState * s,SaveBitmapState * dbms)6913b52726eSVladimir Sementsov-Ogievskiy static void bulk_phase_send_chunk(QEMUFile *f, DBMSaveState *s,
6923b52726eSVladimir Sementsov-Ogievskiy                                   SaveBitmapState *dbms)
693b35ebdf0SVladimir Sementsov-Ogievskiy {
694b35ebdf0SVladimir Sementsov-Ogievskiy     uint32_t nr_sectors = MIN(dbms->total_sectors - dbms->cur_sector,
695b35ebdf0SVladimir Sementsov-Ogievskiy                              dbms->sectors_per_chunk);
696b35ebdf0SVladimir Sementsov-Ogievskiy 
6973b52726eSVladimir Sementsov-Ogievskiy     send_bitmap_bits(f, s, dbms, dbms->cur_sector, nr_sectors);
698b35ebdf0SVladimir Sementsov-Ogievskiy 
699b35ebdf0SVladimir Sementsov-Ogievskiy     dbms->cur_sector += nr_sectors;
700b35ebdf0SVladimir Sementsov-Ogievskiy     if (dbms->cur_sector >= dbms->total_sectors) {
701b35ebdf0SVladimir Sementsov-Ogievskiy         dbms->bulk_completed = true;
702b35ebdf0SVladimir Sementsov-Ogievskiy     }
703b35ebdf0SVladimir Sementsov-Ogievskiy }
704b35ebdf0SVladimir Sementsov-Ogievskiy 
705b35ebdf0SVladimir Sementsov-Ogievskiy /* Called with no lock taken.  */
bulk_phase(QEMUFile * f,DBMSaveState * s,bool limit)7063b52726eSVladimir Sementsov-Ogievskiy static void bulk_phase(QEMUFile *f, DBMSaveState *s, bool limit)
707b35ebdf0SVladimir Sementsov-Ogievskiy {
708fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
709b35ebdf0SVladimir Sementsov-Ogievskiy 
7103b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
711b35ebdf0SVladimir Sementsov-Ogievskiy         while (!dbms->bulk_completed) {
7123b52726eSVladimir Sementsov-Ogievskiy             bulk_phase_send_chunk(f, s, dbms);
713e1fde0e0SJuan Quintela             if (limit && migration_rate_exceeded(f)) {
714b35ebdf0SVladimir Sementsov-Ogievskiy                 return;
715b35ebdf0SVladimir Sementsov-Ogievskiy             }
716b35ebdf0SVladimir Sementsov-Ogievskiy         }
717b35ebdf0SVladimir Sementsov-Ogievskiy     }
718b35ebdf0SVladimir Sementsov-Ogievskiy 
7193b52726eSVladimir Sementsov-Ogievskiy     s->bulk_completed = true;
720b35ebdf0SVladimir Sementsov-Ogievskiy }
721b35ebdf0SVladimir Sementsov-Ogievskiy 
722b35ebdf0SVladimir Sementsov-Ogievskiy /* for SaveVMHandlers */
dirty_bitmap_save_cleanup(void * opaque)723b35ebdf0SVladimir Sementsov-Ogievskiy static void dirty_bitmap_save_cleanup(void *opaque)
724b35ebdf0SVladimir Sementsov-Ogievskiy {
7253b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
7263b52726eSVladimir Sementsov-Ogievskiy 
7273b52726eSVladimir Sementsov-Ogievskiy     dirty_bitmap_do_save_cleanup(s);
728b35ebdf0SVladimir Sementsov-Ogievskiy }
729b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_save_iterate(QEMUFile * f,void * opaque)730b35ebdf0SVladimir Sementsov-Ogievskiy static int dirty_bitmap_save_iterate(QEMUFile *f, void *opaque)
731b35ebdf0SVladimir Sementsov-Ogievskiy {
7323b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
7333b52726eSVladimir Sementsov-Ogievskiy 
734b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_save_iterate(migration_in_postcopy());
735b35ebdf0SVladimir Sementsov-Ogievskiy 
7363b52726eSVladimir Sementsov-Ogievskiy     if (migration_in_postcopy() && !s->bulk_completed) {
7373b52726eSVladimir Sementsov-Ogievskiy         bulk_phase(f, s, true);
738b35ebdf0SVladimir Sementsov-Ogievskiy     }
739b35ebdf0SVladimir Sementsov-Ogievskiy 
740b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
741b35ebdf0SVladimir Sementsov-Ogievskiy 
7423b52726eSVladimir Sementsov-Ogievskiy     return s->bulk_completed;
743b35ebdf0SVladimir Sementsov-Ogievskiy }
744b35ebdf0SVladimir Sementsov-Ogievskiy 
745a4a411fbSStefan Hajnoczi /* Called with the BQL taken.  */
746b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_save_complete(QEMUFile * f,void * opaque)747b35ebdf0SVladimir Sementsov-Ogievskiy static int dirty_bitmap_save_complete(QEMUFile *f, void *opaque)
748b35ebdf0SVladimir Sementsov-Ogievskiy {
7493b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
750fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
751b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_save_complete_enter();
752b35ebdf0SVladimir Sementsov-Ogievskiy 
7533b52726eSVladimir Sementsov-Ogievskiy     if (!s->bulk_completed) {
7543b52726eSVladimir Sementsov-Ogievskiy         bulk_phase(f, s, false);
755b35ebdf0SVladimir Sementsov-Ogievskiy     }
756b35ebdf0SVladimir Sementsov-Ogievskiy 
7573b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
7583b52726eSVladimir Sementsov-Ogievskiy         send_bitmap_complete(f, s, dbms);
759b35ebdf0SVladimir Sementsov-Ogievskiy     }
760b35ebdf0SVladimir Sementsov-Ogievskiy 
761b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
762b35ebdf0SVladimir Sementsov-Ogievskiy 
763b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_save_complete_finish();
764b35ebdf0SVladimir Sementsov-Ogievskiy 
7653b52726eSVladimir Sementsov-Ogievskiy     dirty_bitmap_save_cleanup(opaque);
766b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
767b35ebdf0SVladimir Sementsov-Ogievskiy }
768b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_state_pending(void * opaque,uint64_t * must_precopy,uint64_t * can_postcopy)769c8df4a7aSJuan Quintela static void dirty_bitmap_state_pending(void *opaque,
77024beea4eSJuan Quintela                                        uint64_t *must_precopy,
77124beea4eSJuan Quintela                                        uint64_t *can_postcopy)
772b35ebdf0SVladimir Sementsov-Ogievskiy {
7733b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
774fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms;
775b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t pending = 0;
776b35ebdf0SVladimir Sementsov-Ogievskiy 
777195801d7SStefan Hajnoczi     bql_lock();
778b35ebdf0SVladimir Sementsov-Ogievskiy 
7793b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
780b35ebdf0SVladimir Sementsov-Ogievskiy         uint64_t gran = bdrv_dirty_bitmap_granularity(dbms->bitmap);
781b35ebdf0SVladimir Sementsov-Ogievskiy         uint64_t sectors = dbms->bulk_completed ? 0 :
782b35ebdf0SVladimir Sementsov-Ogievskiy                            dbms->total_sectors - dbms->cur_sector;
783b35ebdf0SVladimir Sementsov-Ogievskiy 
784b35ebdf0SVladimir Sementsov-Ogievskiy         pending += DIV_ROUND_UP(sectors * BDRV_SECTOR_SIZE, gran);
785b35ebdf0SVladimir Sementsov-Ogievskiy     }
786b35ebdf0SVladimir Sementsov-Ogievskiy 
787195801d7SStefan Hajnoczi     bql_unlock();
788b35ebdf0SVladimir Sementsov-Ogievskiy 
789c8df4a7aSJuan Quintela     trace_dirty_bitmap_state_pending(pending);
790b35ebdf0SVladimir Sementsov-Ogievskiy 
79124beea4eSJuan Quintela     *can_postcopy += pending;
792b35ebdf0SVladimir Sementsov-Ogievskiy }
793b35ebdf0SVladimir Sementsov-Ogievskiy 
794b35ebdf0SVladimir Sementsov-Ogievskiy /* First occurrence of this bitmap. It should be created if doesn't exist */
dirty_bitmap_load_start(QEMUFile * f,DBMLoadState * s)795fbbc6b14SVladimir Sementsov-Ogievskiy static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s)
796b35ebdf0SVladimir Sementsov-Ogievskiy {
797b35ebdf0SVladimir Sementsov-Ogievskiy     Error *local_err = NULL;
798b35ebdf0SVladimir Sementsov-Ogievskiy     uint32_t granularity = qemu_get_be32(f);
799b35ebdf0SVladimir Sementsov-Ogievskiy     uint8_t flags = qemu_get_byte(f);
8000a47190aSVladimir Sementsov-Ogievskiy     LoadBitmapState *b;
8016e9f21a2SPeter Krempa     bool persistent;
802b35ebdf0SVladimir Sementsov-Ogievskiy 
803b91f33b8SVladimir Sementsov-Ogievskiy     if (s->cancelled) {
804b91f33b8SVladimir Sementsov-Ogievskiy         return 0;
805b91f33b8SVladimir Sementsov-Ogievskiy     }
806b91f33b8SVladimir Sementsov-Ogievskiy 
807b35ebdf0SVladimir Sementsov-Ogievskiy     if (s->bitmap) {
808b35ebdf0SVladimir Sementsov-Ogievskiy         error_report("Bitmap with the same name ('%s') already exists on "
809b35ebdf0SVladimir Sementsov-Ogievskiy                      "destination", bdrv_dirty_bitmap_name(s->bitmap));
810b35ebdf0SVladimir Sementsov-Ogievskiy         return -EINVAL;
811b35ebdf0SVladimir Sementsov-Ogievskiy     } else {
812b35ebdf0SVladimir Sementsov-Ogievskiy         s->bitmap = bdrv_create_dirty_bitmap(s->bs, granularity,
813b35ebdf0SVladimir Sementsov-Ogievskiy                                              s->bitmap_name, &local_err);
814b35ebdf0SVladimir Sementsov-Ogievskiy         if (!s->bitmap) {
815b35ebdf0SVladimir Sementsov-Ogievskiy             error_report_err(local_err);
816b35ebdf0SVladimir Sementsov-Ogievskiy             return -EINVAL;
817b35ebdf0SVladimir Sementsov-Ogievskiy         }
818b35ebdf0SVladimir Sementsov-Ogievskiy     }
819b35ebdf0SVladimir Sementsov-Ogievskiy 
820b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_START_FLAG_RESERVED_MASK) {
821b35ebdf0SVladimir Sementsov-Ogievskiy         error_report("Unknown flags in migrated dirty bitmap header: %x",
822b35ebdf0SVladimir Sementsov-Ogievskiy                      flags);
823b35ebdf0SVladimir Sementsov-Ogievskiy         return -EINVAL;
824b35ebdf0SVladimir Sementsov-Ogievskiy     }
825b35ebdf0SVladimir Sementsov-Ogievskiy 
8266e9f21a2SPeter Krempa     if (s->bmap_inner &&
827720a252cSMarkus Armbruster         s->bmap_inner->transform &&
8286e9f21a2SPeter Krempa         s->bmap_inner->transform->has_persistent) {
8296e9f21a2SPeter Krempa         persistent = s->bmap_inner->transform->persistent;
8306e9f21a2SPeter Krempa     } else {
8316e9f21a2SPeter Krempa         persistent = flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT;
8326e9f21a2SPeter Krempa     }
8336e9f21a2SPeter Krempa 
8346e9f21a2SPeter Krempa     if (persistent) {
835796a3798SEric Blake         bdrv_dirty_bitmap_set_persistence(s->bitmap, true);
836b35ebdf0SVladimir Sementsov-Ogievskiy     }
837b35ebdf0SVladimir Sementsov-Ogievskiy 
838b35ebdf0SVladimir Sementsov-Ogievskiy     bdrv_disable_dirty_bitmap(s->bitmap);
839b35ebdf0SVladimir Sementsov-Ogievskiy     if (flags & DIRTY_BITMAP_MIG_START_FLAG_ENABLED) {
8405deb6cbdSVladimir Sementsov-Ogievskiy         bdrv_dirty_bitmap_create_successor(s->bitmap, &local_err);
841b35ebdf0SVladimir Sementsov-Ogievskiy         if (local_err) {
842b35ebdf0SVladimir Sementsov-Ogievskiy             error_report_err(local_err);
843b35ebdf0SVladimir Sementsov-Ogievskiy             return -EINVAL;
844b35ebdf0SVladimir Sementsov-Ogievskiy         }
8454290b483SVladimir Sementsov-Ogievskiy     } else {
8464290b483SVladimir Sementsov-Ogievskiy         bdrv_dirty_bitmap_set_busy(s->bitmap, true);
8470a47190aSVladimir Sementsov-Ogievskiy     }
848b35ebdf0SVladimir Sementsov-Ogievskiy 
849fbbc6b14SVladimir Sementsov-Ogievskiy     b = g_new(LoadBitmapState, 1);
850b35ebdf0SVladimir Sementsov-Ogievskiy     b->bs = s->bs;
851b35ebdf0SVladimir Sementsov-Ogievskiy     b->bitmap = s->bitmap;
852b35ebdf0SVladimir Sementsov-Ogievskiy     b->migrated = false;
8530a47190aSVladimir Sementsov-Ogievskiy     b->enabled = flags & DIRTY_BITMAP_MIG_START_FLAG_ENABLED;
8540a47190aSVladimir Sementsov-Ogievskiy 
8550a47190aSVladimir Sementsov-Ogievskiy     s->bitmaps = g_slist_prepend(s->bitmaps, b);
856b35ebdf0SVladimir Sementsov-Ogievskiy 
857b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
858b35ebdf0SVladimir Sementsov-Ogievskiy }
859b35ebdf0SVladimir Sementsov-Ogievskiy 
8600a47190aSVladimir Sementsov-Ogievskiy /*
8610a47190aSVladimir Sementsov-Ogievskiy  * before_vm_start_handle_item
8620a47190aSVladimir Sementsov-Ogievskiy  *
8630a47190aSVladimir Sementsov-Ogievskiy  * g_slist_foreach helper
8640a47190aSVladimir Sementsov-Ogievskiy  *
8650a47190aSVladimir Sementsov-Ogievskiy  * item is LoadBitmapState*
8660a47190aSVladimir Sementsov-Ogievskiy  * opaque is DBMLoadState*
8670a47190aSVladimir Sementsov-Ogievskiy  */
before_vm_start_handle_item(void * item,void * opaque)8680a47190aSVladimir Sementsov-Ogievskiy static void before_vm_start_handle_item(void *item, void *opaque)
869b35ebdf0SVladimir Sementsov-Ogievskiy {
8700a47190aSVladimir Sementsov-Ogievskiy     DBMLoadState *s = opaque;
8710a47190aSVladimir Sementsov-Ogievskiy     LoadBitmapState *b = item;
872b35ebdf0SVladimir Sementsov-Ogievskiy 
8730a47190aSVladimir Sementsov-Ogievskiy     if (b->enabled) {
874b35ebdf0SVladimir Sementsov-Ogievskiy         if (b->migrated) {
875e6ce5e92SVladimir Sementsov-Ogievskiy             bdrv_enable_dirty_bitmap(b->bitmap);
876b35ebdf0SVladimir Sementsov-Ogievskiy         } else {
877b35ebdf0SVladimir Sementsov-Ogievskiy             bdrv_dirty_bitmap_enable_successor(b->bitmap);
878b35ebdf0SVladimir Sementsov-Ogievskiy         }
879b35ebdf0SVladimir Sementsov-Ogievskiy     }
880b35ebdf0SVladimir Sementsov-Ogievskiy 
8810a47190aSVladimir Sementsov-Ogievskiy     if (b->migrated) {
8820a47190aSVladimir Sementsov-Ogievskiy         s->bitmaps = g_slist_remove(s->bitmaps, b);
8830a47190aSVladimir Sementsov-Ogievskiy         g_free(b);
8840a47190aSVladimir Sementsov-Ogievskiy     }
8850a47190aSVladimir Sementsov-Ogievskiy }
8860a47190aSVladimir Sementsov-Ogievskiy 
dirty_bitmap_mig_before_vm_start(void)8870a47190aSVladimir Sementsov-Ogievskiy void dirty_bitmap_mig_before_vm_start(void)
8880a47190aSVladimir Sementsov-Ogievskiy {
8890a47190aSVladimir Sementsov-Ogievskiy     DBMLoadState *s = &dbm_state.load;
8900a47190aSVladimir Sementsov-Ogievskiy     qemu_mutex_lock(&s->lock);
8910a47190aSVladimir Sementsov-Ogievskiy 
8920a47190aSVladimir Sementsov-Ogievskiy     assert(!s->before_vm_start_handled);
8930a47190aSVladimir Sementsov-Ogievskiy     g_slist_foreach(s->bitmaps, before_vm_start_handle_item, s);
8940a47190aSVladimir Sementsov-Ogievskiy     s->before_vm_start_handled = true;
895b35ebdf0SVladimir Sementsov-Ogievskiy 
89689491216SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(&s->lock);
897b35ebdf0SVladimir Sementsov-Ogievskiy }
898b35ebdf0SVladimir Sementsov-Ogievskiy 
cancel_incoming_locked(DBMLoadState * s)899b91f33b8SVladimir Sementsov-Ogievskiy static void cancel_incoming_locked(DBMLoadState *s)
900b91f33b8SVladimir Sementsov-Ogievskiy {
901b91f33b8SVladimir Sementsov-Ogievskiy     GSList *item;
902b91f33b8SVladimir Sementsov-Ogievskiy 
903b91f33b8SVladimir Sementsov-Ogievskiy     if (s->cancelled) {
904b91f33b8SVladimir Sementsov-Ogievskiy         return;
905b91f33b8SVladimir Sementsov-Ogievskiy     }
906b91f33b8SVladimir Sementsov-Ogievskiy 
907b91f33b8SVladimir Sementsov-Ogievskiy     s->cancelled = true;
908b91f33b8SVladimir Sementsov-Ogievskiy     s->bs = NULL;
909b91f33b8SVladimir Sementsov-Ogievskiy     s->bitmap = NULL;
910b91f33b8SVladimir Sementsov-Ogievskiy 
911b91f33b8SVladimir Sementsov-Ogievskiy     /* Drop all unfinished bitmaps */
912b91f33b8SVladimir Sementsov-Ogievskiy     for (item = s->bitmaps; item; item = g_slist_next(item)) {
913b91f33b8SVladimir Sementsov-Ogievskiy         LoadBitmapState *b = item->data;
914b91f33b8SVladimir Sementsov-Ogievskiy 
915b91f33b8SVladimir Sementsov-Ogievskiy         /*
916b91f33b8SVladimir Sementsov-Ogievskiy          * Bitmap must be unfinished, as finished bitmaps should already be
917b91f33b8SVladimir Sementsov-Ogievskiy          * removed from the list.
918b91f33b8SVladimir Sementsov-Ogievskiy          */
919b91f33b8SVladimir Sementsov-Ogievskiy         assert(!s->before_vm_start_handled || !b->migrated);
920b91f33b8SVladimir Sementsov-Ogievskiy         if (bdrv_dirty_bitmap_has_successor(b->bitmap)) {
921b91f33b8SVladimir Sementsov-Ogievskiy             bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort);
9224290b483SVladimir Sementsov-Ogievskiy         } else {
9234290b483SVladimir Sementsov-Ogievskiy             bdrv_dirty_bitmap_set_busy(b->bitmap, false);
924b91f33b8SVladimir Sementsov-Ogievskiy         }
925b91f33b8SVladimir Sementsov-Ogievskiy         bdrv_release_dirty_bitmap(b->bitmap);
926b91f33b8SVladimir Sementsov-Ogievskiy     }
927b91f33b8SVladimir Sementsov-Ogievskiy 
928b91f33b8SVladimir Sementsov-Ogievskiy     g_slist_free_full(s->bitmaps, g_free);
929b91f33b8SVladimir Sementsov-Ogievskiy     s->bitmaps = NULL;
930b91f33b8SVladimir Sementsov-Ogievskiy }
931b91f33b8SVladimir Sementsov-Ogievskiy 
dirty_bitmap_mig_cancel_outgoing(void)9321499ab09SVladimir Sementsov-Ogievskiy void dirty_bitmap_mig_cancel_outgoing(void)
9331499ab09SVladimir Sementsov-Ogievskiy {
9341499ab09SVladimir Sementsov-Ogievskiy     dirty_bitmap_do_save_cleanup(&dbm_state.save);
9351499ab09SVladimir Sementsov-Ogievskiy }
9361499ab09SVladimir Sementsov-Ogievskiy 
dirty_bitmap_mig_cancel_incoming(void)9371499ab09SVladimir Sementsov-Ogievskiy void dirty_bitmap_mig_cancel_incoming(void)
9381499ab09SVladimir Sementsov-Ogievskiy {
9391499ab09SVladimir Sementsov-Ogievskiy     DBMLoadState *s = &dbm_state.load;
9401499ab09SVladimir Sementsov-Ogievskiy 
9411499ab09SVladimir Sementsov-Ogievskiy     qemu_mutex_lock(&s->lock);
9421499ab09SVladimir Sementsov-Ogievskiy 
9431499ab09SVladimir Sementsov-Ogievskiy     cancel_incoming_locked(s);
9441499ab09SVladimir Sementsov-Ogievskiy 
9451499ab09SVladimir Sementsov-Ogievskiy     qemu_mutex_unlock(&s->lock);
9461499ab09SVladimir Sementsov-Ogievskiy }
9471499ab09SVladimir Sementsov-Ogievskiy 
dirty_bitmap_load_complete(QEMUFile * f,DBMLoadState * s)948fbbc6b14SVladimir Sementsov-Ogievskiy static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
949b35ebdf0SVladimir Sementsov-Ogievskiy {
950b35ebdf0SVladimir Sementsov-Ogievskiy     GSList *item;
951b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_load_complete();
952b35ebdf0SVladimir Sementsov-Ogievskiy 
953b91f33b8SVladimir Sementsov-Ogievskiy     if (s->cancelled) {
954b91f33b8SVladimir Sementsov-Ogievskiy         return;
955b91f33b8SVladimir Sementsov-Ogievskiy     }
956b91f33b8SVladimir Sementsov-Ogievskiy 
957b91f33b8SVladimir Sementsov-Ogievskiy     bdrv_dirty_bitmap_deserialize_finish(s->bitmap);
958b35ebdf0SVladimir Sementsov-Ogievskiy 
959f3045b9aSVladimir Sementsov-Ogievskiy     if (bdrv_dirty_bitmap_has_successor(s->bitmap)) {
960f3045b9aSVladimir Sementsov-Ogievskiy         bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort);
9614290b483SVladimir Sementsov-Ogievskiy     } else {
9624290b483SVladimir Sementsov-Ogievskiy         bdrv_dirty_bitmap_set_busy(s->bitmap, false);
963f3045b9aSVladimir Sementsov-Ogievskiy     }
964f3045b9aSVladimir Sementsov-Ogievskiy 
9650a47190aSVladimir Sementsov-Ogievskiy     for (item = s->bitmaps; item; item = g_slist_next(item)) {
966fbbc6b14SVladimir Sementsov-Ogievskiy         LoadBitmapState *b = item->data;
967b35ebdf0SVladimir Sementsov-Ogievskiy 
968b35ebdf0SVladimir Sementsov-Ogievskiy         if (b->bitmap == s->bitmap) {
969b35ebdf0SVladimir Sementsov-Ogievskiy             b->migrated = true;
9700a47190aSVladimir Sementsov-Ogievskiy             if (s->before_vm_start_handled) {
9710a47190aSVladimir Sementsov-Ogievskiy                 s->bitmaps = g_slist_remove(s->bitmaps, b);
9720a47190aSVladimir Sementsov-Ogievskiy                 g_free(b);
9730a47190aSVladimir Sementsov-Ogievskiy             }
974b35ebdf0SVladimir Sementsov-Ogievskiy             break;
975b35ebdf0SVladimir Sementsov-Ogievskiy         }
976b35ebdf0SVladimir Sementsov-Ogievskiy     }
977b35ebdf0SVladimir Sementsov-Ogievskiy }
978b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_load_bits(QEMUFile * f,DBMLoadState * s)979fbbc6b14SVladimir Sementsov-Ogievskiy static int dirty_bitmap_load_bits(QEMUFile *f, DBMLoadState *s)
980b35ebdf0SVladimir Sementsov-Ogievskiy {
981b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t first_byte = qemu_get_be64(f) << BDRV_SECTOR_BITS;
982b35ebdf0SVladimir Sementsov-Ogievskiy     uint64_t nr_bytes = (uint64_t)qemu_get_be32(f) << BDRV_SECTOR_BITS;
983b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_load_bits_enter(first_byte >> BDRV_SECTOR_BITS,
984b35ebdf0SVladimir Sementsov-Ogievskiy                                        nr_bytes >> BDRV_SECTOR_BITS);
985b35ebdf0SVladimir Sementsov-Ogievskiy 
986b35ebdf0SVladimir Sementsov-Ogievskiy     if (s->flags & DIRTY_BITMAP_MIG_FLAG_ZEROES) {
987b35ebdf0SVladimir Sementsov-Ogievskiy         trace_dirty_bitmap_load_bits_zeroes();
988b91f33b8SVladimir Sementsov-Ogievskiy         if (!s->cancelled) {
989b91f33b8SVladimir Sementsov-Ogievskiy             bdrv_dirty_bitmap_deserialize_zeroes(s->bitmap, first_byte,
990b91f33b8SVladimir Sementsov-Ogievskiy                                                  nr_bytes, false);
991b91f33b8SVladimir Sementsov-Ogievskiy         }
992b35ebdf0SVladimir Sementsov-Ogievskiy     } else {
993b35ebdf0SVladimir Sementsov-Ogievskiy         size_t ret;
994b91f33b8SVladimir Sementsov-Ogievskiy         g_autofree uint8_t *buf = NULL;
995b35ebdf0SVladimir Sementsov-Ogievskiy         uint64_t buf_size = qemu_get_be64(f);
996b91f33b8SVladimir Sementsov-Ogievskiy         uint64_t needed_size;
997b91f33b8SVladimir Sementsov-Ogievskiy 
998b91f33b8SVladimir Sementsov-Ogievskiy         /*
999b91f33b8SVladimir Sementsov-Ogievskiy          * The actual check for buf_size is done a bit later. We can't do it in
1000b91f33b8SVladimir Sementsov-Ogievskiy          * cancelled mode as we don't have the bitmap to check the constraints
1001b91f33b8SVladimir Sementsov-Ogievskiy          * (so, we allocate a buffer and read prior to the check). On the other
1002b91f33b8SVladimir Sementsov-Ogievskiy          * hand, we shouldn't blindly g_malloc the number from the stream.
1003b91f33b8SVladimir Sementsov-Ogievskiy          * Actually one chunk should not be larger than CHUNK_SIZE. Let's allow
1004b91f33b8SVladimir Sementsov-Ogievskiy          * a bit larger (which means that bitmap migration will fail anyway and
1005b91f33b8SVladimir Sementsov-Ogievskiy          * the whole migration will most probably fail soon due to broken
1006b91f33b8SVladimir Sementsov-Ogievskiy          * stream).
1007b91f33b8SVladimir Sementsov-Ogievskiy          */
1008b91f33b8SVladimir Sementsov-Ogievskiy         if (buf_size > 10 * CHUNK_SIZE) {
1009b91f33b8SVladimir Sementsov-Ogievskiy             error_report("Bitmap migration stream buffer allocation request "
1010b91f33b8SVladimir Sementsov-Ogievskiy                          "is too large");
1011b91f33b8SVladimir Sementsov-Ogievskiy             return -EIO;
1012b91f33b8SVladimir Sementsov-Ogievskiy         }
1013b91f33b8SVladimir Sementsov-Ogievskiy 
1014b91f33b8SVladimir Sementsov-Ogievskiy         buf = g_malloc(buf_size);
1015b91f33b8SVladimir Sementsov-Ogievskiy         ret = qemu_get_buffer(f, buf, buf_size);
1016b91f33b8SVladimir Sementsov-Ogievskiy         if (ret != buf_size) {
1017b91f33b8SVladimir Sementsov-Ogievskiy             error_report("Failed to read bitmap bits");
1018b91f33b8SVladimir Sementsov-Ogievskiy             return -EIO;
1019b91f33b8SVladimir Sementsov-Ogievskiy         }
1020b91f33b8SVladimir Sementsov-Ogievskiy 
1021b91f33b8SVladimir Sementsov-Ogievskiy         if (s->cancelled) {
1022b91f33b8SVladimir Sementsov-Ogievskiy             return 0;
1023b91f33b8SVladimir Sementsov-Ogievskiy         }
1024b91f33b8SVladimir Sementsov-Ogievskiy 
1025b91f33b8SVladimir Sementsov-Ogievskiy         needed_size = bdrv_dirty_bitmap_serialization_size(s->bitmap,
1026b91f33b8SVladimir Sementsov-Ogievskiy                                                            first_byte,
1027b91f33b8SVladimir Sementsov-Ogievskiy                                                            nr_bytes);
1028b35ebdf0SVladimir Sementsov-Ogievskiy 
1029b35ebdf0SVladimir Sementsov-Ogievskiy         if (needed_size > buf_size ||
1030b35ebdf0SVladimir Sementsov-Ogievskiy             buf_size > QEMU_ALIGN_UP(needed_size, 4 * sizeof(long))
1031b35ebdf0SVladimir Sementsov-Ogievskiy              /* Here used same alignment as in send_bitmap_bits */
1032b35ebdf0SVladimir Sementsov-Ogievskiy         ) {
1033b35ebdf0SVladimir Sementsov-Ogievskiy             error_report("Migrated bitmap granularity doesn't "
1034b35ebdf0SVladimir Sementsov-Ogievskiy                          "match the destination bitmap '%s' granularity",
1035b35ebdf0SVladimir Sementsov-Ogievskiy                          bdrv_dirty_bitmap_name(s->bitmap));
1036b91f33b8SVladimir Sementsov-Ogievskiy             cancel_incoming_locked(s);
1037b91f33b8SVladimir Sementsov-Ogievskiy             return 0;
1038b35ebdf0SVladimir Sementsov-Ogievskiy         }
1039b35ebdf0SVladimir Sementsov-Ogievskiy 
1040b35ebdf0SVladimir Sementsov-Ogievskiy         bdrv_dirty_bitmap_deserialize_part(s->bitmap, buf, first_byte, nr_bytes,
1041b35ebdf0SVladimir Sementsov-Ogievskiy                                            false);
1042b35ebdf0SVladimir Sementsov-Ogievskiy     }
1043b35ebdf0SVladimir Sementsov-Ogievskiy 
1044b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
1045b35ebdf0SVladimir Sementsov-Ogievskiy }
1046b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_load_header(QEMUFile * f,DBMLoadState * s,GHashTable * alias_map)104731e4c354SMax Reitz static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s,
104831e4c354SMax Reitz                                     GHashTable *alias_map)
1049b35ebdf0SVladimir Sementsov-Ogievskiy {
105031e4c354SMax Reitz     GHashTable *bitmap_alias_map = NULL;
1051b35ebdf0SVladimir Sementsov-Ogievskiy     Error *local_err = NULL;
1052b35ebdf0SVladimir Sementsov-Ogievskiy     bool nothing;
1053b35ebdf0SVladimir Sementsov-Ogievskiy     s->flags = qemu_get_bitmap_flags(f);
1054b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_load_header(s->flags);
1055b35ebdf0SVladimir Sementsov-Ogievskiy 
1056b35ebdf0SVladimir Sementsov-Ogievskiy     nothing = s->flags == (s->flags & DIRTY_BITMAP_MIG_FLAG_EOS);
1057b35ebdf0SVladimir Sementsov-Ogievskiy 
1058b35ebdf0SVladimir Sementsov-Ogievskiy     if (s->flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) {
105931e4c354SMax Reitz         if (!qemu_get_counted_string(f, s->node_alias)) {
106031e4c354SMax Reitz             error_report("Unable to read node alias string");
1061b35ebdf0SVladimir Sementsov-Ogievskiy             return -EINVAL;
1062b35ebdf0SVladimir Sementsov-Ogievskiy         }
106331e4c354SMax Reitz 
1064b91f33b8SVladimir Sementsov-Ogievskiy         if (!s->cancelled) {
106531e4c354SMax Reitz             if (alias_map) {
106631e4c354SMax Reitz                 const AliasMapInnerNode *amin;
106731e4c354SMax Reitz 
106831e4c354SMax Reitz                 amin = g_hash_table_lookup(alias_map, s->node_alias);
106931e4c354SMax Reitz                 if (!amin) {
107031e4c354SMax Reitz                     error_setg(&local_err, "Error: Unknown node alias '%s'",
107131e4c354SMax Reitz                                s->node_alias);
107231e4c354SMax Reitz                     s->bs = NULL;
107331e4c354SMax Reitz                 } else {
107431e4c354SMax Reitz                     bitmap_alias_map = amin->subtree;
107531e4c354SMax Reitz                     s->bs = bdrv_lookup_bs(NULL, amin->string, &local_err);
107631e4c354SMax Reitz                 }
107731e4c354SMax Reitz             } else {
107831e4c354SMax Reitz                 s->bs = bdrv_lookup_bs(s->node_alias, s->node_alias,
107931e4c354SMax Reitz                                        &local_err);
108031e4c354SMax Reitz             }
1081b35ebdf0SVladimir Sementsov-Ogievskiy             if (!s->bs) {
1082b35ebdf0SVladimir Sementsov-Ogievskiy                 error_report_err(local_err);
1083b91f33b8SVladimir Sementsov-Ogievskiy                 cancel_incoming_locked(s);
1084b35ebdf0SVladimir Sementsov-Ogievskiy             }
1085b91f33b8SVladimir Sementsov-Ogievskiy         }
108631e4c354SMax Reitz     } else if (s->bs) {
108731e4c354SMax Reitz         if (alias_map) {
108831e4c354SMax Reitz             const AliasMapInnerNode *amin;
108931e4c354SMax Reitz 
109031e4c354SMax Reitz             /* Must be present in the map, or s->bs would not be set */
109131e4c354SMax Reitz             amin = g_hash_table_lookup(alias_map, s->node_alias);
109231e4c354SMax Reitz             assert(amin != NULL);
109331e4c354SMax Reitz 
109431e4c354SMax Reitz             bitmap_alias_map = amin->subtree;
109531e4c354SMax Reitz         }
109631e4c354SMax Reitz     } else if (!nothing && !s->cancelled) {
1097b35ebdf0SVladimir Sementsov-Ogievskiy         error_report("Error: block device name is not set");
1098b91f33b8SVladimir Sementsov-Ogievskiy         cancel_incoming_locked(s);
1099b35ebdf0SVladimir Sementsov-Ogievskiy     }
1100b35ebdf0SVladimir Sementsov-Ogievskiy 
110131e4c354SMax Reitz     assert(nothing || s->cancelled || !!alias_map == !!bitmap_alias_map);
110231e4c354SMax Reitz 
1103b35ebdf0SVladimir Sementsov-Ogievskiy     if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
110431e4c354SMax Reitz         const char *bitmap_name;
110531e4c354SMax Reitz 
110631e4c354SMax Reitz         if (!qemu_get_counted_string(f, s->bitmap_alias)) {
110731e4c354SMax Reitz             error_report("Unable to read bitmap alias string");
1108b35ebdf0SVladimir Sementsov-Ogievskiy             return -EINVAL;
1109b35ebdf0SVladimir Sementsov-Ogievskiy         }
111031e4c354SMax Reitz 
1111a024890aSChen Qun         bitmap_name = s->bitmap_alias;
1112a024890aSChen Qun         if (!s->cancelled && bitmap_alias_map) {
11130d1e450cSPeter Krempa             BitmapMigrationBitmapAlias *bmap_inner;
11140d1e450cSPeter Krempa 
11150d1e450cSPeter Krempa             bmap_inner = g_hash_table_lookup(bitmap_alias_map, s->bitmap_alias);
11160d1e450cSPeter Krempa             if (!bmap_inner) {
111731e4c354SMax Reitz                 error_report("Error: Unknown bitmap alias '%s' on node "
111831e4c354SMax Reitz                              "'%s' (alias '%s')", s->bitmap_alias,
111931e4c354SMax Reitz                              s->bs->node_name, s->node_alias);
112031e4c354SMax Reitz                 cancel_incoming_locked(s);
11210d1e450cSPeter Krempa             } else {
11220d1e450cSPeter Krempa                 bitmap_name = bmap_inner->name;
112331e4c354SMax Reitz             }
11246e9f21a2SPeter Krempa 
11256e9f21a2SPeter Krempa             s->bmap_inner = bmap_inner;
112631e4c354SMax Reitz         }
112731e4c354SMax Reitz 
112831e4c354SMax Reitz         if (!s->cancelled) {
112931e4c354SMax Reitz             g_strlcpy(s->bitmap_name, bitmap_name, sizeof(s->bitmap_name));
1130b35ebdf0SVladimir Sementsov-Ogievskiy             s->bitmap = bdrv_find_dirty_bitmap(s->bs, s->bitmap_name);
1131b35ebdf0SVladimir Sementsov-Ogievskiy 
1132b91f33b8SVladimir Sementsov-Ogievskiy             /*
1133b91f33b8SVladimir Sementsov-Ogievskiy              * bitmap may be NULL here, it wouldn't be an error if it is the
1134b91f33b8SVladimir Sementsov-Ogievskiy              * first occurrence of the bitmap
1135b91f33b8SVladimir Sementsov-Ogievskiy              */
1136b35ebdf0SVladimir Sementsov-Ogievskiy             if (!s->bitmap && !(s->flags & DIRTY_BITMAP_MIG_FLAG_START)) {
1137b35ebdf0SVladimir Sementsov-Ogievskiy                 error_report("Error: unknown dirty bitmap "
1138b35ebdf0SVladimir Sementsov-Ogievskiy                              "'%s' for block device '%s'",
113931e4c354SMax Reitz                              s->bitmap_name, s->bs->node_name);
1140b91f33b8SVladimir Sementsov-Ogievskiy                 cancel_incoming_locked(s);
1141b35ebdf0SVladimir Sementsov-Ogievskiy             }
1142b91f33b8SVladimir Sementsov-Ogievskiy         }
1143b91f33b8SVladimir Sementsov-Ogievskiy     } else if (!s->bitmap && !nothing && !s->cancelled) {
1144b35ebdf0SVladimir Sementsov-Ogievskiy         error_report("Error: block device name is not set");
1145b91f33b8SVladimir Sementsov-Ogievskiy         cancel_incoming_locked(s);
1146b35ebdf0SVladimir Sementsov-Ogievskiy     }
1147b35ebdf0SVladimir Sementsov-Ogievskiy 
1148b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
1149b35ebdf0SVladimir Sementsov-Ogievskiy }
1150b35ebdf0SVladimir Sementsov-Ogievskiy 
1151b91f33b8SVladimir Sementsov-Ogievskiy /*
1152b91f33b8SVladimir Sementsov-Ogievskiy  * dirty_bitmap_load
1153b91f33b8SVladimir Sementsov-Ogievskiy  *
1154b91f33b8SVladimir Sementsov-Ogievskiy  * Load sequence of dirty bitmap chunks. Return error only on fatal io stream
1155b91f33b8SVladimir Sementsov-Ogievskiy  * violations. On other errors just cancel bitmaps incoming migration and return
1156b91f33b8SVladimir Sementsov-Ogievskiy  * 0.
1157b91f33b8SVladimir Sementsov-Ogievskiy  *
1158b91f33b8SVladimir Sementsov-Ogievskiy  * Note, than when incoming bitmap migration is canceled, we still must read all
1159b91f33b8SVladimir Sementsov-Ogievskiy  * our chunks (and just ignore them), to not affect other migration objects.
1160b91f33b8SVladimir Sementsov-Ogievskiy  */
dirty_bitmap_load(QEMUFile * f,void * opaque,int version_id)1161b35ebdf0SVladimir Sementsov-Ogievskiy static int dirty_bitmap_load(QEMUFile *f, void *opaque, int version_id)
1162b35ebdf0SVladimir Sementsov-Ogievskiy {
116331e4c354SMax Reitz     GHashTable *alias_map = NULL;
11643b52726eSVladimir Sementsov-Ogievskiy     DBMLoadState *s = &((DBMState *)opaque)->load;
1165b35ebdf0SVladimir Sementsov-Ogievskiy     int ret = 0;
1166b35ebdf0SVladimir Sementsov-Ogievskiy 
1167b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_load_enter();
1168b35ebdf0SVladimir Sementsov-Ogievskiy 
1169b35ebdf0SVladimir Sementsov-Ogievskiy     if (version_id != 1) {
1170b91f33b8SVladimir Sementsov-Ogievskiy         QEMU_LOCK_GUARD(&s->lock);
1171b91f33b8SVladimir Sementsov-Ogievskiy         cancel_incoming_locked(s);
1172b35ebdf0SVladimir Sementsov-Ogievskiy         return -EINVAL;
1173b35ebdf0SVladimir Sementsov-Ogievskiy     }
1174b35ebdf0SVladimir Sementsov-Ogievskiy 
11753cba22c9SJuan Quintela     if (migrate_has_block_bitmap_mapping()) {
11763cba22c9SJuan Quintela         alias_map = construct_alias_map(migrate_block_bitmap_mapping(), false,
11773cba22c9SJuan Quintela                                         &error_abort);
117831e4c354SMax Reitz     }
117931e4c354SMax Reitz 
1180b35ebdf0SVladimir Sementsov-Ogievskiy     do {
1181b91f33b8SVladimir Sementsov-Ogievskiy         QEMU_LOCK_GUARD(&s->lock);
1182b91f33b8SVladimir Sementsov-Ogievskiy 
118331e4c354SMax Reitz         ret = dirty_bitmap_load_header(f, s, alias_map);
1184a36f6ff4SVladimir Sementsov-Ogievskiy         if (ret < 0) {
1185b91f33b8SVladimir Sementsov-Ogievskiy             cancel_incoming_locked(s);
118631e4c354SMax Reitz             goto fail;
1187a36f6ff4SVladimir Sementsov-Ogievskiy         }
1188b35ebdf0SVladimir Sementsov-Ogievskiy 
11893b52726eSVladimir Sementsov-Ogievskiy         if (s->flags & DIRTY_BITMAP_MIG_FLAG_START) {
11903b52726eSVladimir Sementsov-Ogievskiy             ret = dirty_bitmap_load_start(f, s);
11913b52726eSVladimir Sementsov-Ogievskiy         } else if (s->flags & DIRTY_BITMAP_MIG_FLAG_COMPLETE) {
11923b52726eSVladimir Sementsov-Ogievskiy             dirty_bitmap_load_complete(f, s);
11933b52726eSVladimir Sementsov-Ogievskiy         } else if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITS) {
11943b52726eSVladimir Sementsov-Ogievskiy             ret = dirty_bitmap_load_bits(f, s);
1195b35ebdf0SVladimir Sementsov-Ogievskiy         }
1196b35ebdf0SVladimir Sementsov-Ogievskiy 
1197b35ebdf0SVladimir Sementsov-Ogievskiy         if (!ret) {
1198b35ebdf0SVladimir Sementsov-Ogievskiy             ret = qemu_file_get_error(f);
1199b35ebdf0SVladimir Sementsov-Ogievskiy         }
1200b35ebdf0SVladimir Sementsov-Ogievskiy 
1201b35ebdf0SVladimir Sementsov-Ogievskiy         if (ret) {
1202b91f33b8SVladimir Sementsov-Ogievskiy             cancel_incoming_locked(s);
120331e4c354SMax Reitz             goto fail;
1204b35ebdf0SVladimir Sementsov-Ogievskiy         }
12053b52726eSVladimir Sementsov-Ogievskiy     } while (!(s->flags & DIRTY_BITMAP_MIG_FLAG_EOS));
1206b35ebdf0SVladimir Sementsov-Ogievskiy 
1207b35ebdf0SVladimir Sementsov-Ogievskiy     trace_dirty_bitmap_load_success();
120831e4c354SMax Reitz     ret = 0;
120931e4c354SMax Reitz fail:
121031e4c354SMax Reitz     if (alias_map) {
121131e4c354SMax Reitz         g_hash_table_destroy(alias_map);
121231e4c354SMax Reitz     }
121331e4c354SMax Reitz     return ret;
1214b35ebdf0SVladimir Sementsov-Ogievskiy }
1215b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_save_setup(QEMUFile * f,void * opaque,Error ** errp)121601c3ac68SCédric Le Goater static int dirty_bitmap_save_setup(QEMUFile *f, void *opaque, Error **errp)
1217b35ebdf0SVladimir Sementsov-Ogievskiy {
12183b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
1219fbbc6b14SVladimir Sementsov-Ogievskiy     SaveBitmapState *dbms = NULL;
12203c158ebaSEmanuele Giuseppe Esposito 
1221dd031677SCédric Le Goater     if (init_dirty_bitmap_migration(s, errp) < 0) {
1222b35ebdf0SVladimir Sementsov-Ogievskiy         return -1;
1223b35ebdf0SVladimir Sementsov-Ogievskiy     }
1224b35ebdf0SVladimir Sementsov-Ogievskiy 
12253b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_FOREACH(dbms, &s->dbms_list, entry) {
12263b52726eSVladimir Sementsov-Ogievskiy         send_bitmap_start(f, s, dbms);
1227b35ebdf0SVladimir Sementsov-Ogievskiy     }
1228b35ebdf0SVladimir Sementsov-Ogievskiy     qemu_put_bitmap_flags(f, DIRTY_BITMAP_MIG_FLAG_EOS);
1229b35ebdf0SVladimir Sementsov-Ogievskiy     return 0;
1230b35ebdf0SVladimir Sementsov-Ogievskiy }
1231b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_is_active(void * opaque)1232b35ebdf0SVladimir Sementsov-Ogievskiy static bool dirty_bitmap_is_active(void *opaque)
1233b35ebdf0SVladimir Sementsov-Ogievskiy {
12343b52726eSVladimir Sementsov-Ogievskiy     DBMSaveState *s = &((DBMState *)opaque)->save;
12353b52726eSVladimir Sementsov-Ogievskiy 
12363b52726eSVladimir Sementsov-Ogievskiy     return migrate_dirty_bitmaps() && !s->no_bitmaps;
1237b35ebdf0SVladimir Sementsov-Ogievskiy }
1238b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_is_active_iterate(void * opaque)1239b35ebdf0SVladimir Sementsov-Ogievskiy static bool dirty_bitmap_is_active_iterate(void *opaque)
1240b35ebdf0SVladimir Sementsov-Ogievskiy {
1241b35ebdf0SVladimir Sementsov-Ogievskiy     return dirty_bitmap_is_active(opaque) && !runstate_is_running();
1242b35ebdf0SVladimir Sementsov-Ogievskiy }
1243b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_has_postcopy(void * opaque)1244b35ebdf0SVladimir Sementsov-Ogievskiy static bool dirty_bitmap_has_postcopy(void *opaque)
1245b35ebdf0SVladimir Sementsov-Ogievskiy {
1246b35ebdf0SVladimir Sementsov-Ogievskiy     return true;
1247b35ebdf0SVladimir Sementsov-Ogievskiy }
1248b35ebdf0SVladimir Sementsov-Ogievskiy 
1249b35ebdf0SVladimir Sementsov-Ogievskiy static SaveVMHandlers savevm_dirty_bitmap_handlers = {
1250b35ebdf0SVladimir Sementsov-Ogievskiy     .save_setup = dirty_bitmap_save_setup,
1251b35ebdf0SVladimir Sementsov-Ogievskiy     .save_live_complete_postcopy = dirty_bitmap_save_complete,
1252b35ebdf0SVladimir Sementsov-Ogievskiy     .save_live_complete_precopy = dirty_bitmap_save_complete,
1253b35ebdf0SVladimir Sementsov-Ogievskiy     .has_postcopy = dirty_bitmap_has_postcopy,
1254c8df4a7aSJuan Quintela     .state_pending_exact = dirty_bitmap_state_pending,
1255c8df4a7aSJuan Quintela     .state_pending_estimate = dirty_bitmap_state_pending,
1256b35ebdf0SVladimir Sementsov-Ogievskiy     .save_live_iterate = dirty_bitmap_save_iterate,
1257b35ebdf0SVladimir Sementsov-Ogievskiy     .is_active_iterate = dirty_bitmap_is_active_iterate,
1258b35ebdf0SVladimir Sementsov-Ogievskiy     .load_state = dirty_bitmap_load,
1259b35ebdf0SVladimir Sementsov-Ogievskiy     .save_cleanup = dirty_bitmap_save_cleanup,
1260b35ebdf0SVladimir Sementsov-Ogievskiy     .is_active = dirty_bitmap_is_active,
1261b35ebdf0SVladimir Sementsov-Ogievskiy };
1262b35ebdf0SVladimir Sementsov-Ogievskiy 
dirty_bitmap_mig_init(void)1263b35ebdf0SVladimir Sementsov-Ogievskiy void dirty_bitmap_mig_init(void)
1264b35ebdf0SVladimir Sementsov-Ogievskiy {
12653b52726eSVladimir Sementsov-Ogievskiy     QSIMPLEQ_INIT(&dbm_state.save.dbms_list);
126689491216SVladimir Sementsov-Ogievskiy     qemu_mutex_init(&dbm_state.load.lock);
1267b35ebdf0SVladimir Sementsov-Ogievskiy 
1268ce62df53SDr. David Alan Gilbert     register_savevm_live("dirty-bitmap", 0, 1,
1269b35ebdf0SVladimir Sementsov-Ogievskiy                          &savevm_dirty_bitmap_handlers,
12703b52726eSVladimir Sementsov-Ogievskiy                          &dbm_state);
1271b35ebdf0SVladimir Sementsov-Ogievskiy }
1272