[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] qemu-nbd: add statistics
From: |
Laurent Vivier |
Subject: |
[Qemu-devel] [PATCH] qemu-nbd: add statistics |
Date: |
Tue, 5 Oct 2010 21:15:51 +0200 |
During qemu-nbd run, I/O statistics can be now displayed using
the option '-a N' where N is the number of seconds between each
collect.
The statistics diplayed are : I/O per second, kilobytes read per second,
kilobytes written per second, and the maximum values for each of them.
Example:
...
0 io/s, 0 R kB/s 0 W kB/s (29 io/s, 59 R kB/s, 0 W kB/s)
123 io/s, 247 R kB/s 0 W kB/s (123 io/s, 247 R kB/s, 0 W kB/s)
145 io/s, 290 R kB/s 0 W kB/s (145 io/s, 290 R kB/s, 0 W kB/s)
383 io/s, 767 R kB/s 0 W kB/s (383 io/s, 767 R kB/s, 0 W kB/s)
273 io/s, 547 R kB/s 0 W kB/s (383 io/s, 767 R kB/s, 0 W kB/s)
2221 io/s, 4443 R kB/s 0 W kB/s (2221 io/s, 4443 R kB/s, 0 W kB/s)
0 io/s, 0 R kB/s 0 W kB/s (2221 io/s, 4443 R kB/s, 0 W kB/s)
0 io/s, 0 R kB/s 0 W kB/s (2221 io/s, 4443 R kB/s, 0 W kB/s)
...
Signed-off-by: Laurent Vivier <address@hidden>
---
nbd.c | 10 ++++++++
nbd.h | 4 +++
qemu-nbd.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/nbd.c b/nbd.c
index 4bf2eb7..730c514 100644
--- a/nbd.c
+++ b/nbd.c
@@ -65,6 +65,12 @@
#define NBD_OPT_EXPORT_NAME (1 << 0)
+/* for I/O statistics */
+
+uint64_t nbd_stats_io = 0;
+uint64_t nbd_stats_read = 0;
+uint64_t nbd_stats_written = 0;
+
/* That's all folks */
#define read_sync(fd, buffer, size) nbd_wr_sync(fd, buffer, size, true)
@@ -687,6 +693,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
uint64_t dev_offset,
switch (request.type) {
case NBD_CMD_READ:
TRACE("Request type is READ");
+ nbd_stats_io++;
+ nbd_stats_read += request.len;
if (bdrv_read(bs, (request.from + dev_offset) / 512,
data + NBD_REPLY_SIZE,
@@ -721,6 +729,8 @@ int nbd_trip(BlockDriverState *bs, int csock, off_t size,
uint64_t dev_offset,
break;
case NBD_CMD_WRITE:
TRACE("Request type is WRITE");
+ nbd_stats_io++;
+ nbd_stats_written += request.len;
TRACE("Reading %u byte(s)", request.len);
diff --git a/nbd.h b/nbd.h
index fc3a594..2d9457b 100644
--- a/nbd.h
+++ b/nbd.h
@@ -44,6 +44,10 @@ enum {
#define NBD_DEFAULT_PORT 10809
+extern uint64_t nbd_stats_io;
+extern uint64_t nbd_stats_read;
+extern uint64_t nbd_stats_written;
+
size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
int tcp_socket_outgoing(const char *address, uint16_t port);
int tcp_socket_incoming(const char *address, uint16_t port);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 99f1d22..7626c37 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -37,6 +37,7 @@
#define NBD_BUFFER_SIZE (1024*1024)
static int verbose;
+static int delay = 0;
static void usage(const char *name)
{
@@ -44,6 +45,7 @@ static void usage(const char *name)
"Usage: %s [OPTIONS] FILE\n"
"QEMU Disk Network Block Device Server\n"
"\n"
+" -a, --stats=N display statistics every N seconds\n"
" -p, --port=PORT port to listen on (default `%d')\n"
" -o, --offset=OFFSET offset into the image\n"
" -b, --bind=IFACE interface to bind to (default `0.0.0.0')\n"
@@ -180,6 +182,49 @@ static void show_parts(const char *device)
}
}
+static void nbd_stats(void)
+{
+ static struct timespec prev;
+ static int first = 1;
+ static uint64_t max_read = 0, max_written = 0, max_io = 0;
+ struct timespec current;
+ long seconds;
+ uint64_t current_read = 0, current_written = 0, current_io = 0;
+
+ clock_gettime(CLOCK_MONOTONIC, ¤t);
+ if (first) {
+ first = 0;
+ prev = current;
+ return;
+ }
+
+ seconds = (current.tv_sec - prev.tv_sec) * 1000 +
+ (current.tv_nsec - prev.tv_nsec) / 1000000;
+
+ if (seconds < delay * 1000)
+ return;
+
+ current_io = nbd_stats_io * 1000 / seconds;
+ if (current_io > max_io)
+ max_io = current_io;
+ current_read = nbd_stats_read * 1000 / seconds / 1024;
+ if (current_read > max_read)
+ max_read = current_read;
+ current_written = nbd_stats_written * 1000 / seconds / 1024;
+ if (current_written > max_written)
+ max_written = current_written;
+
+ printf("%"PRIu64" io/s, %"PRIu64" R kB/s %"PRIu64" W kB/s "
+ "(%"PRIu64" io/s, %"PRIu64" R kB/s, %"PRIu64" W kB/s)\n",
+ current_io, current_read, current_written,
+ max_io, max_read, max_written);
+
+ nbd_stats_io = 0;
+ nbd_stats_read = 0;
+ nbd_stats_written = 0;
+ prev = current;
+}
+
int main(int argc, char **argv)
{
BlockDriverState *bs;
@@ -195,11 +240,12 @@ int main(int argc, char **argv)
char *device = NULL;
char *socket = NULL;
char sockpath[128];
- const char *sopt = "hVb:o:p:rsnP:c:dvk:e:t";
+ const char *sopt = "hVb:o:a:p:rsnP:c:dvk:e:t";
struct option lopt[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "bind", 1, NULL, 'b' },
+ { "stats", 1, NULL, 'a' },
{ "port", 1, NULL, 'p' },
{ "socket", 1, NULL, 'k' },
{ "offset", 1, NULL, 'o' },
@@ -243,6 +289,15 @@ int main(int argc, char **argv)
case 'b':
bindto = optarg;
break;
+ case 'a':
+ delay = strtol(optarg, &end, 0);
+ if (*end) {
+ errx(EXIT_FAILURE, "Invalid statistics delay `%s'", optarg);
+ }
+ if (delay < 0) {
+ errx(EXIT_FAILURE, "Statisctics delay must be positive `%s'",
optarg);
+ }
+ break;
case 'p':
li = strtol(optarg, &end, 0);
if (*end) {
@@ -456,7 +511,16 @@ int main(int argc, char **argv)
for (i = 0; i < nb_fds; i++)
FD_SET(sharing_fds[i], &fds);
- ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
+ if (delay) {
+ struct timeval timeout;
+
+ nbd_stats();
+ timeout.tv_sec = delay;
+ timeout.tv_usec = 0;
+ ret = select(max_fd + 1, &fds, NULL, NULL, &timeout);
+ } else {
+ ret = select(max_fd + 1, &fds, NULL, NULL, NULL);
+ }
if (ret == -1)
break;
--
1.7.0.4
- [Qemu-devel] [PATCH] qemu-nbd: add statistics,
Laurent Vivier <=