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