@@ -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);
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 <mreitz@redhat.com> --- blockdev.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)