flush is usually called once but it can take significant time, so we
need to include it.
Here is an example run with this change:
$ ./nbdkit --foreground \
--unix /tmp/nbd.sock \
--exportname '' \
--filter stats \
file file=/var/tmp/dst.img \
statsfile=/dev/stderr \
--run 'qemu-img convert -p -n -f raw -O raw -T none /var/tmp/fedora-30.img
nbd:unix:/tmp/nbd.sock'
(100.00/100%)
total: 2299 ops, 2.172 s, 6442450944 bytes, 6.000 GiB, 2829.295 MiB/s
write: 1271 ops, 0.356 s, 1219244032 bytes, 1.136 GiB, 3269.711 MiB/s
zero: 1027 ops, 0.012 s, 5223206912 bytes, 4.864 GiB, 431052.118 MiB/s
extents: 1 ops, 0.000 s, 2147483136 bytes, 2.000 GiB, 107789447.985 MiB/s
flush: 2 ops, 1.156 s
---
filters/stats/stats.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/filters/stats/stats.c b/filters/stats/stats.c
index 2c92c65..1d0f242 100644
--- a/filters/stats/stats.c
+++ b/filters/stats/stats.c
@@ -73,6 +73,7 @@ static stat trim_st = { "trim" };
static stat zero_st = { "zero" };
static stat extents_st = { "extents" };
static stat cache_st = { "cache" };
+static stat flush_st = { "flush" };
static inline double
calc_rate (uint64_t bytes, int64_t usecs)
@@ -83,14 +84,20 @@ calc_rate (uint64_t bytes, int64_t usecs)
static inline void
print_stat (const stat *st)
{
- if (st->ops > 0)
- fprintf (fp, "%s: %" PRIu64 " ops, %.3f s, %" PRIu64 "
bytes, %.3f GiB, %.3f MiB/s\n",
+ if (st->ops > 0) {
+ fprintf (fp, "%s: %" PRIu64 " ops, %.3f s",
st->name,
st->ops,
- st->usecs / USEC,
- st->bytes,
- st->bytes / GiB,
- calc_rate (st->bytes, st->usecs));
+ st->usecs / USEC);
+
+ if (st->bytes > 0)
+ fprintf (fp, ", %" PRIu64 " bytes, %.3f GiB, %.3f MiB/s",
+ st->bytes,
+ st->bytes / GiB,
+ calc_rate (st->bytes, st->usecs));
+
+ fprintf (fp, "\n");
+ }
}
static inline void
@@ -117,6 +124,7 @@ print_stats (int64_t usecs)
print_stat (&zero_st);
print_stat (&extents_st);
print_stat (&cache_st);
+ print_stat (&flush_st);
fflush (fp);
}
@@ -263,6 +271,21 @@ stats_trim (struct nbdkit_next_ops *next_ops, void *nxdata,
return r;
}
+/* Flush. */
+static int
+stats_flush (struct nbdkit_next_ops *next_ops, void *nxdata,
+ void *handle, uint32_t flags,
+ int *err)
+{
+ struct timeval start;
+ int r;
+
+ gettimeofday (&start, NULL);
+ r = next_ops->flush (nxdata, flags, err);
+ if (r == 0) record_stat (&flush_st, 0, &start);
+ return r;
+}
+
/* Zero. */
static int
stats_zero (struct nbdkit_next_ops *next_ops, void *nxdata,
@@ -325,6 +348,7 @@ static struct nbdkit_filter filter = {
.pread = stats_pread,
.pwrite = stats_pwrite,
.trim = stats_trim,
+ .flush = stats_flush,
.zero = stats_zero,
.extents = stats_extents,
.cache = stats_cache,
--
2.21.0