qapi: Convert query-blockstats
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
parent
b202381800
commit
f11f57e405
105
block.c
105
block.c
@ -1874,93 +1874,56 @@ BlockInfoList *qmp_query_block(Error **errp)
|
|||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bdrv_stats_iter(QObject *data, void *opaque)
|
/* Consider exposing this as a full fledged QMP command */
|
||||||
|
static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp)
|
||||||
{
|
{
|
||||||
QDict *qdict;
|
BlockStats *s;
|
||||||
Monitor *mon = opaque;
|
|
||||||
|
|
||||||
qdict = qobject_to_qdict(data);
|
s = g_malloc0(sizeof(*s));
|
||||||
monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
|
|
||||||
|
|
||||||
qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
|
if (bs->device_name[0]) {
|
||||||
monitor_printf(mon, " rd_bytes=%" PRId64
|
s->has_device = true;
|
||||||
" wr_bytes=%" PRId64
|
s->device = g_strdup(bs->device_name);
|
||||||
" rd_operations=%" PRId64
|
|
||||||
" wr_operations=%" PRId64
|
|
||||||
" flush_operations=%" PRId64
|
|
||||||
" wr_total_time_ns=%" PRId64
|
|
||||||
" rd_total_time_ns=%" PRId64
|
|
||||||
" flush_total_time_ns=%" PRId64
|
|
||||||
"\n",
|
|
||||||
qdict_get_int(qdict, "rd_bytes"),
|
|
||||||
qdict_get_int(qdict, "wr_bytes"),
|
|
||||||
qdict_get_int(qdict, "rd_operations"),
|
|
||||||
qdict_get_int(qdict, "wr_operations"),
|
|
||||||
qdict_get_int(qdict, "flush_operations"),
|
|
||||||
qdict_get_int(qdict, "wr_total_time_ns"),
|
|
||||||
qdict_get_int(qdict, "rd_total_time_ns"),
|
|
||||||
qdict_get_int(qdict, "flush_total_time_ns"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void bdrv_stats_print(Monitor *mon, const QObject *data)
|
|
||||||
{
|
|
||||||
qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
|
|
||||||
}
|
|
||||||
|
|
||||||
static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
|
|
||||||
{
|
|
||||||
QObject *res;
|
|
||||||
QDict *dict;
|
|
||||||
|
|
||||||
res = qobject_from_jsonf("{ 'stats': {"
|
|
||||||
"'rd_bytes': %" PRId64 ","
|
|
||||||
"'wr_bytes': %" PRId64 ","
|
|
||||||
"'rd_operations': %" PRId64 ","
|
|
||||||
"'wr_operations': %" PRId64 ","
|
|
||||||
"'wr_highest_offset': %" PRId64 ","
|
|
||||||
"'flush_operations': %" PRId64 ","
|
|
||||||
"'wr_total_time_ns': %" PRId64 ","
|
|
||||||
"'rd_total_time_ns': %" PRId64 ","
|
|
||||||
"'flush_total_time_ns': %" PRId64
|
|
||||||
"} }",
|
|
||||||
bs->nr_bytes[BDRV_ACCT_READ],
|
|
||||||
bs->nr_bytes[BDRV_ACCT_WRITE],
|
|
||||||
bs->nr_ops[BDRV_ACCT_READ],
|
|
||||||
bs->nr_ops[BDRV_ACCT_WRITE],
|
|
||||||
bs->wr_highest_sector *
|
|
||||||
(uint64_t)BDRV_SECTOR_SIZE,
|
|
||||||
bs->nr_ops[BDRV_ACCT_FLUSH],
|
|
||||||
bs->total_time_ns[BDRV_ACCT_WRITE],
|
|
||||||
bs->total_time_ns[BDRV_ACCT_READ],
|
|
||||||
bs->total_time_ns[BDRV_ACCT_FLUSH]);
|
|
||||||
dict = qobject_to_qdict(res);
|
|
||||||
|
|
||||||
if (*bs->device_name) {
|
|
||||||
qdict_put(dict, "device", qstring_from_str(bs->device_name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->stats = g_malloc0(sizeof(*s->stats));
|
||||||
|
s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
|
||||||
|
s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
|
||||||
|
s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
|
||||||
|
s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
|
||||||
|
s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
|
||||||
|
s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
|
||||||
|
s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
|
||||||
|
s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
|
||||||
|
s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
|
||||||
|
|
||||||
if (bs->file) {
|
if (bs->file) {
|
||||||
QObject *parent = bdrv_info_stats_bs(bs->file);
|
s->has_parent = true;
|
||||||
qdict_put_obj(dict, "parent", parent);
|
s->parent = qmp_query_blockstat(bs->file, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_info_stats(Monitor *mon, QObject **ret_data)
|
BlockStatsList *qmp_query_blockstats(Error **errp)
|
||||||
{
|
{
|
||||||
QObject *obj;
|
BlockStatsList *head = NULL, *cur_item = NULL;
|
||||||
QList *devices;
|
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
|
||||||
devices = qlist_new();
|
|
||||||
|
|
||||||
QTAILQ_FOREACH(bs, &bdrv_states, list) {
|
QTAILQ_FOREACH(bs, &bdrv_states, list) {
|
||||||
obj = bdrv_info_stats_bs(bs);
|
BlockStatsList *info = g_malloc0(sizeof(*info));
|
||||||
qlist_append_obj(devices, obj);
|
info->value = qmp_query_blockstat(bs, NULL);
|
||||||
|
|
||||||
|
/* XXX: waiting for the qapi to support GSList */
|
||||||
|
if (!cur_item) {
|
||||||
|
head = cur_item = info;
|
||||||
|
} else {
|
||||||
|
cur_item->next = info;
|
||||||
|
cur_item = info;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_data = QOBJECT(devices);
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
|
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
|
||||||
|
34
hmp.c
34
hmp.c
@ -226,6 +226,40 @@ void hmp_info_block(Monitor *mon)
|
|||||||
qapi_free_BlockInfoList(block_list);
|
qapi_free_BlockInfoList(block_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmp_info_blockstats(Monitor *mon)
|
||||||
|
{
|
||||||
|
BlockStatsList *stats_list, *stats;
|
||||||
|
|
||||||
|
stats_list = qmp_query_blockstats(NULL);
|
||||||
|
|
||||||
|
for (stats = stats_list; stats; stats = stats->next) {
|
||||||
|
if (!stats->value->has_device) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_printf(mon, "%s:", stats->value->device);
|
||||||
|
monitor_printf(mon, " rd_bytes=%" PRId64
|
||||||
|
" wr_bytes=%" PRId64
|
||||||
|
" rd_operations=%" PRId64
|
||||||
|
" wr_operations=%" PRId64
|
||||||
|
" flush_operations=%" PRId64
|
||||||
|
" wr_total_time_ns=%" PRId64
|
||||||
|
" rd_total_time_ns=%" PRId64
|
||||||
|
" flush_total_time_ns=%" PRId64
|
||||||
|
"\n",
|
||||||
|
stats->value->stats->rd_bytes,
|
||||||
|
stats->value->stats->wr_bytes,
|
||||||
|
stats->value->stats->rd_operations,
|
||||||
|
stats->value->stats->wr_operations,
|
||||||
|
stats->value->stats->flush_operations,
|
||||||
|
stats->value->stats->wr_total_time_ns,
|
||||||
|
stats->value->stats->rd_total_time_ns,
|
||||||
|
stats->value->stats->flush_total_time_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
qapi_free_BlockStatsList(stats_list);
|
||||||
|
}
|
||||||
|
|
||||||
void hmp_quit(Monitor *mon, const QDict *qdict)
|
void hmp_quit(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
monitor_suspend(mon);
|
monitor_suspend(mon);
|
||||||
|
1
hmp.h
1
hmp.h
@ -27,6 +27,7 @@ void hmp_info_mice(Monitor *mon);
|
|||||||
void hmp_info_migrate(Monitor *mon);
|
void hmp_info_migrate(Monitor *mon);
|
||||||
void hmp_info_cpus(Monitor *mon);
|
void hmp_info_cpus(Monitor *mon);
|
||||||
void hmp_info_block(Monitor *mon);
|
void hmp_info_block(Monitor *mon);
|
||||||
|
void hmp_info_blockstats(Monitor *mon);
|
||||||
void hmp_quit(Monitor *mon, const QDict *qdict);
|
void hmp_quit(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_stop(Monitor *mon, const QDict *qdict);
|
void hmp_stop(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_system_reset(Monitor *mon, const QDict *qdict);
|
void hmp_system_reset(Monitor *mon, const QDict *qdict);
|
||||||
|
11
monitor.c
11
monitor.c
@ -2681,8 +2681,7 @@ static const mon_cmd_t info_cmds[] = {
|
|||||||
.args_type = "",
|
.args_type = "",
|
||||||
.params = "",
|
.params = "",
|
||||||
.help = "show block device statistics",
|
.help = "show block device statistics",
|
||||||
.user_print = bdrv_stats_print,
|
.mhandler.info = hmp_info_blockstats,
|
||||||
.mhandler.info_new = bdrv_info_stats,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "registers",
|
.name = "registers",
|
||||||
@ -2959,14 +2958,6 @@ static const mon_cmd_t qmp_cmds[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const mon_cmd_t qmp_query_cmds[] = {
|
static const mon_cmd_t qmp_query_cmds[] = {
|
||||||
{
|
|
||||||
.name = "blockstats",
|
|
||||||
.args_type = "",
|
|
||||||
.params = "",
|
|
||||||
.help = "show block device statistics",
|
|
||||||
.user_print = bdrv_stats_print,
|
|
||||||
.mhandler.info_new = bdrv_info_stats,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.name = "pci",
|
.name = "pci",
|
||||||
.args_type = "",
|
.args_type = "",
|
||||||
|
@ -436,6 +436,73 @@
|
|||||||
##
|
##
|
||||||
{ 'command': 'query-block', 'returns': ['BlockInfo'] }
|
{ 'command': 'query-block', 'returns': ['BlockInfo'] }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockDeviceStats:
|
||||||
|
#
|
||||||
|
# Statistics of a virtual block device or a block backing device.
|
||||||
|
#
|
||||||
|
# @rd_bytes: The number of bytes read by the device.
|
||||||
|
#
|
||||||
|
# @wr_bytes: The number of bytes written by the device.
|
||||||
|
#
|
||||||
|
# @rd_operations: The number of read operations performed by the device.
|
||||||
|
#
|
||||||
|
# @wr_operations: The number of write operations performed by the device.
|
||||||
|
#
|
||||||
|
# @flush_operations: The number of cache flush operations performed by the
|
||||||
|
# device (since 0.15.0)
|
||||||
|
#
|
||||||
|
# @flush_total_time_ns: Total time spend on cache flushes in nano-seconds
|
||||||
|
# (since 0.15.0).
|
||||||
|
#
|
||||||
|
# @wr_total_time_ns: Total time spend on writes in nano-seconds (since 0.15.0).
|
||||||
|
#
|
||||||
|
# @rd_total_time_ns: Total_time_spend on reads in nano-seconds (since 0.15.0).
|
||||||
|
#
|
||||||
|
# @wr_highest_offset: The offset after the greatest byte written to the
|
||||||
|
# device. The intended use of this information is for
|
||||||
|
# growable sparse files (like qcow2) that are used on top
|
||||||
|
# of a physical device.
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'type': 'BlockDeviceStats',
|
||||||
|
'data': {'rd_bytes': 'int', 'wr_bytes': 'int', 'rd_operations': 'int',
|
||||||
|
'wr_operations': 'int', 'flush_operations': 'int',
|
||||||
|
'flush_total_time_ns': 'int', 'wr_total_time_ns': 'int',
|
||||||
|
'rd_total_time_ns': 'int', 'wr_highest_offset': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockStats:
|
||||||
|
#
|
||||||
|
# Statistics of a virtual block device or a block backing device.
|
||||||
|
#
|
||||||
|
# @device: #optional If the stats are for a virtual block device, the name
|
||||||
|
# corresponding to the virtual block device.
|
||||||
|
#
|
||||||
|
# @stats: A @BlockDeviceStats for the device.
|
||||||
|
#
|
||||||
|
# @parent: #optional This may point to the backing block device if this is a
|
||||||
|
# a virtual block device. If it's a backing block, this will point
|
||||||
|
# to the backing file is one is present.
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'type': 'BlockStats',
|
||||||
|
'data': {'*device': 'str', 'stats': 'BlockDeviceStats',
|
||||||
|
'*parent': 'BlockStats'} }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @query-blockstats:
|
||||||
|
#
|
||||||
|
# Query the @BlockStats for all virtual block devices.
|
||||||
|
#
|
||||||
|
# Returns: A list of @BlockStats for each virtual block devices.
|
||||||
|
#
|
||||||
|
# Since: 0.14.0
|
||||||
|
##
|
||||||
|
{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @quit:
|
# @quit:
|
||||||
#
|
#
|
||||||
|
@ -1311,6 +1311,12 @@ Example:
|
|||||||
|
|
||||||
EQMP
|
EQMP
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "query-blockstats",
|
||||||
|
.args_type = "",
|
||||||
|
.mhandler.cmd_new = qmp_marshal_input_query_blockstats,
|
||||||
|
},
|
||||||
|
|
||||||
SQMP
|
SQMP
|
||||||
query-cpus
|
query-cpus
|
||||||
----------
|
----------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user