Collecting block device statistics (v2)
PATCH 1/1 Collecting block device statistics (v2)
This is an updated patch for collecting block device statistics. Thanks to several people on #qemu channel for giving me feedback about the first version[1].
This patch collects per-block-device statistics and allows them to be displayed in the monitor through a 'info blockstats' command. It generalises the VMDK-only support for this which was added to KVM's version of QEMU.
Screenshot showing 'info blockstats' command being run for a Solaris guest which is doing some moderate disk activity:
http://www.annexia.org/tmp/Screenshot-QEMU-2.png
Rich.
[1] Previous patch was: http://lists.gnu.org/archive/html/qemu-devel/2007-11/msg00489.html
Signature · 4 lines
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/ Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 03798903
Index: block.c
===================================================================
RCS file: /sources/qemu/qemu/block.c,v
retrieving revision 1.49
block.c +46 -4
@@ -521,8 +521,11 @@return ret; else if (ret != len) return -EINVAL; - else + else { + bs->rd_bytes += (unsigned ) len; + bs->rd_ops ++;return 0 ; + } }else {return drv->bdrv_read (bs, sector_num, buf, nb_sectors); }
@@ -553,8 +556,11 @@return ret; else if (ret != len) return -EIO; - else + else { + bs->wr_bytes += (unsigned ) len; + bs->wr_ops ++;return 0 ; + } }else {return drv->bdrv_write (bs, sector_num, buf, nb_sectors); }
@@ -902,6 +908,24 @@ term_printf("\n"); } } + +/* The "info blockstats" command. */ +void bdrv_info_stats (void ) +{ +BlockDriverState *bs; + +for (bs = bdrv_first; bs !=NULL ; bs = bs->next) { +term_printf ("%s:" +" rd_bytes=%" PRIu64 +" wr_bytes=%" PRIu64 +" rd_operations=%" PRIu64 +" wr_operations=%" PRIu64 +"\n" , + bs->device_name, + bs->rd_bytes, bs->wr_bytes, + bs->rd_ops, bs->wr_ops); + } +}#endif void bdrv_get_backing_filename(BlockDriverState *bs,
@@ -1064,6 +1088,7 @@ BlockDriverCompletionFunc *cb, void *opaque) {BlockDriver *drv = bs->drv; +BlockDriverAIOCB *ret;if (!drv)return NULL ;
@@ -1076,7 +1101,15 @@ buf +=512 ; } -return drv->bdrv_aio_read (bs, sector_num, buf, nb_sectors, cb, opaque); + ret = drv->bdrv_aio_read (bs, sector_num, buf, nb_sectors, cb, opaque); + +if (ret) { +/* Update stats even though technically transfer has not happened. */ + bs->rd_bytes += (unsigned ) nb_sectors *SECTOR_SIZE ; + bs->rd_ops ++; + } + +return ret; } BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
@@ -1084,6 +1117,7 @@ BlockDriverCompletionFunc *cb, void *opaque) {BlockDriver *drv = bs->drv; +BlockDriverAIOCB *ret;if (!drv)return NULL ;
@@ -1093,7 +1127,15 @@memcpy (bs->boot_sector_data, buf,512 ); } -return drv->bdrv_aio_write (bs, sector_num, buf, nb_sectors, cb, opaque); + ret = drv->bdrv_aio_write (bs, sector_num, buf, nb_sectors, cb, opaque); + +if (ret) { +/* Update stats even though technically transfer has not happened. */ + bs->wr_bytes += (unsigned ) nb_sectors *SECTOR_SIZE ; + bs->wr_ops ++; + } + +return ret; }void bdrv_aio_cancel (BlockDriverAIOCB *acb)
Index: block.h
===================================================================
RCS file: /sources/qemu/qemu/block.h,v
retrieving revision 1.2
block.h +1 -0
@@ -47,6 +47,7 @@#ifndef QEMU_IMG void bdrv_info (void ); +void bdrv_info_stats (void );#endif void bdrv_init (void );
Index: block_int.h
===================================================================
RCS file: /sources/qemu/qemu/block_int.h,v
retrieving revision 1.14
block_int.h +6 -0
@@ -114,6 +114,12 @@void *sync_aiocb; +/* I/O stats (display with "info blockstats"). */ +uint64_t rd_bytes; +uint64_t wr_bytes; +uint64_t rd_ops; +uint64_t wr_ops; +/* NOTE: the following infos are only hints for real hardware drivers. They are not used by the block driver */ int cyls, heads, secs, translation;
Index: monitor.c
===================================================================
RCS file: /sources/qemu/qemu/monitor.c,v
retrieving revision 1.87
monitor.c +7 -0
@@ -260,6 +260,11 @@bdrv_info (); } +static void do_info_blockstats (void ) +{ +bdrv_info_stats (); +} +/* get the current CPU defined by the user */ static int mon_set_cpu (int cpu_index) {
@@ -1332,6 +1337,8 @@ "", "show the network state" }, {"block" ,"" , do_info_block, "", "show the block devices" }, + { "blockstats", "", do_info_blockstats, + "", "show block device statistics" }, { "registers", "", do_info_registers, "", "show the cpu registers" }, { "cpus", "", do_info_cpus,