Both commands will be reimplemented in a follow-up to this patch so this does not need to be nice, it just has to work.
Signed-off-by: Max Reitz <mre...@redhat.com> --- blockdev.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/blockdev.c b/blockdev.c index 7f4470f..f3091df 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1756,10 +1756,10 @@ static void eject_device(BlockBackend *blk, int force, Error **errp) BlockDriverState *bs = blk_bs(blk); AioContext *aio_context; - aio_context = bdrv_get_aio_context(bs); + aio_context = blk_get_aio_context(blk); aio_context_acquire(aio_context); - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) { + if (bs && bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) { goto out; } if (!blk_dev_has_removable_media(blk)) { @@ -1777,7 +1777,9 @@ static void eject_device(BlockBackend *blk, int force, Error **errp) } } - bdrv_close(bs); + if (bs) { + bdrv_close(bs); + } out: aio_context_release(aio_context); @@ -1830,18 +1832,21 @@ out: } /* Assumes AioContext is held */ -static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, +static void qmp_bdrv_open_encrypted(BlockDriverState **pbs, + const char *filename, int bdrv_flags, BlockDriver *drv, const char *password, Error **errp) { + BlockDriverState *bs; Error *local_err = NULL; int ret; - ret = bdrv_open(&bs, filename, NULL, NULL, bdrv_flags, drv, &local_err); + ret = bdrv_open(pbs, filename, NULL, NULL, bdrv_flags, drv, &local_err); if (ret < 0) { error_propagate(errp, local_err); return; } + bs = *pbs; if (bdrv_key_required(bs)) { if (password) { @@ -1865,6 +1870,7 @@ void qmp_change_blockdev(const char *device, const char *filename, AioContext *aio_context; BlockDriver *drv = NULL; int bdrv_flags; + bool new_bs; Error *err = NULL; blk = blk_by_name(device); @@ -1873,12 +1879,13 @@ void qmp_change_blockdev(const char *device, const char *filename, return; } bs = blk_bs(blk); + new_bs = !bs; - aio_context = bdrv_get_aio_context(bs); + aio_context = blk_get_aio_context(blk); aio_context_acquire(aio_context); if (format) { - drv = bdrv_find_whitelisted_format(format, bs->read_only); + drv = bdrv_find_whitelisted_format(format, blk_is_read_only(blk)); if (!drv) { error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); goto out; @@ -1891,10 +1898,18 @@ void qmp_change_blockdev(const char *device, const char *filename, goto out; } - bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR; - bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0; + bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR; + bdrv_flags |= blk_get_root_state(blk)->open_flags & ~BDRV_O_RDWR; - qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp); + qmp_bdrv_open_encrypted(&bs, filename, bdrv_flags, drv, NULL, &err); + if (err) { + error_propagate(errp, err); + } else if (new_bs) { + blk_insert_bs(blk, bs); + /* Has been sent automatically by bdrv_open() if blk_bs(blk) was not + * NULL */ + blk_dev_change_media_cb(blk, true); + } out: aio_context_release(aio_context); -- 2.1.0