[Libguestfs] [nbdkit PATCH v2 4/5] log: Add .list_exports support

Eric Blake eblake at redhat.com
Thu Aug 6 02:25:21 UTC 2020


Log the list of exports queried by the client, or any attempt by
nbdkit to resolve the canonical name of the default export.

The documentation example was created with libnbd.git (note that
libnbd 1.4 may change from the experimental API shown here...):

$ path/to/libnbd/run ./nbdkit --filter=log memory $((0x400)) \
  logfile=/dev/stderr --run 'nbdsh -c "h.set_list_exports(True)" \
    -c "h.connect_uri(\"$uri\")" -c "h.pread(512,0)"'

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 filters/log/nbdkit-log-filter.pod | 18 ++++++-----
 filters/log/log.c                 | 50 +++++++++++++++++++++++++++++--
 2 files changed, 58 insertions(+), 10 deletions(-)

diff --git a/filters/log/nbdkit-log-filter.pod b/filters/log/nbdkit-log-filter.pod
index 15d61cad..5f690457 100644
--- a/filters/log/nbdkit-log-filter.pod
+++ b/filters/log/nbdkit-log-filter.pod
@@ -62,20 +62,22 @@ the impact of the caching.

 This filter writes to the file specified by the C<logfile=FILE>
 parameter.  All lines include a timestamp, a connection counter, then
-details about the command.  The following actions are logged: Connect,
-Read, Write, Zero, Trim, Extents, Cache, Flush, and Disconnect.
+details about the command.  The following actions are logged: ListExports,
+Connect, Read, Write, Zero, Trim, Extents, Cache, Flush, and Disconnect.
 Except for Connect and Disconnect, an event is logged across two lines
 for call and return value, to allow tracking duration and tracing any
 parallel execution, using id for correlation (incremented per action
 on the connection).

-An example logging session of a client that performs a single
-successful read is:
+An example logging session of a client that requests an export list
+before performing a single successful read is:

- 2018-01-27 20:38:22.959984 connection=1 Connect export='' size=0x400 write=1 flush=1 rotational=0 trim=0 zero=1 fua=1 extents=1 cache=0 fast_zero=0
- 2018-01-27 20:38:23.001720 connection=1 Read id=1 offset=0x0 count=0x100 ...
- 2018-01-27 20:38:23.001995 connection=1 ...Read id=1 return=0 (Success)
- 2018-01-27 20:38:23.044259 connection=1 Disconnect transactions=1
+ 2020-08-06 02:07:23.080415 ListExports id=1 readonly=0 default_only=0 ...
+ 2020-08-06 02:07:23.080502 ...ListExports id=1 exports=[""] return=0
+ 2020-08-06 02:07:23.080712 connection=1 Connect export='' size=0x400 write=1 flush=1 rotational=0 trim=1 zero=2 fua=2 extents=1 cache=2 fast_zero=1
+ 2020-08-06 02:07:23.080907 connection=1 Read id=1 offset=0x0 count=0x200 ...
+ 2020-08-06 02:07:23.080927 connection=1 ...Read id=1 return=0 (Success)
+ 2020-08-06 02:07:23.081255 connection=1 Disconnect transactions=1

 =item F<$filterdir/nbdkit-log-filter.so>

diff --git a/filters/log/log.c b/filters/log/log.c
index 2078d0c2..c89f5001 100644
--- a/filters/log/log.c
+++ b/filters/log/log.c
@@ -48,6 +48,7 @@
 #include <nbdkit-filter.h>

 #include "cleanup.h"
+#include "utils.h"

 static uint64_t connections;
 static char *logfilename;
@@ -166,8 +167,11 @@ output (struct handle *h, const char *act, uint64_t id, const char *fmt, ...)
                 0L + tv.tv_usec);
     }
   flockfile (logfile);
-  fprintf (logfile, "%s connection=%" PRIu64 " %s ", timestamp, h->connection,
-           act);
+  if (h)
+    fprintf (logfile, "%s connection=%" PRIu64 " %s ", timestamp,
+             h->connection, act);
+  else
+    fprintf (logfile, "%s %s ", timestamp, act);
   if (id)
     fprintf (logfile, "id=%" PRIu64 " ", id);
   va_start (args, fmt);
@@ -235,6 +239,47 @@ output_return (struct handle *h, const char *act, uint64_t id, int r, int *err)
   output (h, act, id, "return=%d (%s)", r, s);
 }

+/* List exports. */
+static int
+log_list_exports (nbdkit_next_list_exports *next, void *nxdata,
+                  int readonly, int default_only,
+                  struct nbdkit_exports *exports)
+{
+  static uint64_t id;
+  int r;
+  int err;
+
+  output (NULL, "ListExports", ++id, "readonly=%d default_only=%d ...",
+          readonly, default_only);
+  r = next (nxdata, readonly, default_only, exports);
+  if (r == -1) {
+    err = errno;
+    output_return (NULL, "...ListExports", id, r, &err);
+  }
+  else {
+    FILE *fp;
+    CLEANUP_FREE char *exports_str = NULL;
+    size_t i, n, len = 0;
+
+    fp = open_memstream (&exports_str, &len);
+    if (fp != NULL) {
+      n = nbdkit_exports_count (exports);
+      for (i = 0; i < n; ++i) {
+        struct nbdkit_export e = nbdkit_get_export (exports, i);
+        if (i > 0)
+          fprintf (fp, ", ");
+        shell_quote (e.name, fp);
+      }
+
+      fclose (fp);
+    }
+
+    output (NULL, "...ListExports", id, "exports=[%s] return=0",
+            exports_str ? exports_str : "(null)");
+  }
+  return r;
+}
+
 /* Open a connection. */
 static void *
 log_open (nbdkit_next_open *next, void *nxdata,
@@ -476,6 +521,7 @@ static struct nbdkit_filter filter = {
   .config_help       = log_config_help,
   .unload            = log_unload,
   .get_ready         = log_get_ready,
+  .list_exports      = log_list_exports,
   .open              = log_open,
   .close             = log_close,
   .prepare           = log_prepare,
-- 
2.28.0




More information about the Libguestfs mailing list