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