[Libguestfs] [PATCH nbdkit v2 3/4] info: Add mode for sending back server time.

Eric Blake eblake at redhat.com
Mon Sep 30 16:48:46 UTC 2019


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μs

Examples 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




More information about the Libguestfs mailing list