@@ -4497,10 +4497,6 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,
}
}
- /* At this point persistent bitmaps should be already stored by the format
- * driver */
- bdrv_release_persistent_dirty_bitmaps(bs);
-
return 0;
}
@@ -383,26 +383,6 @@ void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs)
bdrv_dirty_bitmaps_unlock(bs);
}
-/**
- * Release all persistent dirty bitmaps attached to a BDS (for use in
- * bdrv_inactivate_recurse()).
- * There must not be any frozen bitmaps attached.
- * This function does not remove persistent bitmaps from the storage.
- * Called with BQL taken.
- */
-void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs)
-{
- BdrvDirtyBitmap *bm, *next;
-
- bdrv_dirty_bitmaps_lock(bs);
- QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) {
- if (bdrv_dirty_bitmap_get_persistance(bm)) {
- bdrv_release_dirty_bitmap_locked(bm);
- }
- }
- bdrv_dirty_bitmaps_unlock(bs);
-}
-
/**
* Remove persistent dirty bitmap from the storage if it exists.
* Absence of bitmap is not an error, because we have the following scenario:
@@ -1418,6 +1418,22 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp)
g_free(tb);
}
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
+ /* For safety, we remove bitmap after storing.
+ * We may be here in two cases:
+ * 1. bdrv_close. It's ok to drop bitmap.
+ * 2. inactivation. It means migration without 'dirty-bitmaps'
+ * capability, so bitmaps are not marked with
+ * BdrvDirtyBitmap.migration flags. It's not bad to drop them too,
+ * and reload on invalidation.
+ */
+ if (bm->dirty_bitmap == NULL) {
+ continue;
+ }
+
+ bdrv_release_dirty_bitmap(bs, bm->dirty_bitmap);
+ }
+
bitmap_list_free(bm_list);
return;
@@ -1495,8 +1495,9 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
}
- if (qcow2_load_dirty_bitmaps(bs, &local_err)) {
- update_header = false;
+ if (!(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) {
+ bool header_updated = qcow2_load_dirty_bitmaps(bs, &local_err);
+ update_header = update_header && !header_updated;
}
if (local_err != NULL) {
error_propagate(errp, local_err);
@@ -26,7 +26,6 @@ BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs,
const char *name);
void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap);
void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs);
-void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs);
void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs,
const char *name,
Error **errp);
@@ -72,6 +71,7 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap,
void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked);
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
Error **errp);
+void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration);
/* Functions that require manual locking. */
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
@@ -295,6 +295,12 @@ static int init_dirty_bitmap_migration(void)
continue;
}
+ /* Skip persistant bitmaps, unless it's a block migration: */
+ if (bdrv_dirty_bitmap_get_persistance(bitmap) &&
+ !migrate_use_block()) {
+ continue;
+ }
+
if (drive_name == NULL) {
error_report("Found bitmap '%s' in unnamed node %p. It can't "
"be migrated", bdrv_dirty_bitmap_name(bitmap), bs);
@@ -335,11 +341,6 @@ static int init_dirty_bitmap_migration(void)
}
}
- /* unset persistance here, to not roll back it */
- QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
- bdrv_dirty_bitmap_set_persistance(dbms->bitmap, false);
- }
-
if (QSIMPLEQ_EMPTY(&dirty_bitmap_mig_state.dbms_list)) {
dirty_bitmap_mig_state.no_bitmaps = true;
}