1nbd_opt_go(3) LIBNBD nbd_opt_go(3)
2
3
4
6 nbd_opt_go - end negotiation and move on to using an export
7
9 #include <libnbd.h>
10
11 int nbd_opt_go (struct nbd_handle *h);
12
14 Request that the server finish negotiation and move on to serving the
15 export previously specified by the most recent nbd_set_export_name(3)
16 or nbd_connect_uri(3). This can only be used if nbd_set_opt_mode(3)
17 enabled option mode.
18
19 If this fails, the server may still be in negotiation, where it is
20 possible to attempt another option such as a different export name;
21 although older servers will instead have killed the connection.
22
24 If the call is successful the function returns 0.
25
27 On error "-1" is returned.
28
29 Refer to "ERROR HANDLING" in libnbd(3) for how to get further details
30 of the error.
31
32 The following parameters must not be NULL: "h". For more information
33 see "Non-NULL parameters" in libnbd(3).
34
36 The handle must be negotiating, otherwise this call will return an
37 error.
38
40 This function first appeared in libnbd 1.4.
41
42 If you need to test if this function is available at compile time check
43 if the following macro is defined:
44
45 #define LIBNBD_HAVE_NBD_OPT_GO 1
46
48 This example is also available as examples/list-exports.c in the libnbd
49 source code.
50
51 /* This example shows how to list NBD exports.
52 *
53 * To test this with qemu-nbd:
54 * $ qemu-nbd -x "hello" -t -k /tmp/sock disk.img
55 * $ ./run examples/list-exports /tmp/sock
56 * [0] hello
57 * Which export to connect to (-1 to quit)? 0
58 * Connecting to hello ...
59 * /tmp/sock: hello: size = 2048 bytes
60 *
61 * To test this with nbdkit (requires 1.22):
62 * $ nbdkit -U /tmp/sock sh - <<\EOF
63 * case $1 in
64 * list_exports) echo NAMES; echo foo; echo foobar ;;
65 * open) echo "$3" ;;
66 * get_size) echo "$2" | wc -c ;;
67 * pread) echo "$2" | dd bs=1 skip=$4 count=$3 ;;
68 * *) exit 2 ;;
69 * esac
70 * EOF
71 * $ ./run examples/list-exports /tmp/sock
72 * [0] foo
73 * [1] foobar
74 * Which export to connect to (-1 to quit)? 1
75 * Connecting to foobar ...
76 * /tmp/sock: foobar: size = 7 bytes
77 */
78
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <stdint.h>
82 #include <string.h>
83 #include <inttypes.h>
84 #include <errno.h>
85
86 #include <libnbd.h>
87
88 struct export_list {
89 int i;
90 char **names;
91 };
92
93 /* Callback function for nbd_opt_list */
94 static int
95 list_one (void *opaque, const char *name,
96 const char *description)
97 {
98 struct export_list *l = opaque;
99 char **names;
100
101 printf ("[%d] %s\n", l->i, name);
102 if (*description)
103 printf(" (%s)\n", description);
104 names = realloc (l->names,
105 (l->i + 1) * sizeof *names);
106 if (!names) {
107 perror ("realloc");
108 exit (EXIT_FAILURE);
109 }
110 names[l->i] = strdup (name);
111 if (!names[l->i]) {
112 perror ("strdup");
113 exit (EXIT_FAILURE);
114 }
115 l->names = names;
116 l->i++;
117 return 0;
118 }
119
120 int
121 main (int argc, char *argv[])
122 {
123 struct nbd_handle *nbd;
124 int i;
125 const char *name;
126 int64_t size;
127 struct export_list list = { 0 };
128
129 if (argc != 2) {
130 fprintf (stderr, "%s socket\n", argv[0]);
131 exit (EXIT_FAILURE);
132 }
133
134 /* Create the libnbd handle. */
135 nbd = nbd_create ();
136 if (nbd == NULL) {
137 fprintf (stderr, "%s\n", nbd_get_error ());
138 exit (EXIT_FAILURE);
139 }
140
141 /* Set opt mode. */
142 nbd_set_opt_mode (nbd, true);
143
144 /* Connect to the NBD server over a
145 * Unix domain socket. If we did not
146 * end up in option mode, then a
147 * listing is not possible.
148 */
149 if (nbd_connect_unix (nbd, argv[1]) == -1) {
150 fprintf (stderr, "%s\n", nbd_get_error ());
151 exit (EXIT_FAILURE);
152 }
153 if (!nbd_aio_is_negotiating (nbd)) {
154 fprintf (stderr, "Server does not support "
155 "listing exports.\n");
156 exit (EXIT_FAILURE);
157 }
158
159 /* Print the export list. */
160 if (nbd_opt_list (nbd,
161 (nbd_list_callback) {
162 .callback = list_one,
163 .user_data = &list, }) == -1) {
164 fprintf (stderr, "%s\n", nbd_get_error ());
165 exit (EXIT_FAILURE);
166 }
167
168 /* Display the list of exports. */
169 printf ("Which export to connect to? ");
170 if (scanf ("%d", &i) != 1) exit (EXIT_FAILURE);
171 if (i == -1) {
172 if (nbd_opt_abort (nbd) == -1) {
173 fprintf (stderr, "%s\n", nbd_get_error ());
174 exit (EXIT_FAILURE);
175 }
176 nbd_close (nbd);
177 exit (EXIT_SUCCESS);
178 }
179 if (i < 0 || i >= list.i) {
180 fprintf (stderr, "index %d out of range", i);
181 exit (EXIT_FAILURE);
182 }
183 name = list.names[i];
184 printf ("Connecting to %s ...\n", name);
185
186 /* Resume connecting to the chosen export. */
187 if (nbd_set_export_name (nbd, name) == -1 ||
188 nbd_opt_go (nbd) == -1) {
189 fprintf (stderr, "%s\n", nbd_get_error ());
190 exit (EXIT_FAILURE);
191 }
192 if (!nbd_aio_is_ready (nbd)) {
193 fprintf (stderr, "server closed early\n");
194 exit (EXIT_FAILURE);
195 }
196
197 /* Read the size in bytes and print it. */
198 size = nbd_get_size (nbd);
199 if (size == -1) {
200 fprintf (stderr, "%s\n", nbd_get_error ());
201 exit (EXIT_FAILURE);
202 }
203 printf ("%s: %s: size = %" PRIi64 " bytes\n",
204 argv[1], name, size);
205
206 /* Close the libnbd handle. */
207 nbd_close (nbd);
208
209 for (i = 0; i < list.i; i++)
210 free (list.names[i]);
211 free (list.names);
212
213 exit (EXIT_SUCCESS);
214 }
215
217 nbd_aio_opt_go(3), nbd_connect_uri(3), nbd_create(3), nbd_opt_abort(3),
218 nbd_opt_info(3), nbd_set_export_name(3), nbd_set_opt_mode(3),
219 libnbd(3).
220
222 Eric Blake
223
224 Richard W.M. Jones
225
227 Copyright (C) 2019-2021 Red Hat Inc.
228
230 This library is free software; you can redistribute it and/or modify it
231 under the terms of the GNU Lesser General Public License as published
232 by the Free Software Foundation; either version 2 of the License, or
233 (at your option) any later version.
234
235 This library is distributed in the hope that it will be useful, but
236 WITHOUT ANY WARRANTY; without even the implied warranty of
237 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
238 Lesser General Public License for more details.
239
240 You should have received a copy of the GNU Lesser General Public
241 License along with this library; if not, write to the Free Software
242 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
243 02110-1301 USA
244
245
246
247libnbd-1.14.2 2023-01-03 nbd_opt_go(3)