Now the high watermark and statistics of the underlying images are exposed via QMP, but they are missing in the user monitor. This patch changes the user monitor to provide the same functionality.
Note that it's not possible to maintain compatibility with older clients that try to parse the output of this command. They need to use QMP for a stable API. The new info blockstats output looks like this (and yes, the example shows that read/write statistics are broken currently, they ignore synchronous I/O): (qemu) info blockstats ide0-hd0: qcow2 rd_bytes=814592 rd_ops=1591 wr_bytes=0 wr_ops=0 wr_highest_offset=0 file rd_bytes=814592 rd_ops=1591 wr_bytes=0 wr_ops=0 wr_highest_offset=0 Signed-off-by: Kevin Wolf <kw...@redhat.com> --- block.c | 35 +++++++++++++++++++++-------------- qdict.c | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/block.c b/block.c index b75cef2..b22325e 100644 --- a/block.c +++ b/block.c @@ -1517,19 +1517,25 @@ static void bdrv_stats_iter(QObject *data, void *opaque) qdict = qobject_to_qdict(data); monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); - qdict = qobject_to_qdict(qdict_get(qdict, "stats")); - monitor_printf(mon, " rd_bytes=%" PRId64 - " wr_bytes=%" PRId64 - " rd_operations=%" PRId64 - " wr_operations=%" 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")); - if (qdict_haskey(qdict, "parent")) { - QObject *parent = qdict_get(qdict, "parent"); - bdrv_stats_iter(parent, mon); + while (qdict) { + QDict *stats = qobject_to_qdict(qdict_get(qdict, "stats")); + + monitor_printf(mon, "\n %-12s rd_bytes=%" PRId64 + " rd_ops=%" PRId64 + "\n %-12s wr_bytes=%" PRId64 + " wr_ops=%" PRId64 + " wr_highest_offset=%" PRId64 + "\n", + qdict_get_str(qdict, "format"), + qdict_get_int(stats, "rd_bytes"), + qdict_get_int(stats, "rd_operations"), + "", + qdict_get_int(stats, "wr_bytes"), + qdict_get_int(stats, "wr_operations"), + qdict_get_int(stats, "wr_highest_offset")); + + + qdict = qobject_to_qdict(qdict_get(qdict, "parent")); } } @@ -1547,7 +1553,7 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs) parent = bdrv_info_stats_bs(bs->file); } - res = qobject_from_jsonf("{ 'device': %s, 'stats': {" + res = qobject_from_jsonf("{ 'device': %s, 'format': %s, 'stats': {" "'rd_bytes': %" PRId64 "," "'wr_bytes': %" PRId64 "," "'rd_operations': %" PRId64 "," @@ -1555,6 +1561,7 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs) "'wr_highest_offset': %" PRId64 "} }", bs->device_name, + bs->drv ? bs->drv->format_name : "none", bs->rd_bytes, bs->wr_bytes, bs->rd_ops, bs->wr_ops, bs->wr_highest_sector * 512); diff --git a/qdict.c b/qdict.c index aae57bf..32491db 100644 --- a/qdict.c +++ b/qdict.c @@ -46,7 +46,7 @@ QDict *qdict_new(void) */ QDict *qobject_to_qdict(const QObject *obj) { - if (qobject_type(obj) != QTYPE_QDICT) + if (!obj || qobject_type(obj) != QTYPE_QDICT) return NULL; return container_of(obj, QDict, base); -- 1.6.6.1