Skip to content

Commit 4290b48

Browse files
Vladimir Sementsov-OgievskiystefanhaRH
authored andcommitted
migration/block-dirty-bitmap: make incoming disabled bitmaps busy
Incoming enabled bitmaps are busy, because we do bdrv_dirty_bitmap_create_successor() for them. But disabled bitmaps being migrated are not marked busy, and user can remove them during the incoming migration. Then we may crash in cancel_incoming_locked() when try to remove the bitmap that was already removed by user, like this: #0 qemu_mutex_lock_impl (mutex=0x5593d88c50d1, file=0x559680554b20 "../block/dirty-bitmap.c", line=64) at ../util/qemu-thread-posix.c:77 #1 bdrv_dirty_bitmaps_lock (bs=0x5593d88c0ee9) at ../block/dirty-bitmap.c:64 qemu#2 bdrv_release_dirty_bitmap (bitmap=0x5596810e9570) at ../block/dirty-bitmap.c:362 qemu#3 cancel_incoming_locked (s=0x559680be8208 <dbm_state+40>) at ../migration/block-dirty-bitmap.c:918 qemu#4 dirty_bitmap_load (f=0x559681d02b10, opaque=0x559680be81e0 <dbm_state>, version_id=1) at ../migration/block-dirty-bitmap.c:1194 qemu#5 vmstate_load (f=0x559681d02b10, se=0x559680fb5810) at ../migration/savevm.c:908 qemu#6 qemu_loadvm_section_part_end (f=0x559681d02b10, mis=0x559680fb4a30) at ../migration/savevm.c:2473 qemu#7 qemu_loadvm_state_main (f=0x559681d02b10, mis=0x559680fb4a30) at ../migration/savevm.c:2626 qemu#8 postcopy_ram_listen_thread (opaque=0x0) at ../migration/savevm.c:1871 qemu#9 qemu_thread_start (args=0x5596817ccd10) at ../util/qemu-thread-posix.c:521 qemu#10 start_thread () at /lib64/libpthread.so.0 qemu#11 clone () at /lib64/libc.so.6 Note bs pointer taken from bitmap: it's definitely bad aligned. That's because we are in use after free, bitmap is already freed. So, let's make disabled bitmaps (being migrated) busy during incoming migration. Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]> Signed-off-by: Stefan Hajnoczi <[email protected]> Message-Id: <[email protected]>
1 parent 67c1115 commit 4290b48

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

migration/block-dirty-bitmap.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,8 @@ static int dirty_bitmap_load_start(QEMUFile *f, DBMLoadState *s)
839839
error_report_err(local_err);
840840
return -EINVAL;
841841
}
842+
} else {
843+
bdrv_dirty_bitmap_set_busy(s->bitmap, true);
842844
}
843845

844846
b = g_new(LoadBitmapState, 1);
@@ -914,6 +916,8 @@ static void cancel_incoming_locked(DBMLoadState *s)
914916
assert(!s->before_vm_start_handled || !b->migrated);
915917
if (bdrv_dirty_bitmap_has_successor(b->bitmap)) {
916918
bdrv_reclaim_dirty_bitmap(b->bitmap, &error_abort);
919+
} else {
920+
bdrv_dirty_bitmap_set_busy(b->bitmap, false);
917921
}
918922
bdrv_release_dirty_bitmap(b->bitmap);
919923
}
@@ -951,6 +955,8 @@ static void dirty_bitmap_load_complete(QEMUFile *f, DBMLoadState *s)
951955

952956
if (bdrv_dirty_bitmap_has_successor(s->bitmap)) {
953957
bdrv_reclaim_dirty_bitmap(s->bitmap, &error_abort);
958+
} else {
959+
bdrv_dirty_bitmap_set_busy(s->bitmap, false);
954960
}
955961

956962
for (item = s->bitmaps; item; item = g_slist_next(item)) {

0 commit comments

Comments
 (0)