Richard W.M. Jones
2019-Sep-28 20:02 UTC
[Libguestfs] [PATCH nbdkit v2 0/4] info: Add mode for sending back server time.
v1 was: https://www.redhat.com/archives/libguestfs/2019-September/thread.html#00361 v2: - Adds a patch to rename the reflection plugin to the info plugin. - Adds tests. Rich.
Richard W.M. Jones
2019-Sep-28 20:02 UTC
[Libguestfs] [PATCH nbdkit v2 1/4] common/include: Add function for subtracting struct timeval.
--- common/include/test-tvdiff.c | 75 +++++++++++++++++++++++++++++------- common/include/tvdiff.h | 13 ++++++- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/common/include/test-tvdiff.c b/common/include/test-tvdiff.c index 9cbcfc0..abefb2e 100644 --- a/common/include/test-tvdiff.c +++ b/common/include/test-tvdiff.c @@ -36,7 +36,6 @@ #include <stdlib.h> #include <stdint.h> #include <inttypes.h> -#include <assert.h> #include <sys/time.h> #include "tvdiff.h" @@ -45,37 +44,87 @@ * implementation. */ +#define TEST_TVDIFF(tv1, tv2, expected) \ + do { \ + int64_t actual = tvdiff_usec (&(tv1), &(tv2)); \ + \ + if (actual != (expected)) { \ + fprintf (stderr, \ + "%s: unexpected result %" PRIi64 ", expecting %" PRIi64 "\n", \ + argv[0], actual, (int64_t) (expected)); \ + errors++; \ + } \ + } while (0) + +#define TEST_SUBTRACT(tv1, tv2, exp_sec, exp_usec) \ + do { \ + struct timeval z; \ + \ + subtract_timeval (&tv1, &tv2, &z); \ + if (z.tv_sec != (exp_sec) || z.tv_usec != (exp_usec)) { \ + fprintf (stderr, \ + "%s: unexpected (%ld, %d), expecting (%ld, %d)\n", \ + argv[0], \ + (long) z.tv_sec, (int) z.tv_usec, \ + (long) (exp_sec), (int) (exp_usec)); \ + errors++; \ + } \ + } while (0) + int -main (void) +main (int argc, char *argv[]) { struct timeval tv1, tv2; + unsigned errors = 0; tv1.tv_sec = 1000; tv1.tv_usec = 1; - assert (tvdiff_usec (&tv1, &tv1) == 0); + TEST_TVDIFF (tv1, tv1, 0); + TEST_SUBTRACT (tv1, tv1, 0, 0); + tv2.tv_sec = 1000; tv2.tv_usec = 2; - assert (tvdiff_usec (&tv1, &tv2) == 1); - assert (tvdiff_usec (&tv2, &tv1) == -1); + TEST_TVDIFF (tv1, tv2, 1); + TEST_SUBTRACT (tv1, tv2, 0, 1); + TEST_TVDIFF (tv2, tv1, -1); + TEST_SUBTRACT (tv2, tv1, 0, -1); + tv2.tv_sec = 1000; tv2.tv_usec = 3; - assert (tvdiff_usec (&tv1, &tv2) == 2); - assert (tvdiff_usec (&tv2, &tv1) == -2); + TEST_TVDIFF (tv1, tv2, 2); + TEST_SUBTRACT (tv1, tv2, 0, 2); + TEST_TVDIFF (tv2, tv1, -2); + TEST_SUBTRACT (tv2, tv1, 0, -2); + tv2.tv_sec = 1001; tv2.tv_usec = 0; - assert (tvdiff_usec (&tv1, &tv2) == 999999); - assert (tvdiff_usec (&tv2, &tv1) == -999999); + TEST_TVDIFF (tv1, tv2, 999999); + TEST_SUBTRACT (tv1, tv2, 0, 999999); + TEST_TVDIFF (tv2, tv1, -999999); + TEST_SUBTRACT (tv2, tv1, 0, -999999); tv1.tv_sec = 1000; tv1.tv_usec = 999999; tv2.tv_sec = 1001; tv2.tv_usec = 1; - assert (tvdiff_usec (&tv1, &tv2) == 2); - assert (tvdiff_usec (&tv2, &tv1) == -2); + TEST_TVDIFF (tv1, tv2, 2); + TEST_SUBTRACT (tv1, tv2, 0, 2); + TEST_TVDIFF (tv2, tv1, -2); + TEST_SUBTRACT (tv2, tv1, 0, -2); + + tv1.tv_sec = 1000; + tv1.tv_usec = 1; + tv2.tv_sec = 1001; + tv2.tv_usec = 2; + TEST_TVDIFF (tv1, tv2, 1000001); + TEST_SUBTRACT (tv1, tv2, 1, 1); + TEST_TVDIFF (tv2, tv1, -1000001); + TEST_SUBTRACT (tv2, tv1, -1, -1); /* Test that an arbitrary tv is equal to itself. */ gettimeofday (&tv1, NULL); - assert (tvdiff_usec (&tv1, &tv1) == 0); + TEST_TVDIFF (tv1, tv1, 0); + TEST_SUBTRACT (tv1, tv1, 0, 0); - exit (EXIT_SUCCESS); + exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/common/include/tvdiff.h b/common/include/tvdiff.h index db86b66..cec8345 100644 --- a/common/include/tvdiff.h +++ b/common/include/tvdiff.h @@ -40,7 +40,7 @@ #include <sys/time.h> /* Return the number of µs (microseconds) in y - x. */ -static int64_t +static inline int64_t tvdiff_usec (const struct timeval *x, const struct timeval *y) { int64_t usec; @@ -50,4 +50,15 @@ tvdiff_usec (const struct timeval *x, const struct timeval *y) return usec; } +/* Return timeval difference as another struct timeval. z = y - x. */ +static inline void +subtract_timeval (const struct timeval *x, const struct timeval *y, + struct timeval *z) +{ + int64_t usec = tvdiff_usec (x, y); + + z->tv_sec = usec / 1000000; + z->tv_usec = usec % 1000000; +} + #endif /* NBDKIT_TVDIFF_H */ -- 2.23.0
Richard W.M. Jones
2019-Sep-28 20:02 UTC
[Libguestfs] [PATCH nbdkit v2 2/4] Rename nbdkit-reflection-plugin to nbdkit-info-plugin.
See commit 2a29634aa0589037b5625032097a3a2f7b1d5c7d and https://www.redhat.com/archives/libguestfs/2019-September/msg00366.html --- configure.ac | 4 +- plugins/data/nbdkit-data-plugin.pod | 2 +- plugins/{reflection => info}/Makefile.am | 20 ++++----- .../{reflection/reflection.c => info/info.c} | 42 +++++++++---------- .../nbdkit-info-plugin.pod} | 38 ++++++++--------- plugins/memory/nbdkit-memory-plugin.pod | 2 +- tests/Makefile.am | 20 ++++----- ...ection-address.sh => test-info-address.sh} | 8 ++-- ...flection-base64.sh => test-info-base64.sh} | 10 ++--- ...est-reflection-raw.sh => test-info-raw.sh} | 6 +-- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/configure.ac b/configure.ac index 8e38b2d..a6387d5 100644 --- a/configure.ac +++ b/configure.ac @@ -837,6 +837,7 @@ non_lang_plugins="\ full \ guestfs \ gzip \ + info \ iso \ libvirt \ linuxdisk \ @@ -846,7 +847,6 @@ non_lang_plugins="\ partitioning \ pattern \ random \ - reflection \ split \ ssh \ streaming \ @@ -913,6 +913,7 @@ AC_CONFIG_FILES([Makefile plugins/full/Makefile plugins/guestfs/Makefile plugins/gzip/Makefile + plugins/info/Makefile plugins/iso/Makefile plugins/libvirt/Makefile plugins/linuxdisk/Makefile @@ -926,7 +927,6 @@ AC_CONFIG_FILES([Makefile plugins/perl/Makefile plugins/python/Makefile plugins/random/Makefile - plugins/reflection/Makefile plugins/ruby/Makefile plugins/rust/Cargo.toml plugins/rust/Makefile diff --git a/plugins/data/nbdkit-data-plugin.pod b/plugins/data/nbdkit-data-plugin.pod index 6686c2d..a5ee299 100644 --- a/plugins/data/nbdkit-data-plugin.pod +++ b/plugins/data/nbdkit-data-plugin.pod @@ -247,12 +247,12 @@ Use C<nbdkit --dump-config> to find the location of C<$plugindir>. L<nbdkit(1)>, L<nbdkit-captive(1)>, L<nbdkit-plugin(3)>, +L<nbdkit-info-plugin(1)>, L<nbdkit-memory-plugin(1)>, L<nbdkit-null-plugin(1)>, L<nbdkit-partitioning-plugin(1)>, L<nbdkit-pattern-plugin(1)>, L<nbdkit-random-plugin(1)>, -L<nbdkit-reflection-plugin(1)>, L<nbdkit-zero-plugin(1)>, L<https://github.com/libguestfs/nbdkit/blob/master/plugins/data/disk2data.pl>, L<https://en.wikipedia.org/wiki/Base64>. diff --git a/plugins/reflection/Makefile.am b/plugins/info/Makefile.am similarity index 81% rename from plugins/reflection/Makefile.am rename to plugins/info/Makefile.am index 40aa786..675533a 100644 --- a/plugins/reflection/Makefile.am +++ b/plugins/info/Makefile.am @@ -31,32 +31,32 @@ include $(top_srcdir)/common-rules.mk -EXTRA_DIST = nbdkit-reflection-plugin.pod +EXTRA_DIST = nbdkit-info-plugin.pod -plugin_LTLIBRARIES = nbdkit-reflection-plugin.la +plugin_LTLIBRARIES = nbdkit-info-plugin.la -nbdkit_reflection_plugin_la_SOURCES = \ - reflection.c \ +nbdkit_info_plugin_la_SOURCES = \ + info.c \ $(top_srcdir)/include/nbdkit-plugin.h \ $(NULL) -nbdkit_reflection_plugin_la_CPPFLAGS = \ +nbdkit_info_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) -nbdkit_reflection_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) -nbdkit_reflection_plugin_la_LDFLAGS = \ +nbdkit_info_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_info_plugin_la_LDFLAGS = \ -module -avoid-version -shared \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ $(NULL) -nbdkit_reflection_plugin_la_LIBADD = \ +nbdkit_info_plugin_la_LIBADD = \ $(NULL) if HAVE_POD -man_MANS = nbdkit-reflection-plugin.1 +man_MANS = nbdkit-info-plugin.1 CLEANFILES += $(man_MANS) -nbdkit-reflection-plugin.1: nbdkit-reflection-plugin.pod +nbdkit-info-plugin.1: nbdkit-info-plugin.pod $(PODWRAPPER) --section=1 --man $@ \ --html $(top_builddir)/html/$@.html \ $< diff --git a/plugins/reflection/reflection.c b/plugins/info/info.c similarity index 91% rename from plugins/reflection/reflection.c rename to plugins/info/info.c index 6fd1962..4807287 100644 --- a/plugins/reflection/reflection.c +++ b/plugins/info/info.c @@ -57,7 +57,7 @@ enum mode { static enum mode mode = MODE_EXPORTNAME; static int -reflection_config (const char *key, const char *value) +info_config (const char *key, const char *value) { if (strcmp (key, "mode") == 0) { if (strcasecmp (value, "exportname") == 0 || @@ -89,15 +89,15 @@ reflection_config (const char *key, const char *value) return 0; } -#define reflection_config_help \ +#define info_config_help \ "mode=exportname|base64exportname|address Plugin mode (default exportname)." /* Provide a way to detect if the base64 feature is supported. */ static void -reflection_dump_plugin (void) +info_dump_plugin (void) { #ifdef HAVE_BASE64 - printf ("reflection_base64=yes\n"); + printf ("info_base64=yes\n"); #endif } @@ -228,7 +228,7 @@ handle_address (struct sockaddr *sa, socklen_t addrlen, * - Leaking host information (eg. paths). */ static void * -reflection_open (int readonly) +info_open (int readonly) { const char *export_name; size_t export_name_len; @@ -286,7 +286,7 @@ reflection_open (int readonly) /* Close the per-connection handle. */ static void -reflection_close (void *handle) +info_close (void *handle) { struct handle *h = handle; @@ -298,7 +298,7 @@ reflection_close (void *handle) /* Get the disk size. */ static int64_t -reflection_get_size (void *handle) +info_get_size (void *handle) { struct handle *h = handle; @@ -306,7 +306,7 @@ reflection_get_size (void *handle) } static int -reflection_can_multi_conn (void *handle) +info_can_multi_conn (void *handle) { switch (mode) { /* Safe for exportname modes since clients should only request @@ -329,7 +329,7 @@ reflection_can_multi_conn (void *handle) /* Cache. */ static int -reflection_can_cache (void *handle) +info_can_cache (void *handle) { /* Everything is already in memory, returning this without * implementing .cache lets nbdkit do the correct no-op. @@ -339,8 +339,8 @@ reflection_can_cache (void *handle) /* Read data. */ static int -reflection_pread (void *handle, void *buf, uint32_t count, uint64_t offset, - uint32_t flags) +info_pread (void *handle, void *buf, uint32_t count, uint64_t offset, + uint32_t flags) { struct handle *h = handle; @@ -349,18 +349,18 @@ reflection_pread (void *handle, void *buf, uint32_t count, uint64_t offset, } static struct nbdkit_plugin plugin = { - .name = "reflection", + .name = "info", .version = PACKAGE_VERSION, - .config = reflection_config, - .config_help = reflection_config_help, - .dump_plugin = reflection_dump_plugin, + .config = info_config, + .config_help = info_config_help, + .dump_plugin = info_dump_plugin, .magic_config_key = "mode", - .open = reflection_open, - .close = reflection_close, - .get_size = reflection_get_size, - .can_multi_conn = reflection_can_multi_conn, - .can_cache = reflection_can_cache, - .pread = reflection_pread, + .open = info_open, + .close = info_close, + .get_size = info_get_size, + .can_multi_conn = info_can_multi_conn, + .can_cache = info_can_cache, + .pread = info_pread, /* In this plugin, errno is preserved properly along error return * paths from failed system calls. */ diff --git a/plugins/reflection/nbdkit-reflection-plugin.pod b/plugins/info/nbdkit-info-plugin.pod similarity index 72% rename from plugins/reflection/nbdkit-reflection-plugin.pod rename to plugins/info/nbdkit-info-plugin.pod index f971cef..3edfa73 100644 --- a/plugins/reflection/nbdkit-reflection-plugin.pod +++ b/plugins/info/nbdkit-info-plugin.pod @@ -1,15 +1,15 @@ =head1 NAME -nbdkit-reflection-plugin - reflect client info back to the client +nbdkit-info-plugin - serve client and server information =head1 SYNOPSIS - nbdkit reflection [mode=]exportname|base64exportname|address + nbdkit info [mode=]exportname|base64exportname|address =head1 DESCRIPTION -C<nbdkit-reflection-plugin> is a test plugin which reflects -information sent by the client back to the client. +C<nbdkit-info-plugin> is a test plugin which serves information about +the client and server in a disk image back to the client. In its default mode (C<mode=exportname>) it converts the export name passed from the client into a disk image. C<mode=base64exportname> is @@ -27,11 +27,11 @@ add L<nbdkit-cow-filter(1)> on top. =head1 EXAMPLES -Create a reflection disk. By setting the export name to C<"hello"> +Create a “reflection disk”. By setting the export name to C<"hello"> when we open it, a virtual disk of only 5 bytes containing these characters is created. We then display the contents: - $ nbdkit --exit-with-parent reflection mode=exportname & + $ nbdkit --exit-with-parent info mode=exportname & $ nbdsh -u 'nbd://localhost/hello' -c - <<'EOF' size = h.get_size() print("size = %d" % size) @@ -42,10 +42,10 @@ characters is created. We then display the contents: size = 5 buf = b"hello" -By running a reflection plugin, you can pass whole bootable VMs on the +By running the info plugin, you can pass whole bootable VMs on the qemu command line: - $ nbdkit reflection mode=base64exportname + $ nbdkit info mode=base64exportname $ qemu-system-x86_64 \ -drive 'snapshot=on,file.driver=nbd,file.host=localhost,file.port=10809,file.export tACwA80QtBOzCrABuRwAtgCyAL0ZfM0Q9CoqKiBIZWxsbyBmcm9tIG5iZGtp @@ -62,10 +62,10 @@ qemu command line: AAAAAAAAAAAAAAAAAAAAVao ' -Another use for the reflection plugin is to send back the client's IP +Another use for the info plugin is to send back the client's IP address: - $ nbdkit reflection mode=address + $ nbdkit info mode=address $ nbdsh -u 'nbd://localhost' -c 'print(h.pread(h.get_size(), 0))' which will print something like: @@ -78,28 +78,28 @@ which will print something like: =item [B<mode=>]B<address> -Reflect the client's IP address and client port number as a string in -the usual format. For Unix sockets this sets the disk to the string +Send the client's IP address and client port number as a string in the +usual format. For Unix sockets this sets the disk to the string C<"unix"> to avoid leaking host paths. =item [B<mode=>]B<base64exportname> -Reflect the export name passed by the client, assuming the client -string is base64 encoded. +Send the export name passed by the client, assuming the client string +is base64 encoded. This mode is only supported if nbdkit was compiled with GnuTLS E<ge> 3.6.0. You can find out by checking if: - $ nbdkit reflection --dump-plugin + $ nbdkit info --dump-plugin contains: - reflection_base64=yes + info_base64=yes =item [B<mode=>]B<exportname> -Reflect the raw export name passed by the client. Note the export -name cannot contain ASCII NUL characters. +Send the raw export name passed by the client. Note the export name +cannot contain ASCII NUL characters. This is the default mode. @@ -112,7 +112,7 @@ See L<nbdkit(1)/Magic parameters>. =over 4 -=item F<$plugindir/nbdkit-reflection-plugin.so> +=item F<$plugindir/nbdkit-info-plugin.so> The plugin. diff --git a/plugins/memory/nbdkit-memory-plugin.pod b/plugins/memory/nbdkit-memory-plugin.pod index 94e5da1..31c8649 100644 --- a/plugins/memory/nbdkit-memory-plugin.pod +++ b/plugins/memory/nbdkit-memory-plugin.pod @@ -99,7 +99,7 @@ L<nbdkit-plugin(3)>, L<nbdkit-loop(1)>, L<nbdkit-data-plugin(1)>, L<nbdkit-file-plugin(1)>, -L<nbdkit-reflection-plugin(1)>. +L<nbdkit-info-plugin(1)>. =head1 AUTHORS diff --git a/tests/Makefile.am b/tests/Makefile.am index 7d254be..5a65db7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -73,6 +73,9 @@ EXTRA_DIST = \ test-full.sh \ test-help.sh \ test-help-plugin.sh \ + test-info-address.sh \ + test-info-base64.sh \ + test-info-raw.sh \ test-ip.sh \ test-iso.sh \ test-layers.sh \ @@ -112,9 +115,6 @@ EXTRA_DIST = \ test-rate-dynamic.sh \ test.rb \ test-readahead-copy.sh \ - test-reflection-address.sh \ - test-reflection-base64.sh \ - test-reflection-raw.sh \ test-retry.sh \ test-retry-reopen-fail.sh \ test-shutdown.sh \ @@ -537,6 +537,13 @@ disk.gz: disk endif HAVE_GUESTFISH endif HAVE_ZLIB +# info plugin test. +TESTS += \ + test-info-address.sh \ + test-info-base64.sh \ + test-info-raw.sh \ + $(NULL) + # iso plugin test. if HAVE_ISO if HAVE_GUESTFISH @@ -611,13 +618,6 @@ test_random_CPPFLAGS = -I $(top_srcdir)/common/include test_random_CFLAGS = $(WARNINGS_CFLAGS) $(LIBGUESTFS_CFLAGS) test_random_LDADD = libtest.la $(LIBGUESTFS_LIBS) -# reflection plugin test. -TESTS += \ - test-reflection-address.sh \ - test-reflection-base64.sh \ - test-reflection-raw.sh \ - $(NULL) - # split files plugin test. check_DATA += split1 split2 split3 CLEANFILES += split1 split2 split3 diff --git a/tests/test-reflection-address.sh b/tests/test-info-address.sh similarity index 90% rename from tests/test-reflection-address.sh rename to tests/test-info-address.sh index e4289a7..929dffe 100755 --- a/tests/test-reflection-address.sh +++ b/tests/test-info-address.sh @@ -30,7 +30,7 @@ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# Test the reflection plugin with mode=address. +# Test the info plugin with mode=address. source ./functions.sh set -e @@ -39,13 +39,13 @@ set -x requires nbdsh --version sock=`mktemp -u` -files="reflection-address.out reflection-address.pid $sock" +files="info-address.out info-address.pid $sock" rm -f $files cleanup_fn rm -f $files # Run nbdkit. -start_nbdkit -P reflection-address.pid -U $sock \ - reflection mode=address +start_nbdkit -P info-address.pid -U $sock \ + info mode=address export sock nbdsh -c - <<'EOF' diff --git a/tests/test-reflection-base64.sh b/tests/test-info-base64.sh similarity index 90% rename from tests/test-reflection-base64.sh rename to tests/test-info-base64.sh index 9196deb..542fe90 100755 --- a/tests/test-reflection-base64.sh +++ b/tests/test-info-base64.sh @@ -30,7 +30,7 @@ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# Test the reflection plugin with base64-encoded export name. +# Test the info plugin with base64-encoded export name. source ./functions.sh set -e @@ -39,19 +39,19 @@ set -x requires nbdsh -c 'import base64' # Test if mode=base64exportname is supported in this build. -if ! nbdkit reflection --dump-plugin | grep -sq "reflection_base64=yes"; then +if ! nbdkit info --dump-plugin | grep -sq "info_base64=yes"; then echo "$0: mode=base64exportname is not supported in this build" exit 77 fi sock=`mktemp -u` -files="reflection-base64.out reflection-base64.pid $sock" +files="info-base64.out info-base64.pid $sock" rm -f $files cleanup_fn rm -f $files # Run nbdkit. -start_nbdkit -P reflection-base64.pid -U $sock \ - reflection mode=base64exportname +start_nbdkit -P info-base64.pid -U $sock \ + info mode=base64exportname export e sock for e in "" "test" "/" "//" " " "/ " "?" "テスト" "-n" '\\' $'\n' "%%" \ diff --git a/tests/test-reflection-raw.sh b/tests/test-info-raw.sh similarity index 93% rename from tests/test-reflection-raw.sh rename to tests/test-info-raw.sh index dfbcd29..f937d9f 100755 --- a/tests/test-reflection-raw.sh +++ b/tests/test-info-raw.sh @@ -30,7 +30,7 @@ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# Test the reflection plugin with raw export name. +# Test the info plugin with raw export name. source ./functions.sh set -e @@ -39,12 +39,12 @@ set -x requires nbdsh --version sock=`mktemp -u` -files="reflection-raw.out reflection-raw.pid $sock" +files="info-raw.out info-raw.pid $sock" rm -f $files cleanup_fn rm -f $files # Run nbdkit. -start_nbdkit -P reflection-raw.pid -U $sock reflection +start_nbdkit -P info-raw.pid -U $sock info for e in "" "test" "/" "//" " " "/ " "?" "テスト" "-n" '\\' $'\n' "%%" \ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -- 2.23.0
Richard W.M. Jones
2019-Sep-28 20:02 UTC
[Libguestfs] [PATCH nbdkit v2 3/4] info: Add mode for sending back server time.
Either wallclock time, uptime or time since client connection can be served back to the client in a big endian binary structure. $ nbdkit info time --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' 00000000 00 00 00 00 5d 8f 24 c7 00 04 24 01 └─────┬─────┘ ┌─┘ │ $ date --date="@$(( 0x5d8f24c7 ))" Sat 28 Sep 10:15:51 BST 2019 $ nbdkit info uptime --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' 00000000 00 00 00 00 00 00 00 00 00 00 60 4b └──┬──┘ 0x604b is about 25ms $ nbdkit info conntime --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' 00000000 00 00 00 00 00 00 00 00 00 00 00 e0 └─┬─┘ 0xe0 is about 200μs Suggested by Eric Blake. --- plugins/info/Makefile.am | 1 + plugins/info/info.c | 90 ++++++++++++++++++++++++++++- plugins/info/nbdkit-info-plugin.pod | 41 ++++++++++++- 3 files changed, 128 insertions(+), 4 deletions(-) diff --git a/plugins/info/Makefile.am b/plugins/info/Makefile.am index 675533a..442753b 100644 --- a/plugins/info/Makefile.am +++ b/plugins/info/Makefile.am @@ -42,6 +42,7 @@ nbdkit_info_plugin_la_SOURCES = \ nbdkit_info_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/common/include \ $(NULL) nbdkit_info_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_info_plugin_la_LDFLAGS = \ diff --git a/plugins/info/info.c b/plugins/info/info.c index 4807287..329a368 100644 --- a/plugins/info/info.c +++ b/plugins/info/info.c @@ -35,6 +35,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -48,14 +49,29 @@ #include <nbdkit-plugin.h> +#include "byte-swapping.h" +#include "tvdiff.h" + /* The mode. */ enum mode { MODE_EXPORTNAME, MODE_BASE64EXPORTNAME, MODE_ADDRESS, + MODE_TIME, + MODE_UPTIME, + MODE_CONNTIME, }; static enum mode mode = MODE_EXPORTNAME; +/* Plugin load time. */ +static struct timeval load_t; + +static void +info_load (void) +{ + gettimeofday (&load_t, NULL); +} + static int info_config (const char *key, const char *value) { @@ -73,9 +89,14 @@ info_config (const char *key, const char *value) return -1; #endif } - else if (strcasecmp (value, "address") == 0) { + else if (strcasecmp (value, "address") == 0) mode = MODE_ADDRESS; - } + else if (strcasecmp (value, "time") == 0) + mode = MODE_TIME; + else if (strcasecmp (value, "uptime") == 0) + mode = MODE_UPTIME; + else if (strcasecmp (value, "conntime") == 0) + mode = MODE_CONNTIME; else { nbdkit_error ("unknown mode: '%s'", value); return -1; @@ -90,7 +111,8 @@ info_config (const char *key, const char *value) } #define info_config_help \ - "mode=exportname|base64exportname|address Plugin mode (default exportname)." + "mode=exportname|base64exportname|address|time|uptime|conntime\n" \ + " Plugin mode (default exportname)." /* Provide a way to detect if the base64 feature is supported. */ static void @@ -105,6 +127,7 @@ info_dump_plugin (void) struct handle { void *data; /* Block device data. */ size_t len; /* Length of data in bytes. */ + struct timeval conn_t; /* Time since connection was opened. */ }; static int @@ -279,6 +302,19 @@ info_open (int readonly) } return h; + case MODE_TIME: + case MODE_UPTIME: + case MODE_CONNTIME: + gettimeofday (&h->conn_t, NULL); + h->len = 12; + h->data = malloc (h->len); + if (h->data == NULL) { + nbdkit_error ("malloc: %m"); + free (h); + return NULL; + } + return h; + default: abort (); } @@ -320,6 +356,13 @@ info_can_multi_conn (void *handle) */ case MODE_ADDRESS: return 0; + /* All time modes will read different values at different times, + * so all of them are unsafe for multi-conn. + */ + case MODE_TIME: + case MODE_UPTIME: + case MODE_CONNTIME: + return 0; /* Keep GCC happy. */ default: @@ -337,6 +380,42 @@ info_can_cache (void *handle) return NBDKIT_CACHE_NATIVE; } +static void +update_time (struct handle *h) +{ + struct timeval tv; + int64_t secs; + int32_t usecs; + char *p; + + gettimeofday (&tv, NULL); + + switch (mode) { + case MODE_TIME: + break; + + case MODE_UPTIME: + subtract_timeval (&load_t, &tv, &tv); + break; + + case MODE_CONNTIME: + subtract_timeval (&h->conn_t, &tv, &tv); + break; + + default: + abort (); + } + + /* Pack the result into the output buffer. */ + secs = tv.tv_sec; + usecs = tv.tv_usec; + secs = htobe64 (secs); + usecs = htobe32 (usecs); + p = h->data; + memcpy (&p[0], &secs, 8); + memcpy (&p[8], &usecs, 4); +} + /* Read data. */ static int info_pread (void *handle, void *buf, uint32_t count, uint64_t offset, @@ -344,6 +423,10 @@ info_pread (void *handle, void *buf, uint32_t count, uint64_t offset, { struct handle *h = handle; + /* For the time modes we update the data on every read. */ + if (mode == MODE_TIME || mode == MODE_UPTIME || mode == MODE_CONNTIME) + update_time (h); + memcpy (buf, h->data + offset, count); return 0; } @@ -351,6 +434,7 @@ info_pread (void *handle, void *buf, uint32_t count, uint64_t offset, static struct nbdkit_plugin plugin = { .name = "info", .version = PACKAGE_VERSION, + .load = info_load, .config = info_config, .config_help = info_config_help, .dump_plugin = info_dump_plugin, diff --git a/plugins/info/nbdkit-info-plugin.pod b/plugins/info/nbdkit-info-plugin.pod index 3edfa73..29fc37e 100644 --- a/plugins/info/nbdkit-info-plugin.pod +++ b/plugins/info/nbdkit-info-plugin.pod @@ -4,7 +4,8 @@ nbdkit-info-plugin - serve client and server information =head1 SYNOPSIS - nbdkit info [mode=]exportname|base64exportname|address + nbdkit info [mode=]exportname|base64exportname|address| + time|uptime|conntime =head1 DESCRIPTION @@ -22,6 +23,10 @@ than this. C<mode=address> creates a disk which contains the client's IP address and port number as a string. +C<mode=time>, C<mode=uptime> and C<mode=conntime> report server +wallclock time, nbdkit uptime, or time since the connection was opened +respectively and may be used to measure latency. + The plugin only supports read-only access. To make the disk writable, add L<nbdkit-cow-filter(1)> on top. @@ -103,6 +108,40 @@ cannot contain ASCII NUL characters. This is the default mode. +=item [B<mode=>]B<time> + +Reflect server wallclock time as seconds and microseconds since the +Epoch (see L<gettimeofday(2)>): + + ┌────────┬────────┬────────────┬──────────────────────┐ + │ offset │ length │ format │ field │ + ╞════════╪════════╪════════════╪══════════════════════╡ + │ 0 │ 8 │ 64 bit int │ seconds │ + │ │ │ big endian │ │ + ├────────┼────────┼────────────┼──────────────────────┤ + │ 8 │ 4 │ 32 bit int │ microseconds │ + │ │ │ big endian │ │ + └────────┴────────┴────────────┴──────────────────────┘ + +To be able to read this atomically you must read the whole 12 bytes in +a single request. + +Note that exposing server time may be insecure. It is safer to use +C<mode=uptime> or C<mode=conntime> instead. + +=item [B<mode=>]B<uptime> + +Reflect nbdkit uptime in seconds and microseconds (ie. both fields are +C<0> immediately after nbdkit starts, although a client would never be +able to observe this). The format is exactly the same as for +C<mode=time> above. + +=item [B<mode=>]B<conntime> + +Reflect time since the NBD client connection was opened in seconds and +milliseconds. The format is exactly the same as for C<mode=time> +above. + C<mode=> is a magic config key and may be omitted in most cases. See L<nbdkit(1)/Magic parameters>. -- 2.23.0
Richard W.M. Jones
2019-Sep-28 20:02 UTC
[Libguestfs] [PATCH nbdkit v2 4/4] info: Add tests for time, uptime and conntime modes.
--- tests/Makefile.am | 6 ++++ tests/test-info-conntime.sh | 65 +++++++++++++++++++++++++++++++++++ tests/test-info-time.sh | 68 +++++++++++++++++++++++++++++++++++++ tests/test-info-uptime.sh | 65 +++++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+) diff --git a/tests/Makefile.am b/tests/Makefile.am index 5a65db7..abcce94 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -76,6 +76,9 @@ EXTRA_DIST = \ test-info-address.sh \ test-info-base64.sh \ test-info-raw.sh \ + test-info-time.sh \ + test-info-uptime.sh \ + test-info-conntime.sh \ test-ip.sh \ test-iso.sh \ test-layers.sh \ @@ -542,6 +545,9 @@ TESTS += \ test-info-address.sh \ test-info-base64.sh \ test-info-raw.sh \ + test-info-time.sh \ + test-info-uptime.sh \ + test-info-conntime.sh \ $(NULL) # iso plugin test. diff --git a/tests/test-info-conntime.sh b/tests/test-info-conntime.sh new file mode 100755 index 0000000..046d1a1 --- /dev/null +++ b/tests/test-info-conntime.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright (C) 2018-2019 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# Test the info plugin with mode=conntime. + +source ./functions.sh +set -e +set -x + +requires nbdsh --version + +sock=`mktemp -u` +files="info-conntime.out info-conntime.pid $sock" +rm -f $files +cleanup_fn rm -f $files + +# Run nbdkit. +start_nbdkit -P info-conntime.pid -U $sock info mode=conntime + +export sock +nbdsh -c - <<'EOF' +import os +import time + +h.connect_unix (os.environ["sock"]) + +size = h.get_size () +assert size == 12 + +buf = h.pread (size, 0) +secs = int.from_bytes (buf[0:8], byteorder='big') +usecs = int.from_bytes (buf[8:12], byteorder='big') +print ("%d, %d" % (secs, usecs)) + +assert abs (secs) <= 60 +EOF diff --git a/tests/test-info-time.sh b/tests/test-info-time.sh new file mode 100755 index 0000000..c3e82e8 --- /dev/null +++ b/tests/test-info-time.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright (C) 2018-2019 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# Test the info plugin with mode=time. + +source ./functions.sh +set -e +set -x + +requires nbdsh --version + +sock=`mktemp -u` +files="info-time.out info-time.pid $sock" +rm -f $files +cleanup_fn rm -f $files + +# Run nbdkit. +start_nbdkit -P info-time.pid -U $sock info mode=time + +export sock +nbdsh -c - <<'EOF' +import os +import time + +h.connect_unix (os.environ["sock"]) + +size = h.get_size () +assert size == 12 + +buf = h.pread (size, 0) +secs = int.from_bytes (buf[0:8], byteorder='big') +usecs = int.from_bytes (buf[8:12], byteorder='big') +print ("%d, %d" % (secs, usecs)) + +# Assume it's correct if it's within 60 seconds of +# our time. Obviously it should be much closer. +expected = int (time.time ()) +assert abs (secs - expected) <= 60 +EOF diff --git a/tests/test-info-uptime.sh b/tests/test-info-uptime.sh new file mode 100755 index 0000000..ccae4fc --- /dev/null +++ b/tests/test-info-uptime.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# nbdkit +# Copyright (C) 2018-2019 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# Test the info plugin with mode=uptime. + +source ./functions.sh +set -e +set -x + +requires nbdsh --version + +sock=`mktemp -u` +files="info-uptime.out info-uptime.pid $sock" +rm -f $files +cleanup_fn rm -f $files + +# Run nbdkit. +start_nbdkit -P info-uptime.pid -U $sock info mode=uptime + +export sock +nbdsh -c - <<'EOF' +import os +import time + +h.connect_unix (os.environ["sock"]) + +size = h.get_size () +assert size == 12 + +buf = h.pread (size, 0) +secs = int.from_bytes (buf[0:8], byteorder='big') +usecs = int.from_bytes (buf[8:12], byteorder='big') +print ("%d, %d" % (secs, usecs)) + +assert abs (secs) <= 60 +EOF -- 2.23.0
Richard W.M. Jones
2019-Sep-28 20:13 UTC
Re: [Libguestfs] [PATCH nbdkit v2 4/4] info: Add tests for time, uptime and conntime modes.
On Sat, Sep 28, 2019 at 09:02:44PM +0100, Richard W.M. Jones wrote:> diff --git a/tests/test-info-conntime.sh b/tests/test-info-conntime.sh > new file mode 100755 > index 0000000..046d1a1 > --- /dev/null > +++ b/tests/test-info-conntime.sh...> +sock=`mktemp -u` > +files="info-conntime.out info-conntime.pid $sock"The info-conntime.out file (and the same copy and paste bug applies in all the other added tests) is not actually used by the tests so should be deleted. Updated in my copy. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v
Eric Blake
2019-Sep-30 16:24 UTC
Re: [Libguestfs] [PATCH nbdkit v2 1/4] common/include: Add function for subtracting struct timeval.
On 9/28/19 3:02 PM, Richard W.M. Jones wrote:> --- > common/include/test-tvdiff.c | 75 +++++++++++++++++++++++++++++------- > common/include/tvdiff.h | 13 ++++++- > 2 files changed, 74 insertions(+), 14 deletions(-) >ACK> int > -main (void) > +main (int argc, char *argv[])Not sure this part matters, but doesn't hurt either.> +++ b/common/include/tvdiff.h > @@ -40,7 +40,7 @@ > #include <sys/time.h> > > /* Return the number of µs (microseconds) in y - x. */ > -static int64_t > +static inline int64_t > tvdiff_usec (const struct timeval *x, const struct timeval *y) > { > int64_t usec; > @@ -50,4 +50,15 @@ tvdiff_usec (const struct timeval *x, const struct timeval *y) > return usec; > } > > +/* Return timeval difference as another struct timeval. z = y - x. */ > +static inline void > +subtract_timeval (const struct timeval *x, const struct timeval *y, > + struct timeval *z) > +{ > + int64_t usec = tvdiff_usec (x, y); > + > + z->tv_sec = usec / 1000000; > + z->tv_usec = usec % 1000000; > +} > + > #endif /* NBDKIT_TVDIFF_H */ >-- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2019-Sep-30 16:26 UTC
Re: [Libguestfs] [PATCH nbdkit v2 2/4] Rename nbdkit-reflection-plugin to nbdkit-info-plugin.
On 9/28/19 3:02 PM, Richard W.M. Jones wrote:> See commit 2a29634aa0589037b5625032097a3a2f7b1d5c7d and > https://www.redhat.com/archives/libguestfs/2019-September/msg00366.html > --- > configure.ac | 4 +- > plugins/data/nbdkit-data-plugin.pod | 2 +- > plugins/{reflection => info}/Makefile.am | 20 ++++----- > .../{reflection/reflection.c => info/info.c} | 42 +++++++++---------- > .../nbdkit-info-plugin.pod} | 38 ++++++++--------- > plugins/memory/nbdkit-memory-plugin.pod | 2 +- > tests/Makefile.am | 20 ++++----- > ...ection-address.sh => test-info-address.sh} | 8 ++-- > ...flection-base64.sh => test-info-base64.sh} | 10 ++--- > ...est-reflection-raw.sh => test-info-raw.sh} | 6 +-- > 10 files changed, 76 insertions(+), 76 deletions(-)ACK -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2019-Sep-30 16:48 UTC
Re: [Libguestfs] [PATCH nbdkit v2 3/4] info: Add mode for sending back server time.
On 9/28/19 3:02 PM, Richard W.M. Jones wrote:> Either wallclock time, uptime or time since client connection can be > served back to the client in a big endian binary structure. > > $ nbdkit info time --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' > 00000000 00 00 00 00 5d 8f 24 c7 00 04 24 01 > └─────┬─────┘ > ┌─┘ > │ > $ date --date="@$(( 0x5d8f24c7 ))" > Sat 28 Sep 10:15:51 BST 2019 > > $ nbdkit info uptime --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' > 00000000 00 00 00 00 00 00 00 00 00 00 60 4b > └──┬──┘ > 0x604b is about 25ms > > $ nbdkit info conntime --run 'nbdsh --connect $uri -c "sys.stdout.buffer.write(h.pread(12,0))" | hexdump -C' > 00000000 00 00 00 00 00 00 00 00 00 00 00 e0 > └─┬─┘ > 0xe0 is about 200μsExamples like these should probably also be in the man page.> > Suggested by Eric Blake. > --- > plugins/info/Makefile.am | 1 + > plugins/info/info.c | 90 ++++++++++++++++++++++++++++- > plugins/info/nbdkit-info-plugin.pod | 41 ++++++++++++- > 3 files changed, 128 insertions(+), 4 deletions(-) >> +static void > +info_load (void) > +{ > + gettimeofday (&load_t, NULL); > +} > +gettimeofday() can jump. It is okay to use it when exposing the server's current notion of time (as if it jumps, that accurately reflects that the server changed its own time), but not ideal as the basis for diffs of relative time. clock_gettime() is a better solution for uptime and conntime.> @@ -279,6 +302,19 @@ info_open (int readonly) > } > return h; > > + case MODE_TIME: > + case MODE_UPTIME: > + case MODE_CONNTIME: > + gettimeofday (&h->conn_t, NULL);Of course, while gettimeofday() uses struct timeval (usec), clock_gettime() uses struct timespec (nsec), so you'll have to scale things. Representing usec to the client for all cases is still acceptable to me, though (after all, is sub-usec precision across a network worthwhile?)> +++ b/plugins/info/nbdkit-info-plugin.pod > @@ -4,7 +4,8 @@ nbdkit-info-plugin - serve client and server information > > =head1 SYNOPSIS > > - nbdkit info [mode=]exportname|base64exportname|address > + nbdkit info [mode=]exportname|base64exportname|address| > + time|uptime|conntime > > =head1 DESCRIPTION > > @@ -22,6 +23,10 @@ than this. > C<mode=address> creates a disk which contains the client's IP address > and port number as a string. > > +C<mode=time>, C<mode=uptime> and C<mode=conntime> report server > +wallclock time, nbdkit uptime, or time since the connection was opened > +respectively and may be used to measure latency. > + > The plugin only supports read-only access. To make the disk writable, > add L<nbdkit-cow-filter(1)> on top. > > @@ -103,6 +108,40 @@ cannot contain ASCII NUL characters. > > This is the default mode. > > +=item [B<mode=>]B<time> > + > +Reflect server wallclock time as seconds and microseconds since the > +Epoch (see L<gettimeofday(2)>): > + > + ┌────────┬────────┬────────────┬──────────────────────┐ > + │ offset │ length │ format │ field │ > + ╞════════╪════════╪════════════╪══════════════════════╡ > + │ 0 │ 8 │ 64 bit int │ seconds │ > + │ │ │ big endian │ │ > + ├────────┼────────┼────────────┼──────────────────────┤ > + │ 8 │ 4 │ 32 bit int │ microseconds │ > + │ │ │ big endian │ │ > + └────────┴────────┴────────────┴──────────────────────┘ > + > +To be able to read this atomically you must read the whole 12 bytes in > +a single request. > + > +Note that exposing server time may be insecure. It is safer to use > +C<mode=uptime> or C<mode=conntime> instead.Also, a caveat that time may jump forward (large discontinuity) or backwards (visit the same time twice).> + > +=item [B<mode=>]B<uptime> > + > +Reflect nbdkit uptime in seconds and microseconds (ie. both fields are > +C<0> immediately after nbdkit starts, although a client would never be > +able to observe this). The format is exactly the same as for > +C<mode=time> above.If you switch to clock_gettime() for this, then there are no discontinuities from time jumps.> + > +=item [B<mode=>]B<conntime> > + > +Reflect time since the NBD client connection was opened in seconds and > +milliseconds. The format is exactly the same as for C<mode=time>s/milliseconds/microseconds/> +above. > + > C<mode=> is a magic config key and may be omitted in most cases. > See L<nbdkit(1)/Magic parameters>. > >-- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2019-Sep-30 16:53 UTC
Re: [Libguestfs] [PATCH nbdkit v2 4/4] info: Add tests for time, uptime and conntime modes.
On 9/28/19 3:02 PM, Richard W.M. Jones wrote:> --- > tests/Makefile.am | 6 ++++ > tests/test-info-conntime.sh | 65 +++++++++++++++++++++++++++++++++++ > tests/test-info-time.sh | 68 +++++++++++++++++++++++++++++++++++++ > tests/test-info-uptime.sh | 65 +++++++++++++++++++++++++++++++++++ > 4 files changed, 204 insertions(+) >> +# Test the info plugin with mode=conntime. > + > +source ./functions.sh > +set -e > +set -x > + > +requires nbdsh --version > + > +sock=`mktemp -u` > +files="info-conntime.out info-conntime.pid $sock" > +rm -f $files > +cleanup_fn rm -f $files > + > +# Run nbdkit. > +start_nbdkit -P info-conntime.pid -U $sock info mode=conntime > +For conntime, is it worth testing 2 separate connections: Connection 1: connect, sleep 1, read Connection 2: connect, read where the delta read by connection 2 should be less than the delta read by 1? (longer sleep if needed) Conversely, for uptime, 2 separate connections with the same access pattern should show connection 2 greater than the delta of 1. Otherwise looks good. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Reasonably Related Threads
- [PATCH nbdkit 2/2] reflection: Add mode for reflecting server time.
- [PATCH nbdkit 1/2] common/include: Add function for subtracting struct timeval.
- [PATCH nbdkit v2 0/4] info: Add mode for sending back server time.
- [PATCH nbdkit] common/include: Add locale-safe ascii_strcasecmp and ascii_strncasecmp.
- [PATCH nbdkit v2 2/4] Rename nbdkit-reflection-plugin to nbdkit-info-plugin.