[Libguestfs] [libnbd PATCH v2 08/13] examples: Update list-exports to demonstrate nbd_opt_go

Eric Blake
Fri, 14 Aug 2020 22:00:27 -0000

There's more improvements coming, but this is enough to prove that
we've got a working option mode.  We can now select an export name
from the same connection requesting the list.
---
 examples/list-exports.c | 64 ++++++++++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 20 deletions(-)

diff --git a/examples/list-exports.c b/examples/list-exports.c
index 643e611..daea2ab 100644
--- a/examples/list-exports.c
+++ b/examples/list-exports.c
@@ -4,9 +4,27 @@
  *   $ qemu-nbd -x "hello" -t -k /tmp/sock disk.img
  *   $ ./run examples/list-exports /tmp/sock
  *   [0] hello
- *   Which export to connect to? 0
+ *   Which export to connect to (-1 to quit)? 0
  *   Connecting to hello ...
  *   /tmp/sock: hello: size = 2048 bytes
+ *
+ * To test this with nbdkit (requires 1.22):
+ *   $ nbdkit -U /tmp/sock sh - <<\EOF
+ *   case $1 in
+ *     list_exports) echo NAMES; echo foo; echo foobar ;;
+ *     open) echo "$3" ;;
+ *     get_size) echo "$2" | wc -c ;;
+ *     pread) echo "$2" | dd skip=$4 count=$3 \
+ *       iflag=skip_bytes,count_bytes ;;
+ *     *) exit 2 ;;
+ *   esac
+ *   EOF
+ *   $ ./run examples/list-exports /tmp/sock
+ *   [0] foo
+ *   [1] foobar
+ *   Which export to connect to (-1 to quit)? 1
+ *   Connecting to foobar ...
+ *   /tmp/sock: foobar: size = 7 bytes
  */

 #include <stdio.h>
@@ -20,7 +38,7 @@
 int
 main (int argc, char *argv[])
 {
-  struct nbd_handle *nbd, *nbd2;
+  struct nbd_handle *nbd;
   int r, i;
   char *name, *desc;
   int64_t size;
@@ -30,14 +48,15 @@ main (int argc, char *argv[])
     exit (EXIT_FAILURE);
   }

-  /* Create the libnbd handle for querying exports. */
+  /* Create the libnbd handle. */
   nbd = nbd_create ();
   if (nbd == NULL) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }

-  /* Set the list exports mode in the handle. */
+  /* Set opt mode and request list exports. */
+  nbd_set_opt_mode (nbd, true);
   nbd_set_list_exports (nbd, true);

   /* Connect to the NBD server over a
@@ -52,8 +71,8 @@ main (int argc, char *argv[])
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }
-
-  if (nbd_get_nr_list_exports (nbd) == 0) {
+  if (!nbd_aio_is_negotiating (nbd) ||
+      nbd_get_nr_list_exports (nbd) == 0) {
     fprintf (stderr, "Server does not support "
              "listing exports.\n");
     exit (EXIT_FAILURE);
@@ -73,29 +92,34 @@ main (int argc, char *argv[])
   }
   printf ("Which export to connect to? ");
   if (scanf ("%d", &i) != 1) exit (EXIT_FAILURE);
+  if (i == -1) {
+    if (nbd_opt_abort (nbd) == -1) {
+      fprintf (stderr, "%s\n", nbd_get_error ());
+      exit (EXIT_FAILURE);
+    }
+    nbd_close (nbd);
+    exit (EXIT_SUCCESS);
+  }
   name = nbd_get_list_export_name (nbd, i);
+  if (name == NULL) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
   printf ("Connecting to %s ...\n", name);
-  nbd_close (nbd);

-  /* Connect again to the chosen export. */
-  nbd2 = nbd_create ();
-  if (nbd2 == NULL) {
+  /* Resume connecting to the chosen export. */
+  if (nbd_set_export_name (nbd, name) == -1 ||
+      nbd_opt_go (nbd) == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }
-
-  if (nbd_set_export_name (nbd2, name) == -1) {
-    fprintf (stderr, "%s\n", nbd_get_error ());
-    exit (EXIT_FAILURE);
-  }
-
-  if (nbd_connect_unix (nbd2, argv[1]) == -1) {
-    fprintf (stderr, "%s\n", nbd_get_error ());
+  if (!nbd_aio_is_ready (nbd)) {
+    fprintf (stderr, "server closed early\n");
     exit (EXIT_FAILURE);
   }

   /* Read the size in bytes and print it. */
-  size = nbd_get_size (nbd2);
+  size = nbd_get_size (nbd);
   if (size == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
@@ -104,7 +128,7 @@ main (int argc, char *argv[])
           argv[1], name, size);

   /* Close the libnbd handle. */
-  nbd_close (nbd2);
+  nbd_close (nbd);

   free (name);

--
2.28.0