提交 727f005e 编写于 作者: Z Zhi Yong Wu 提交者: Kevin Wolf

hmp/qmp: add block_set_io_throttle

Signed-off-by: NZhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Signed-off-by: NStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 98f90dba
...@@ -1978,6 +1978,21 @@ BlockInfoList *qmp_query_block(Error **errp) ...@@ -1978,6 +1978,21 @@ BlockInfoList *qmp_query_block(Error **errp)
info->value->inserted->has_backing_file = true; info->value->inserted->has_backing_file = true;
info->value->inserted->backing_file = g_strdup(bs->backing_file); 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 */ /* XXX: waiting for the qapi to support GSList */
......
...@@ -759,6 +759,65 @@ int do_change_block(Monitor *mon, const char *device, ...@@ -759,6 +759,65 @@ int do_change_block(Monitor *mon, const char *device,
return monitor_read_bdrv_key_start(mon, bs, NULL, NULL); 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) int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{ {
const char *id = qdict_get_str(qdict, "id"); const char *id = qdict_get_str(qdict, "id");
......
...@@ -63,6 +63,8 @@ int do_block_set_passwd(Monitor *mon, const QDict *qdict, QObject **ret_data); ...@@ -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, int do_change_block(Monitor *mon, const char *device,
const char *filename, const char *fmt); const char *filename, const char *fmt);
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data); 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_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data);
......
...@@ -1206,6 +1206,21 @@ ETEXI ...@@ -1206,6 +1206,21 @@ ETEXI
.mhandler.cmd_new = do_block_set_passwd, .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 STEXI
@item block_passwd @var{device} @var{password} @item block_passwd @var{device} @var{password}
@findex block_passwd @findex block_passwd
......
...@@ -216,6 +216,16 @@ void hmp_info_block(Monitor *mon) ...@@ -216,6 +216,16 @@ void hmp_info_block(Monitor *mon)
info->value->inserted->ro, info->value->inserted->ro,
info->value->inserted->drv, info->value->inserted->drv,
info->value->inserted->encrypted); 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 { } else {
monitor_printf(mon, " [not inserted]"); monitor_printf(mon, " [not inserted]");
} }
......
...@@ -370,13 +370,27 @@ ...@@ -370,13 +370,27 @@
# #
# @encrypted: true if the backing device is encrypted # @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 # Since: 0.14.0
# #
# Notes: This interface is only found in @BlockInfo. # Notes: This interface is only found in @BlockInfo.
## ##
{ 'type': 'BlockDeviceInfo', { 'type': 'BlockDeviceInfo',
'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str', '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: # @BlockDeviceIoStatus:
......
...@@ -246,6 +246,10 @@ static const QErrorStringTable qerror_table[] = { ...@@ -246,6 +246,10 @@ static const QErrorStringTable qerror_table[] = {
.error_fmt = QERR_QGA_COMMAND_FAILED, .error_fmt = QERR_QGA_COMMAND_FAILED,
.desc = "Guest agent command failed, error was '%(message)'", .desc = "Guest agent command failed, error was '%(message)'",
}, },
{
.error_fmt = QERR_INVALID_PARAMETER_COMBINATION,
.desc = "Invalid paramter combination",
},
{} {}
}; };
......
...@@ -204,4 +204,7 @@ QError *qobject_to_qerror(const QObject *obj); ...@@ -204,4 +204,7 @@ QError *qobject_to_qerror(const QObject *obj);
#define QERR_QGA_COMMAND_FAILED \ #define QERR_QGA_COMMAND_FAILED \
"{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }" "{ 'class': 'QgaCommandFailed', 'data': { 'message': %s } }"
#define QERR_INVALID_PARAMETER_COMBINATION \
"{ 'class': 'InvalidParameterCombination', 'data': {} }"
#endif /* QERROR_H */ #endif /* QERROR_H */
...@@ -848,6 +848,44 @@ Example: ...@@ -848,6 +848,44 @@ Example:
"password": "12345" } } "password": "12345" } }
<- { "return": {} } <- { "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 EQMP
{ {
...@@ -1152,6 +1190,13 @@ Each json-object contain the following: ...@@ -1152,6 +1190,13 @@ Each json-object contain the following:
"tftp", "vdi", "vmdk", "vpc", "vvfat" "tftp", "vdi", "vmdk", "vpc", "vvfat"
- "backing_file": backing file name (json-string, optional) - "backing_file": backing file name (json-string, optional)
- "encrypted": true if encrypted, false otherwise (json-bool) - "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 - "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 and the VM is configured to stop on errors. It's always reset
to "ok" when the "cont" command is issued (json_string, optional) to "ok" when the "cont" command is issued (json_string, optional)
...@@ -1171,7 +1216,13 @@ Example: ...@@ -1171,7 +1216,13 @@ Example:
"ro":false, "ro":false,
"drv":"qcow2", "drv":"qcow2",
"encrypted":false, "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" "type":"unknown"
}, },
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册