diff options
-rw-r--r-- | migration/block-dirty-bitmap.c | 29 | ||||
-rw-r--r-- | qapi/migration.json | 19 |
2 files changed, 44 insertions, 4 deletions
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index b39c13ce4e..975093610a 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -150,6 +150,7 @@ typedef struct DBMLoadState { BdrvDirtyBitmap *bitmap; bool before_vm_start_handled; /* set in dirty_bitmap_mig_before_vm_start */ + BitmapMigrationBitmapAlias *bmap_inner; /* * cancelled @@ -529,6 +530,7 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, } FOR_EACH_DIRTY_BITMAP(bs, bitmap) { + BitmapMigrationBitmapAliasTransform *bitmap_transform = NULL; bitmap_name = bdrv_dirty_bitmap_name(bitmap); if (!bitmap_name) { continue; @@ -549,6 +551,9 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, } bitmap_alias = bmap_inner->alias; + if (bmap_inner->has_transform) { + bitmap_transform = bmap_inner->transform; + } } else { if (strlen(bitmap_name) > UINT8_MAX) { error_report("Cannot migrate bitmap '%s' on node '%s': " @@ -574,8 +579,15 @@ static int add_bitmaps_to_list(DBMSaveState *s, BlockDriverState *bs, if (bdrv_dirty_bitmap_enabled(bitmap)) { dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_ENABLED; } - if (bdrv_dirty_bitmap_get_persistence(bitmap)) { - dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + if (bitmap_transform && + bitmap_transform->has_persistent) { + if (bitmap_transform->persistent) { + dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } + } else { + if (bdrv_dirty_bitmap_get_persistence(bitmap)) { + dbms->flags |= DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } } QSIMPLEQ_INSERT_TAIL(&s->dbms_list, dbms, entry); @@ -783,6 +795,7 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) uint32_t granularity = qemu_get_be32(f); uint8_t flags = qemu_get_byte(f); LoadBitmapState *b; + bool persistent; if (s->cancelled) { return 0; @@ -807,7 +820,15 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) return -EINVAL; } - if (flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT) { + if (s->bmap_inner && + s->bmap_inner->has_transform && + s->bmap_inner->transform->has_persistent) { + persistent = s->bmap_inner->transform->persistent; + } else { + persistent = flags & DIRTY_BITMAP_MIG_START_FLAG_PERSISTENT; + } + + if (persistent) { bdrv_dirty_bitmap_set_persistence(s->bitmap, true); } @@ -1091,6 +1112,8 @@ static int dirty_bitmap_load_header(QEMUFile *f, DBMLoadState *s, } else { bitmap_name = bmap_inner->name; } + + s->bmap_inner = bmap_inner; } if (!s->cancelled) { diff --git a/qapi/migration.json b/qapi/migration.json index ce14d78071..6e5943fbb4 100644 --- a/qapi/migration.json +++ b/qapi/migration.json @@ -537,6 +537,19 @@ { 'name': 'zstd', 'if': 'defined(CONFIG_ZSTD)' } ] } ## +# @BitmapMigrationBitmapAliasTransform: +# +# @persistent: If present, the bitmap will be made persistent +# or transient depending on this parameter. +# +# Since: 6.0 +## +{ 'struct': 'BitmapMigrationBitmapAliasTransform', + 'data': { + '*persistent': 'bool' + } } + +## # @BitmapMigrationBitmapAlias: # # @name: The name of the bitmap. @@ -544,12 +557,16 @@ # @alias: An alias name for migration (for example the bitmap name on # the opposite site). # +# @transform: Allows the modification of the migrated bitmap. +# (since 6.0) +# # Since: 5.2 ## { 'struct': 'BitmapMigrationBitmapAlias', 'data': { 'name': 'str', - 'alias': 'str' + 'alias': 'str', + '*transform': 'BitmapMigrationBitmapAliasTransform' } } ## |