diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 975093610a..35f5ef688d 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -839,6 +839,8 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s) error_report_err(local_err); return -EINVAL; } + } else { + bdrv_dirty_bitmap_set_busy(s->bitmap, true); } b = g_new(LoadBitmapState, 1); @@ -914,6 +916,8 @@ static void cancel_incoming_locked(DBMLoadState *s) assert(!s->before_vm_start_handled || !b->migrated); if (bdrv_dirty_bitmap_has_successor(b->bitmap)) { bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort); + } else { + bdrv_dirty_bitmap_set_busy(b->bitmap, false); } bdrv_release_dirty_bitmap(b->bitmap); } @@ -951,6 +955,8 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s) if (bdrv_dirty_bitmap_has_successor(s->bitmap)) { bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort); + } else { + bdrv_dirty_bitmap_set_busy(s->bitmap, false); } for (item = s->bitmaps; item; item = g_slist_next(item)) { diff --git a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test index d046ebeb94..584062b412 100755 --- a/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test +++ b/tests/qemu-iotests/tests/migrate-bitmaps-postcopy-test @@ -224,6 +224,16 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase): self.start_postcopy() self.vm_b_events += self.vm_b.get_qmp_events() + + # While being here, let's check that we can't remove in-flight bitmaps. + for vm in (self.vm_a, self.vm_b): + for i in range(0, nb_bitmaps): + result = vm.qmp('block-dirty-bitmap-remove', node='drive0', + name=f'bitmap{i}') + self.assert_qmp(result, 'error/desc', + f"Bitmap 'bitmap{i}' is currently in use by " + "another operation and cannot be used") + self.vm_b.shutdown() # recreate vm_b, so there is no incoming option, which prevents # loading bitmaps from disk