[Libguestfs] [libnbd PATCH 2/2] info: Use nbd_opt_info for fewer handles during --list

Eric Blake eblake at redhat.com
Wed Aug 19 01:53:18 UTC 2020


We have now resolved some TODO entries, making nbdinfo --list able to
use a single connection except when doing content probing.
---
 info/nbdinfo.pod |  2 ++
 TODO             | 13 -----------
 info/nbdinfo.c   | 56 +++++++++++++++++++++++++++---------------------
 3 files changed, 34 insertions(+), 37 deletions(-)

diff --git a/info/nbdinfo.pod b/info/nbdinfo.pod
index d0d20a9..19305bf 100644
--- a/info/nbdinfo.pod
+++ b/info/nbdinfo.pod
@@ -156,6 +156,8 @@ L<qemu-nbd(8)>.

 Richard W.M. Jones

+Eric Blake
+
 =head1 COPYRIGHT

 Copyright (C) 2020 Red Hat Inc.
diff --git a/TODO b/TODO
index 239e0b0..4a0cd22 100644
--- a/TODO
+++ b/TODO
@@ -9,12 +9,8 @@ Example code integrating with ppoll, pollfd, APR pollset (and others?).

 Example command line utils to copy in/out (like qemu-img convert).

-NBD_OPT_INFO mode (like qemu-nbd -L).
-
 NBD resize extension.

-NBD_INFO_BLOCK_SIZE.
-
 TLS should properly shut down the session (calling gnutls_bye).

 Performance: Chart it over various buffer sizes and threads, as that
@@ -71,12 +67,3 @@ Suggested API improvements:
     maybe nbd_shutdown should wait for the subprocess or there
     should be another API to do this
   - capture error message when nbd_connect_command fails
-
-  list exports
-  - It should be possible to get details from each export without
-    needing to reconnect.  This would make nbdinfo --list much more
-    efficient.  This involves issuing an NBD_OPT_INFO request per
-    export (but only in list mode).  See how qemu-nbd -L is
-    implemented.  The main difficulty is how to express this through
-    the API since we can no longer user nbd_can_* and nbd_is_* to
-    unpack the flags.
diff --git a/info/nbdinfo.c b/info/nbdinfo.c
index bd3615e..cdff958 100644
--- a/info/nbdinfo.c
+++ b/info/nbdinfo.c
@@ -209,11 +209,12 @@ main (int argc, char *argv[])
       fprintf (stderr, "%s\n", nbd_get_error ());
       exit (EXIT_FAILURE);
     }
-    /* Disconnect from the server to move the handle into a closed
-     * state, in case the server serializes further connections.
-     * But we can ignore errors in this case.
-     */
-    nbd_opt_abort (nbd);
+    if (probe_content)
+      /* Disconnect from the server to move the handle into a closed
+       * state, in case the server serializes further connections.
+       * But we can ignore errors in this case.
+       */
+      nbd_opt_abort (nbd);
   }

   if (size_only) {
@@ -456,9 +457,6 @@ list_one_export (struct nbd_handle *nbd, const char *desc,
   free (export_name);
 }

-/* XXX Inefficient and hacky.  See TODO for a suggestion on how to
- * improve this.
- */
 static void
 list_all_exports (struct nbd_handle *nbd1, const char *uri)
 {
@@ -468,31 +466,41 @@ list_all_exports (struct nbd_handle *nbd1, const char *uri)
     printf ("\t\"exports\": []\n");

   for (i = 0; i < export_list.len; ++i) {
-    const char *name;
+    const char *name = export_list.names[i];
     struct nbd_handle *nbd2;

-    /* Connect to the original URI, but using opt mode to alter the export. */
-    name = export_list.names[i];
-    nbd2 = nbd_create ();
-    if (nbd2 == NULL) {
-      fprintf (stderr, "%s\n", nbd_get_error ());
-      exit (EXIT_FAILURE);
-    }
-    nbd_set_uri_allow_local_file (nbd2, true); /* Allow ?tls-psk-file. */
-    nbd_set_opt_mode (nbd2, true);
+    if (probe_content) {
+      /* Connect to the original URI, but using opt mode to alter the export. */
+      nbd2 = nbd_create ();
+      if (nbd2 == NULL) {
+        fprintf (stderr, "%s\n", nbd_get_error ());
+        exit (EXIT_FAILURE);
+      }
+      nbd_set_uri_allow_local_file (nbd2, true); /* Allow ?tls-psk-file. */
+      nbd_set_opt_mode (nbd2, true);

-    if (nbd_connect_uri (nbd2, uri) == -1 ||
-        nbd_set_export_name (nbd2, name) == -1 ||
-        nbd_opt_go (nbd2) == -1) {
-      fprintf (stderr, "%s\n", nbd_get_error ());
-      exit (EXIT_FAILURE);
+      if (nbd_connect_uri (nbd2, uri) == -1 ||
+          nbd_set_export_name (nbd2, name) == -1 ||
+          nbd_opt_go (nbd2) == -1) {
+        fprintf (stderr, "%s\n", nbd_get_error ());
+        exit (EXIT_FAILURE);
+      }
+    }
+    else { /* ! probe_content */
+      if (nbd_set_export_name (nbd1, name) == -1 ||
+          nbd_opt_info (nbd1) == -1) {
+        fprintf (stderr, "%s\n", nbd_get_error ());
+        exit (EXIT_FAILURE);
+      }
+      nbd2 = nbd1;
     }

     /* List the metadata of this export. */
     list_one_export (nbd2, export_list.descs[i], i == 0,
                      i + 1 == export_list.len);

-    nbd_close (nbd2);
+    if (probe_content)
+      nbd_close (nbd2);
   }
 }

-- 
2.28.0




More information about the Libguestfs mailing list