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