1 /* This example shows how to list NBD exports.
3 * To test this with qemu-nbd:
4 * $ qemu-nbd -x "hello" -t -k /tmp/sock disk.img
5 * $ ./run examples/list-exports /tmp/sock
7 * Which export to connect to (-1 to quit)? 0
8 * Connecting to hello ...
9 * /tmp/sock: hello: size = 2048 bytes
11 * To test this with nbdkit (requires 1.22):
12 * $ nbdkit -U /tmp/sock sh - <<\EOF
14 * list_exports) echo NAMES; echo foo; echo foobar ;;
16 * get_size) echo "$2" | wc -c ;;
17 * pread) echo "$2" | dd bs=1 skip=$4 count=$3 ;;
21 * $ ./run examples/list-exports /tmp/sock
24 * Which export to connect to (-1 to quit)? 1
25 * Connecting to foobar ...
26 * /tmp/sock: foobar: size = 7 bytes
43 /* Callback function for nbd_opt_list */
45 list_one (void *opaque
, const char *name
,
46 const char *description
)
48 struct export_list
*l
= opaque
;
51 printf ("[%d] %s\n", l
->i
, name
);
53 printf (" (%s)\n", description
);
54 names
= realloc (l
->names
,
55 (l
->i
+ 1) * sizeof *names
);
60 names
[l
->i
] = strdup (name
);
71 main (int argc
, char *argv
[])
73 struct nbd_handle
*nbd
;
77 struct export_list list
= { 0 };
80 fprintf (stderr
, "%s socket\n", argv
[0]);
84 /* Create the libnbd handle. */
87 fprintf (stderr
, "%s\n", nbd_get_error ());
92 nbd_set_opt_mode (nbd
, true);
94 /* Connect to the NBD server over a
95 * Unix domain socket. If we did not
96 * end up in option mode, then a
97 * listing is not possible.
99 if (nbd_connect_unix (nbd
, argv
[1]) == -1) {
100 fprintf (stderr
, "%s\n", nbd_get_error ());
103 if (!nbd_aio_is_negotiating (nbd
)) {
104 fprintf (stderr
, "Server does not support "
105 "listing exports.\n");
109 /* Print the export list. */
110 if (nbd_opt_list (nbd
,
111 (nbd_list_callback
) {
112 .callback
= list_one
,
113 .user_data
= &list
, }) == -1) {
114 fprintf (stderr
, "%s\n", nbd_get_error ());
118 /* Display the list of exports. */
119 printf ("Which export to connect to? ");
120 if (scanf ("%d", &i
) != 1) exit (EXIT_FAILURE
);
122 if (nbd_opt_abort (nbd
) == -1) {
123 fprintf (stderr
, "%s\n", nbd_get_error ());
129 if (i
< 0 || i
>= list
.i
) {
130 fprintf (stderr
, "index %d out of range", i
);
133 name
= list
.names
[i
];
134 printf ("Connecting to %s ...\n", name
);
136 /* Resume connecting to the chosen export. */
137 if (nbd_set_export_name (nbd
, name
) == -1 ||
138 nbd_opt_go (nbd
) == -1) {
139 fprintf (stderr
, "%s\n", nbd_get_error ());
142 if (!nbd_aio_is_ready (nbd
)) {
143 fprintf (stderr
, "server closed early\n");
147 /* Read the size in bytes and print it. */
148 size
= nbd_get_size (nbd
);
150 fprintf (stderr
, "%s\n", nbd_get_error ());
153 printf ("%s: %s: size = %" PRIi64
" bytes\n",
154 argv
[1], name
, size
);
156 /* Close the libnbd handle. */
159 for (i
= 0; i
< list
.i
; i
++)
160 free (list
.names
[i
]);