diff --git a/blockdev.c b/blockdev.c index a42c8028ac3f824bb238d9fc36dc1e886ac6f28b..773336c1c300b817101b8c04995701cd8c340ae5 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1856,30 +1856,23 @@ static void do_drive_backup(const char *job_id, const char *device, static void drive_backup_prepare(BlkActionState *common, Error **errp) { DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common); - BlockBackend *blk; + BlockDriverState *bs; DriveBackup *backup; Error *local_err = NULL; assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); backup = common->action->u.drive_backup.data; - blk = blk_by_name(backup->device); - if (!blk) { - error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, - "Device '%s' not found", backup->device); - return; - } - - if (!blk_is_available(blk)) { - error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, backup->device); + bs = qmp_get_root_bs(backup->device, errp); + if (!bs) { return; } /* AioContext is released in .clean() */ - state->aio_context = blk_get_aio_context(blk); + state->aio_context = bdrv_get_aio_context(bs); aio_context_acquire(state->aio_context); - bdrv_drained_begin(blk_bs(blk)); - state->bs = blk_bs(blk); + bdrv_drained_begin(bs); + state->bs = bs; do_drive_backup(backup->has_job_id ? backup->job_id : NULL, backup->device, backup->target, @@ -3153,7 +3146,6 @@ static void do_drive_backup(const char *job_id, const char *device, BlockdevOnError on_target_error, BlockJobTxn *txn, Error **errp) { - BlockBackend *blk; BlockDriverState *bs; BlockDriverState *target_bs; BlockDriverState *source = NULL; @@ -3177,24 +3169,14 @@ static void do_drive_backup(const char *job_id, const char *device, mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS; } - blk = blk_by_name(device); - if (!blk) { - error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, - "Device '%s' not found", device); + bs = qmp_get_root_bs(device, errp); + if (!bs) { return; } - aio_context = blk_get_aio_context(blk); + aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); - /* Although backup_run has this check too, we need to use bs->drv below, so - * do an early check redundantly. */ - if (!blk_is_available(blk)) { - error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); - goto out; - } - bs = blk_bs(blk); - if (!has_format) { format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name; } diff --git a/qapi/block-core.json b/qapi/block-core.json index d25ba46b7783d2310708848cfdeebadba7956ef0..f081eb8c56a0b064eda278350c46affea3fdff18 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -876,7 +876,7 @@ # @job-id: #optional identifier for the newly-created block job. If # omitted, the device name will be used. (Since 2.7) # -# @device: the name of the device which should be copied. +# @device: the device name or node-name of a root node which should be copied. # # @target: the target of the new image. If the file exists, or if it # is a device, the existing file/device will be used as the new @@ -1087,7 +1087,7 @@ # For the arguments, see the documentation of DriveBackup. # # Returns: nothing on success -# If @device is not a valid block device, DeviceNotFound +# If @device is not a valid block device, GenericError # # Since 1.6 ## diff --git a/qmp-commands.hx b/qmp-commands.hx index c4ca603c5d8f94e49cd52c5386d2a850d6bcad6c..c5e6cd57aae84c2f75eb551274e31c958fc3cabc 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -1235,7 +1235,7 @@ Arguments: - "job-id": Identifier for the newly-created block job. If omitted, the device name will be used. (json-string, optional) -- "device": the name of the device which should be copied. +- "device": the device name or node-name of a root node which should be copied. (json-string) - "target": the target of the new image. If the file exists, or if it is a device, the existing file/device will be used as the new diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055 index c8e35787020eef8d14e2a66c13e34db27f37d68f..8113c61ade7be518f9dbb4cb1ce085a0d97a2bd7 100755 --- a/tests/qemu-iotests/055 +++ b/tests/qemu-iotests/055 @@ -134,10 +134,7 @@ class TestSingleDrive(iotests.QMPTestCase): def do_test_device_not_found(self, cmd, **args): result = self.vm.qmp(cmd, **args) - if cmd == 'drive-backup': - self.assert_qmp(result, 'error/class', 'DeviceNotFound') - else: - self.assert_qmp(result, 'error/class', 'GenericError') + self.assert_qmp(result, 'error/class', 'GenericError') def test_device_not_found(self): self.do_test_device_not_found('drive-backup', device='nonexistent', @@ -371,7 +368,7 @@ class TestSingleTransaction(iotests.QMPTestCase): 'sync': 'full' }, } ]) - self.assert_qmp(result, 'error/class', 'DeviceNotFound') + self.assert_qmp(result, 'error/class', 'GenericError') result = self.vm.qmp('transaction', actions=[{ 'type': 'blockdev-backup',