#include "qemu-config.h"
#include "sysemu.h"
#include "block_int.h"
+#include "qmp-commands.h"
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
}
}
-int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_blockdev_snapshot_sync(const char *device, const char *snapshot_file,
+ bool has_format, const char *format,
+ Error **errp)
{
- const char *device = qdict_get_str(qdict, "device");
- const char *filename = qdict_get_try_str(qdict, "snapshot-file");
- const char *format = qdict_get_try_str(qdict, "format");
BlockDriverState *bs;
BlockDriver *drv, *old_drv, *proto_drv;
int ret = 0;
int flags;
char old_filename[1024];
- if (!filename) {
- qerror_report(QERR_MISSING_PARAMETER, "snapshot-file");
- ret = -1;
- goto out;
- }
-
bs = bdrv_find(device);
if (!bs) {
- qerror_report(QERR_DEVICE_NOT_FOUND, device);
- ret = -1;
- goto out;
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
}
pstrcpy(old_filename, sizeof(old_filename), bs->filename);
old_drv = bs->drv;
flags = bs->open_flags;
- if (!format) {
+ if (!has_format) {
format = "qcow2";
}
drv = bdrv_find_format(format);
if (!drv) {
- qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
- ret = -1;
- goto out;
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+ return;
}
- proto_drv = bdrv_find_protocol(filename);
+ proto_drv = bdrv_find_protocol(snapshot_file);
if (!proto_drv) {
- qerror_report(QERR_INVALID_BLOCK_FORMAT, format);
- ret = -1;
- goto out;
+ error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
+ return;
}
- ret = bdrv_img_create(filename, format, bs->filename,
+ ret = bdrv_img_create(snapshot_file, format, bs->filename,
bs->drv->format_name, NULL, -1, flags);
if (ret) {
- goto out;
+ error_set(errp, QERR_UNDEFINED_ERROR);
+ return;
}
- qemu_aio_flush();
+ bdrv_drain_all();
bdrv_flush(bs);
bdrv_close(bs);
- ret = bdrv_open(bs, filename, flags, drv);
+ ret = bdrv_open(bs, snapshot_file, flags, drv);
/*
* If reopening the image file we just created fails, fall back
* and try to re-open the original image. If that fails too, we
if (ret != 0) {
ret = bdrv_open(bs, old_filename, flags, old_drv);
if (ret != 0) {
- qerror_report(QERR_OPEN_FILE_FAILED, old_filename);
+ error_set(errp, QERR_OPEN_FILE_FAILED, old_filename);
} else {
- qerror_report(QERR_OPEN_FILE_FAILED, filename);
+ error_set(errp, QERR_OPEN_FILE_FAILED, snapshot_file);
}
}
-out:
- if (ret) {
- ret = -1;
- }
-
- return ret;
}
-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);
}
-int do_block_set_passwd(Monitor *mon, const QDict *qdict,
- QObject **ret_data)
+void qmp_block_passwd(const char *device, const char *password, Error **errp)
{
BlockDriverState *bs;
int err;
- bs = bdrv_find(qdict_get_str(qdict, "device"));
+ bs = bdrv_find(device);
if (!bs) {
- qerror_report(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device"));
- return -1;
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
}
- err = bdrv_set_key(bs, qdict_get_str(qdict, "password"));
+ err = bdrv_set_key(bs, password);
if (err == -EINVAL) {
- qerror_report(QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
- return -1;
+ error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
+ return;
} else if (err < 0) {
- qerror_report(QERR_INVALID_PASSWORD);
- return -1;
+ error_set(errp, QERR_INVALID_PASSWORD);
+ return;
}
+}
- return 0;
+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));
+ }
}
-int do_change_block(Monitor *mon, const char *device,
- const char *filename, const char *fmt)
+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;
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)
}
/* quiesce block driver; prevent further io */
- qemu_aio_flush();
+ bdrv_drain_all();
bdrv_flush(bs);
bdrv_close(bs);
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.
- */
-int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_block_resize(const char *device, int64_t size, Error **errp)
{
- const char *device = qdict_get_str(qdict, "device");
- int64_t size = qdict_get_int(qdict, "size");
BlockDriverState *bs;
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 (size < 0) {
- qerror_report(QERR_UNDEFINED_ERROR);
- return -1;
+ error_set(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size");
+ return;
}
- if (bdrv_truncate(bs, size)) {
- qerror_report(QERR_UNDEFINED_ERROR);
- return -1;
+ 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);
+ break;
}
-
- return 0;
}