From 98d4a8d9d5823d7d43ea816208a35372124a749f Mon Sep 17 00:00:00 2001 From: zhujun2 Date: Sun, 10 Mar 2024 22:52:08 -0700 Subject: [PATCH] block-migration: Ensure we don't crash during migration cleanup We can fail the blk_insert_bs() at init_blk_migration(), leaving the BlkMigDevState without a dirty_bitmap and BlockDriverState. Account for the possibly missing elements when doing cleanup. Fix the following crashes: Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x0000555555ec83ef in bdrv_release_dirty_bitmap (bitmap=0x0) at ../block/dirty-bitmap.c:359 359 BlockDriverState *bs = bitmap->bs; Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. 0x0000555555e971ff in bdrv_op_unblock (bs=0x0, op=BLOCK_OP_TYPE_BACKUP_SOURCE, reason=0x0) at ../block.c:7073 7073 QLIST_FOREACH_SAFE(blocker, &bs->op_blockers[op], list, next) { Signed-off-by: Fabiano Rosas Message-id: 20230731203338.27581-1-farosas@suse.de> Signed-off-by: Stefan Hajnoczi (cherry picked from commit f187609f27b261702a17f79d20bf252ee0d4f9cd) Signed-off-by: zhujun2 --- migration/block.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/migration/block.c b/migration/block.c index a950977855..391f8169fd 100644 --- a/migration/block.c +++ b/migration/block.c @@ -376,7 +376,9 @@ static void unset_dirty_tracking(void) BlkMigDevState *bmds; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - bdrv_release_dirty_bitmap(bmds->dirty_bitmap); + if (bmds->dirty_bitmap) { + bdrv_release_dirty_bitmap(bmds->dirty_bitmap); + } } } @@ -684,13 +686,18 @@ static int64_t get_remaining_dirty(void) static void block_migration_cleanup_bmds(void) { BlkMigDevState *bmds; + BlockDriverState *bs; AioContext *ctx; unset_dirty_tracking(); while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry); - bdrv_op_unblock_all(blk_bs(bmds->blk), bmds->blocker); + + bs = blk_bs(bmds->blk); + if (bs) { + bdrv_op_unblock_all(bs,bmds->blocker); + } error_free(bmds->blocker); /* Save ctx, because bmds->blk can disappear during blk_unref. */ -- 2.27.0