hmp/qmp: add block_set_io_throttle

Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Zhi Yong Wu 2011-11-08 13:00:31 +08:00 committed by Kevin Wolf
parent 98f90dba5e
commit 727f005e6a
9 changed files with 175 additions and 2 deletions

15
block.c
View file

@ -1978,6 +1978,21 @@ BlockInfoList *qmp_query_block(Error **errp)
info->value->inserted->has_backing_file = true;
info->value->inserted->backing_file = g_strdup(bs->backing_file);
}
if (bs->io_limits_enabled) {
info->value->inserted->bps =
bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL];
info->value->inserted->bps_rd =
bs->io_limits.bps[BLOCK_IO_LIMIT_READ];
info->value->inserted->bps_wr =
bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE];
info->value->inserted->iops =
bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL];
info->value->inserted->iops_rd =
bs->io_limits.iops[BLOCK_IO_LIMIT_READ];
info->value->inserted->iops_wr =
bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE];
}
}
/* XXX: waiting for the qapi to support GSList */

View file

@ -759,6 +759,65 @@ int do_change_block(Monitor *mon, const char *device,
return monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
}
/* throttling disk I/O limits */
int do_block_set_io_throttle(Monitor *mon,
const QDict *qdict, QObject **ret_data)
{
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);
if (!bs) {
qerror_report(QERR_DEVICE_NOT_FOUND, devname);
return -1;
}
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;
}
if (!do_check_io_limits(&io_limits)) {
qerror_report(QERR_INVALID_PARAMETER_COMBINATION);
return -1;
}
bs->io_limits = io_limits;
bs->slice_time = BLOCK_IO_SLICE_TIME;
if (!bs->io_limits_enabled && bdrv_io_limits_enabled(bs)) {
bdrv_io_limits_enable(bs);
} else if (bs->io_limits_enabled && !bdrv_io_limits_enabled(bs)) {
bdrv_io_limits_disable(bs);
} else {
if (bs->block_timer) {
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)
{
const char *id = qdict_get_str(qdict, "id");

View file

@ -63,6 +63,8 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt);
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_set_io_throttle(Monitor *mon,
const QDict *qdict, QObject **ret_data);
int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data);

View file

@ -1206,6 +1206,21 @@ ETEXI
.mhandler.cmd_new = do_block_set_passwd,
},
STEXI
@item block_set_io_throttle @var{device} @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}
@findex block_set_io_throttle
Change I/O throttle limits for a block drive to @var{bps} @var{bps_rd} @var{bps_wr} @var{iops} @var{iops_rd} @var{iops_wr}
ETEXI
{
.name = "block_set_io_throttle",
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
.params = "device bps bps_rd bps_wr iops iops_rd iops_wr",
.help = "change I/O throttle limits for a block drive",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_io_throttle,
},
STEXI
@item block_passwd @var{device} @var{password}
@findex block_passwd

10
hmp.c
View file

@ -216,6 +216,16 @@ void hmp_info_block(Monitor *mon)
info->value->inserted->ro,
info->value->inserted->drv,
info->value->inserted->encrypted);
monitor_printf(mon, " bps=%" PRId64 " bps_rd=%" PRId64
" bps_wr=%" PRId64 " iops=%" PRId64
" iops_rd=%" PRId64 " iops_wr=%" PRId64,
info->value->inserted->bps,
info->value->inserted->bps_rd,
info->value->inserted->bps_wr,
info->value->inserted->iops,
info->value->inserted->iops_rd,
info->value->inserted->iops_wr);
} else {
monitor_printf(mon, " [not inserted]");
}

View file

@ -370,13 +370,27 @@
#
# @encrypted: true if the backing device is encrypted
#
# @bps: total throughput limit in bytes per second is specified
#
# @bps_rd: read throughput limit in bytes per second is specified
#
# @bps_wr: write throughput limit in bytes per second is specified
#
# @iops: total I/O operations per second is specified
#
# @iops_rd: read I/O operations per second is specified
#
# @iops_wr: write I/O operations per second is specified
#
# Since: 0.14.0
#
# Notes: This interface is only found in @BlockInfo.
##
{ 'type': 'BlockDeviceInfo',
'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
'*backing_file': 'str', 'encrypted': 'bool' } }
'*backing_file': 'str', 'encrypted': 'bool',
'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int'} }
##
# @BlockDeviceIoStatus:

View file

@ -246,6 +246,10 @@ static const QErrorStringTable qerror_table[] = {
.error_fmt = QERR_QGA_COMMAND_FAILED,
.desc = "Guest agent command failed, error was '%(message)'",
},
{
.error_fmt = QERR_INVALID_PARAMETER_COMBINATION,
.desc = "Invalid paramter combination",
},
{}
};

View file

@ -204,4 +204,7 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_QGA_COMMAND_FAILED \
"{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }"
#define QERR_INVALID_PARAMETER_COMBINATION \
"{ 'class': 'InvalidParameterCombination', 'data': {} }"
#endif /* QERROR_H */

View file

@ -848,6 +848,44 @@ Example:
"password": "12345" } }
<- { "return": {} }
EQMP
{
.name = "block_set_io_throttle",
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l",
.params = "device bps bps_rd bps_wr iops iops_rd iops_wr",
.help = "change I/O throttle limits for a block drive",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_block_set_io_throttle,
},
SQMP
block_set_io_throttle
------------
Change I/O throttle limits for a block drive.
Arguments:
- "device": device name (json-string)
- "bps": total throughput limit in bytes per second(json-int)
- "bps_rd": read throughput limit in bytes per second(json-int)
- "bps_wr": read throughput limit in bytes per second(json-int)
- "iops": total I/O operations per second(json-int)
- "iops_rd": read I/O operations per second(json-int)
- "iops_wr": write I/O operations per second(json-int)
Example:
-> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
"bps": "1000000",
"bps_rd": "0",
"bps_wr": "0",
"iops": "0",
"iops_rd": "0",
"iops_wr": "0" } }
<- { "return": {} }
EQMP
{
@ -1152,6 +1190,13 @@ Each json-object contain the following:
"tftp", "vdi", "vmdk", "vpc", "vvfat"
- "backing_file": backing file name (json-string, optional)
- "encrypted": true if encrypted, false otherwise (json-bool)
- "bps": limit total bytes per second (json-int)
- "bps_rd": limit read bytes per second (json-int)
- "bps_wr": limit write bytes per second (json-int)
- "iops": limit total I/O operations per second (json-int)
- "iops_rd": limit read operations per second (json-int)
- "iops_wr": limit write operations per second (json-int)
- "io-status": I/O operation status, only present if the device supports it
and the VM is configured to stop on errors. It's always reset
to "ok" when the "cont" command is issued (json_string, optional)
@ -1171,7 +1216,13 @@ Example:
"ro":false,
"drv":"qcow2",
"encrypted":false,
"file":"disks/test.img"
"file":"disks/test.img",
"bps":1000000,
"bps_rd":0,
"bps_wr":0,
"iops":1000000,
"iops_rd":0,
"iops_wr":0,
},
"type":"unknown"
},