diff options
Diffstat (limited to 'blockdev.c')
| -rw-r--r-- | blockdev.c | 155 |
1 files changed, 86 insertions, 69 deletions
diff --git a/blockdev.c b/blockdev.c index c832782d03..1f83c888e7 100644 --- a/blockdev.c +++ b/blockdev.c @@ -665,35 +665,35 @@ void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file, } } -static int eject_device(Monitor *mon, BlockDriverState *bs, int force) +static void eject_device(BlockDriverState *bs, int force, Error **errp) { if (!bdrv_dev_has_removable_media(bs)) { - qerror_report(QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs)); - return -1; + error_set(errp, QERR_DEVICE_NOT_REMOVABLE, bdrv_get_device_name(bs)); + return; } + if (bdrv_dev_is_medium_locked(bs) && !bdrv_dev_is_tray_open(bs)) { bdrv_dev_eject_request(bs, force); if (!force) { - qerror_report(QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); - return -1; + error_set(errp, QERR_DEVICE_LOCKED, bdrv_get_device_name(bs)); + return; } } + bdrv_close(bs); - return 0; } -int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) +void qmp_eject(const char *device, bool has_force, bool force, Error **errp) { BlockDriverState *bs; - int force = qdict_get_try_bool(qdict, "force", 0); - const char *filename = qdict_get_str(qdict, "device"); - bs = bdrv_find(filename); + bs = bdrv_find(device); if (!bs) { - qerror_report(QERR_DEVICE_NOT_FOUND, filename); - return -1; + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; } - return eject_device(mon, bs, force); + + eject_device(bs, force, errp); } void qmp_block_passwd(const char *device, const char *password, Error **errp) @@ -717,78 +717,87 @@ void qmp_block_passwd(const char *device, const char *password, Error **errp) } } -int do_change_block(Monitor *mon, const char *device, - const char *filename, const char *fmt) +static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, + int bdrv_flags, BlockDriver *drv, + const char *password, Error **errp) +{ + if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) { + error_set(errp, QERR_OPEN_FILE_FAILED, filename); + return; + } + + if (bdrv_key_required(bs)) { + if (password) { + if (bdrv_set_key(bs, password) < 0) { + error_set(errp, QERR_INVALID_PASSWORD); + } + } else { + error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs), + bdrv_get_encrypted_filename(bs)); + } + } else if (password) { + error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs)); + } +} + +void qmp_change_blockdev(const char *device, const char *filename, + bool has_format, const char *format, Error **errp) { BlockDriverState *bs; BlockDriver *drv = NULL; int bdrv_flags; + Error *err = NULL; bs = bdrv_find(device); if (!bs) { - qerror_report(QERR_DEVICE_NOT_FOUND, device); - return -1; + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; } - if (fmt) { - drv = bdrv_find_whitelisted_format(fmt); + + if (format) { + drv = bdrv_find_whitelisted_format(format); if (!drv) { - qerror_report(QERR_INVALID_BLOCK_FORMAT, fmt); - return -1; + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); + return; } } - if (eject_device(mon, bs, 0) < 0) { - return -1; + + eject_device(bs, 0, &err); + if (error_is_set(&err)) { + error_propagate(errp, err); + return; } + bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR; bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0; - if (bdrv_open(bs, filename, bdrv_flags, drv) < 0) { - qerror_report(QERR_OPEN_FILE_FAILED, filename); - return -1; - } - return monitor_read_bdrv_key_start(mon, bs, NULL, NULL); + + qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp); } /* throttling disk I/O limits */ -int do_block_set_io_throttle(Monitor *mon, - const QDict *qdict, QObject **ret_data) +void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd, + int64_t bps_wr, int64_t iops, int64_t iops_rd, + int64_t iops_wr, Error **errp) { BlockIOLimit io_limits; - const char *devname = qdict_get_str(qdict, "device"); BlockDriverState *bs; - io_limits.bps[BLOCK_IO_LIMIT_TOTAL] - = qdict_get_try_int(qdict, "bps", -1); - io_limits.bps[BLOCK_IO_LIMIT_READ] - = qdict_get_try_int(qdict, "bps_rd", -1); - io_limits.bps[BLOCK_IO_LIMIT_WRITE] - = qdict_get_try_int(qdict, "bps_wr", -1); - io_limits.iops[BLOCK_IO_LIMIT_TOTAL] - = qdict_get_try_int(qdict, "iops", -1); - io_limits.iops[BLOCK_IO_LIMIT_READ] - = qdict_get_try_int(qdict, "iops_rd", -1); - io_limits.iops[BLOCK_IO_LIMIT_WRITE] - = qdict_get_try_int(qdict, "iops_wr", -1); - - bs = bdrv_find(devname); + bs = bdrv_find(device); if (!bs) { - qerror_report(QERR_DEVICE_NOT_FOUND, devname); - return -1; + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; } - if ((io_limits.bps[BLOCK_IO_LIMIT_TOTAL] == -1) - || (io_limits.bps[BLOCK_IO_LIMIT_READ] == -1) - || (io_limits.bps[BLOCK_IO_LIMIT_WRITE] == -1) - || (io_limits.iops[BLOCK_IO_LIMIT_TOTAL] == -1) - || (io_limits.iops[BLOCK_IO_LIMIT_READ] == -1) - || (io_limits.iops[BLOCK_IO_LIMIT_WRITE] == -1)) { - qerror_report(QERR_MISSING_PARAMETER, - "bps/bps_rd/bps_wr/iops/iops_rd/iops_wr"); - return -1; - } + io_limits.bps[BLOCK_IO_LIMIT_TOTAL] = bps; + io_limits.bps[BLOCK_IO_LIMIT_READ] = bps_rd; + io_limits.bps[BLOCK_IO_LIMIT_WRITE] = bps_wr; + io_limits.iops[BLOCK_IO_LIMIT_TOTAL]= iops; + io_limits.iops[BLOCK_IO_LIMIT_READ] = iops_rd; + io_limits.iops[BLOCK_IO_LIMIT_WRITE]= iops_wr; if (!do_check_io_limits(&io_limits)) { - qerror_report(QERR_INVALID_PARAMETER_COMBINATION); - return -1; + error_set(errp, QERR_INVALID_PARAMETER_COMBINATION); + return; } bs->io_limits = io_limits; @@ -803,8 +812,6 @@ int do_block_set_io_throttle(Monitor *mon, qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock)); } } - - return 0; } int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) @@ -841,11 +848,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data) return 0; } -/* - * XXX: replace the QERR_UNDEFINED_ERROR errors with real values once the - * existing QERR_ macro mess is cleaned up. A good example for better - * error reports can be found in the qemu-img resize code. - */ void qmp_block_resize(const char *device, int64_t size, Error **errp) { BlockDriverState *bs; @@ -857,12 +859,27 @@ void qmp_block_resize(const char *device, int64_t size, Error **errp) } if (size < 0) { - error_set(errp, QERR_UNDEFINED_ERROR); + error_set(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size"); return; } - if (bdrv_truncate(bs, size)) { + switch (bdrv_truncate(bs, size)) { + case 0: + break; + case -ENOMEDIUM: + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); + break; + case -ENOTSUP: + error_set(errp, QERR_UNSUPPORTED); + break; + case -EACCES: + error_set(errp, QERR_DEVICE_IS_READ_ONLY, device); + break; + case -EBUSY: + error_set(errp, QERR_DEVICE_IN_USE, device); + break; + default: error_set(errp, QERR_UNDEFINED_ERROR); - return; + break; } } |