1nbd_opt_abort(3)                    LIBNBD                    nbd_opt_abort(3)
2
3
4

NAME

6       nbd_opt_abort - end negotiation and close the connection
7

SYNOPSIS

9        #include <libnbd.h>
10
11        int nbd_opt_abort (struct nbd_handle *h);
12

DESCRIPTION

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

RETURN VALUE

19       If the call is successful the function returns 0.
20

ERRORS

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

HANDLE STATE

31       The handle must be negotiating, otherwise this call will return an
32       error.
33

VERSION

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

EXAMPLE

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

SEE ALSO

212       nbd_aio_opt_abort(3), nbd_create(3), nbd_opt_go(3),
213       nbd_set_opt_mode(3), libnbd(3).
214

AUTHORS

216       Eric Blake
217
218       Richard W.M. Jones
219
221       Copyright (C) 2019-2021 Red Hat Inc.
222

LICENSE

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)
Impressum