This command sets a watermark value for a device. The next commit will add the BLOCK_WATERMARK event, which is emitted when this value is reached.
Please, note that currently only the 'high' watermark value is supported. Signed-off-by: Luiz Capitulino <lcapitul...@redhat.com> --- block.c | 5 +++++ block.h | 2 ++ block_int.h | 3 +++ monitor.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ qemu-monitor.hx | 16 ++++++++++++++++ 5 files changed, 72 insertions(+), 0 deletions(-) diff --git a/block.c b/block.c index 31d1ba4..260502a 100644 --- a/block.c +++ b/block.c @@ -1209,6 +1209,11 @@ void bdrv_flush_all(void) bdrv_flush(bs); } +void bdrv_set_high_watermark(BlockDriverState *bs, uint64_t offset) +{ + bs->high_watermark = offset; +} + /* * Returns true iff the specified sector is present in the disk image. Drivers * not implementing the functionality are assumed to not support backing files, diff --git a/block.h b/block.h index edf5704..af32436 100644 --- a/block.h +++ b/block.h @@ -130,6 +130,8 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, void bdrv_flush(BlockDriverState *bs); void bdrv_flush_all(void); +void bdrv_set_high_watermark(BlockDriverState *bs, uint64_t offset); + int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum); diff --git a/block_int.h b/block_int.h index 50e1a0b..53e087d 100644 --- a/block_int.h +++ b/block_int.h @@ -156,6 +156,9 @@ struct BlockDriverState { void *sync_aiocb; + /* high watermark for monitor event */ + uint64_t high_watermark; + /* I/O stats (display with "info blockstats"). */ uint64_t rd_bytes; uint64_t wr_bytes; diff --git a/monitor.c b/monitor.c index 672ae47..595bd62 100644 --- a/monitor.c +++ b/monitor.c @@ -1041,6 +1041,52 @@ static int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) return eject_device(mon, bs, force); } +static int do_block_set_watermark(Monitor *mon, const QDict *qdict, + QObject **ret_data) +{ + int64_t offset; + char format[32]; + BlockDriverState *bs; + + bs = bdrv_find(qdict_get_str(qdict, "device")); + if (!bs) { + qemu_error_new(QERR_DEVICE_NOT_FOUND, qdict_get_str(qdict, "device")); + return -1; + } + + bdrv_get_format(bs, format, sizeof(format)); + + if (format[0] == '\0') { + qemu_error_new(QERR_DEVICE_NOT_ACTIVE, qdict_get_str(qdict, "device")); + return -1; + } + + /* we only support qcow2 currently */ + if (strcmp(format, "qcow2")) { + qemu_error_new(QERR_INVALID_BLOCK_FORMAT, format); + return -1; + } + + if (strcmp(qdict_get_str(qdict, "type"), "high")) { + qemu_error_new(QERR_INVALID_PARAMETER, "type"); + return -1; + } + + offset = qdict_get_int(qdict, "offset"); + if (offset < 0) { + qemu_error_new(QERR_INVALID_PARAMETER, "offset"); + return -1; + } + + /* + * XXX: 'offset' is int64_t because the monitor code doesn't + * work with uint64_t. Does it matter? If it does, the + * monitor has to be fixed. + */ + bdrv_set_high_watermark(bs, offset); + return 0; +} + static int do_block_set_passwd(Monitor *mon, const QDict *qdict, QObject **ret_data) { diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 7f9d261..c4b48db 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1127,6 +1127,22 @@ Set the encrypted device @var{device} password to @var{password} ETEXI { + .name = "block_watermark", + .args_type = "device:B,type:s,offset:l", + .params = "device type offset", + .help = "set block device watermark", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_set_watermark, + }, + +STEXI +...@item block_watermark @var{device} @var{type} @var{offset} +...@findex block_watermark +Set the block device @var{device} watermark @var{type} to @var{offset} +ETEXI + + + { .name = "qmp_capabilities", .args_type = "", .params = "", -- 1.7.0.1