mirror of https://github.com/xemu-project/xemu.git
block: Take main AioContext lock when calling bdrv_open()
The function documentation already says that all callers must hold the main AioContext lock, but not all of them do. This can cause assertion failures when functions called by bdrv_open() try to drop the lock. Fix a few more callers to take the lock before calling bdrv_open(). Signed-off-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20230525124713.401149-4-kwolf@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
ae400dbb8f
commit
c6e0a6de62
3
block.c
3
block.c
|
@ -7037,6 +7037,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
|
|
||||||
/* Create parameter list */
|
/* Create parameter list */
|
||||||
create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
create_opts = qemu_opts_append(create_opts, drv->create_opts);
|
||||||
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
|
||||||
|
@ -7186,6 +7188,7 @@ out:
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
qemu_opts_free(create_opts);
|
qemu_opts_free(create_opts);
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
}
|
}
|
||||||
|
|
||||||
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
|
||||||
|
|
|
@ -452,7 +452,9 @@ BlockBackend *blk_new_open(const char *filename, const char *reference,
|
||||||
}
|
}
|
||||||
|
|
||||||
blk = blk_new(qemu_get_aio_context(), perm, shared);
|
blk = blk_new(qemu_get_aio_context(), perm, shared);
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
bs = bdrv_open(filename, reference, options, flags, errp);
|
bs = bdrv_open(filename, reference, options, flags, errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
blk_unref(blk);
|
blk_unref(blk);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -362,7 +362,10 @@ void qmp_blockdev_change_medium(const char *device,
|
||||||
qdict_put_str(options, "driver", format);
|
qdict_put_str(options, "driver", format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
|
medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
if (!medium_bs) {
|
if (!medium_bs) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
29
blockdev.c
29
blockdev.c
|
@ -662,6 +662,7 @@ err_no_opts:
|
||||||
/* Takes the ownership of bs_opts */
|
/* Takes the ownership of bs_opts */
|
||||||
BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
||||||
{
|
{
|
||||||
|
BlockDriverState *bs;
|
||||||
int bdrv_flags = 0;
|
int bdrv_flags = 0;
|
||||||
|
|
||||||
GLOBAL_STATE_CODE();
|
GLOBAL_STATE_CODE();
|
||||||
|
@ -676,7 +677,11 @@ BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
||||||
bdrv_flags |= BDRV_O_INACTIVE;
|
bdrv_flags |= BDRV_O_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp);
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
|
bs = bdrv_open(NULL, NULL, bs_opts, bdrv_flags, errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
|
return bs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blockdev_close_all_bdrv_states(void)
|
void blockdev_close_all_bdrv_states(void)
|
||||||
|
@ -1480,14 +1485,20 @@ static void external_snapshot_action(TransactionAction *action,
|
||||||
}
|
}
|
||||||
qdict_put_str(options, "driver", format);
|
qdict_put_str(options, "driver", format);
|
||||||
}
|
}
|
||||||
|
aio_context_release(aio_context);
|
||||||
|
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags,
|
state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags,
|
||||||
errp);
|
errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
/* We will manually add the backing_hd field to the bs later */
|
/* We will manually add the backing_hd field to the bs later */
|
||||||
if (!state->new_bs) {
|
if (!state->new_bs) {
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aio_context_acquire(aio_context);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow attaching a backing file to an overlay that's already in use only
|
* Allow attaching a backing file to an overlay that's already in use only
|
||||||
* if the parents don't assume that they are already seeing a valid image.
|
* if the parents don't assume that they are already seeing a valid image.
|
||||||
|
@ -1732,15 +1743,18 @@ static void drive_backup_action(DriveBackup *backup,
|
||||||
if (format) {
|
if (format) {
|
||||||
qdict_put_str(options, "driver", format);
|
qdict_put_str(options, "driver", format);
|
||||||
}
|
}
|
||||||
|
aio_context_release(aio_context);
|
||||||
|
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
|
target_bs = bdrv_open(backup->target, NULL, options, flags, errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
if (!target_bs) {
|
if (!target_bs) {
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Honor bdrv_try_change_aio_context() context acquisition requirements. */
|
/* Honor bdrv_try_change_aio_context() context acquisition requirements. */
|
||||||
old_context = bdrv_get_aio_context(target_bs);
|
old_context = bdrv_get_aio_context(target_bs);
|
||||||
aio_context_release(aio_context);
|
|
||||||
aio_context_acquire(old_context);
|
aio_context_acquire(old_context);
|
||||||
|
|
||||||
ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
|
ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
|
||||||
|
@ -3066,13 +3080,17 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||||
if (format) {
|
if (format) {
|
||||||
qdict_put_str(options, "driver", format);
|
qdict_put_str(options, "driver", format);
|
||||||
}
|
}
|
||||||
|
aio_context_release(aio_context);
|
||||||
|
|
||||||
/* Mirroring takes care of copy-on-write using the source's backing
|
/* Mirroring takes care of copy-on-write using the source's backing
|
||||||
* file.
|
* file.
|
||||||
*/
|
*/
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
target_bs = bdrv_open(arg->target, NULL, options, flags, errp);
|
target_bs = bdrv_open(arg->target, NULL, options, flags, errp);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
if (!target_bs) {
|
if (!target_bs) {
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL &&
|
zero_target = (arg->sync == MIRROR_SYNC_MODE_FULL &&
|
||||||
|
@ -3082,7 +3100,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||||
|
|
||||||
/* Honor bdrv_try_change_aio_context() context acquisition requirements. */
|
/* Honor bdrv_try_change_aio_context() context acquisition requirements. */
|
||||||
old_context = bdrv_get_aio_context(target_bs);
|
old_context = bdrv_get_aio_context(target_bs);
|
||||||
aio_context_release(aio_context);
|
|
||||||
aio_context_acquire(old_context);
|
aio_context_acquire(old_context);
|
||||||
|
|
||||||
ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
|
ret = bdrv_try_change_aio_context(target_bs, aio_context, NULL, errp);
|
||||||
|
|
|
@ -1071,7 +1071,11 @@ int main(int argc, char **argv)
|
||||||
qdict_put_str(raw_opts, "driver", "raw");
|
qdict_put_str(raw_opts, "driver", "raw");
|
||||||
qdict_put_str(raw_opts, "file", bs->node_name);
|
qdict_put_str(raw_opts, "file", bs->node_name);
|
||||||
qdict_put_int(raw_opts, "offset", dev_offset);
|
qdict_put_int(raw_opts, "offset", dev_offset);
|
||||||
|
|
||||||
|
aio_context_acquire(qemu_get_aio_context());
|
||||||
bs = bdrv_open(NULL, NULL, raw_opts, flags, &error_fatal);
|
bs = bdrv_open(NULL, NULL, raw_opts, flags, &error_fatal);
|
||||||
|
aio_context_release(qemu_get_aio_context());
|
||||||
|
|
||||||
blk_remove_bs(blk);
|
blk_remove_bs(blk);
|
||||||
blk_insert_bs(blk, bs, &error_fatal);
|
blk_insert_bs(blk, bs, &error_fatal);
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
|
|
|
@ -833,8 +833,11 @@ static void test_attach_second_node(void)
|
||||||
qdict_put_str(options, "driver", "raw");
|
qdict_put_str(options, "driver", "raw");
|
||||||
qdict_put_str(options, "file", "base");
|
qdict_put_str(options, "file", "base");
|
||||||
|
|
||||||
|
/* FIXME raw_open() should take ctx's lock internally */
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
|
aio_context_acquire(main_ctx);
|
||||||
filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
|
filter = bdrv_open(NULL, NULL, options, BDRV_O_RDWR, &error_abort);
|
||||||
|
aio_context_release(main_ctx);
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
|
|
||||||
g_assert(blk_get_aio_context(blk) == ctx);
|
g_assert(blk_get_aio_context(blk) == ctx);
|
||||||
|
|
Loading…
Reference in New Issue