1nbd_aio_in_flight(3) LIBNBD nbd_aio_in_flight(3)
2
3
4
6 nbd_aio_in_flight - check how many aio commands are still in flight
7
9 #include <libnbd.h>
10
11 int nbd_aio_in_flight (struct nbd_handle *h);
12
14 Return the number of in-flight aio commands that are still awaiting a
15 response from the server before they can be retired. If this returns a
16 non-zero value when requesting a disconnect from the server (see
17 nbd_aio_disconnect(3) and nbd_shutdown(3)), libnbd does not try to wait
18 for those commands to complete gracefully; if the server strands
19 commands while shutting down, nbd_aio_command_completed(3) will report
20 those commands as failed with a status of "ENOTCONN".
21
23 This call returns an integer ≥ 0.
24
26 On error "-1" is returned.
27
28 Refer to "ERROR HANDLING" in libnbd(3) for how to get further details
29 of the error.
30
32 The handle must be connected with the server, or shut down, or dead,
33 otherwise this call will return an error.
34
36 This function first appeared in libnbd 1.0.
37
38 If you need to test if this function is available at compile time check
39 if the following macro is defined:
40
41 #define LIBNBD_HAVE_NBD_AIO_IN_FLIGHT 1
42
44 This example is also available as examples/aio-connect-read.c in the
45 libnbd source code.
46
47 /* This example shows how to use the AIO (asynchronous) low
48 * level API to connect to a server and read the disk.
49 *
50 * Here are a few ways to try this example:
51 *
52 * nbdkit -U - linuxdisk . \
53 * --run './aio-connect-read $unixsocket'
54 *
55 * nbdkit -U - floppy . \
56 * --run './aio-connect-read $unixsocket'
57 *
58 * nbdkit -U - pattern size=1M \
59 * --run './aio-connect-read $unixsocket'
60 */
61
62 #include <stdio.h>
63 #include <stdlib.h>
64 #include <stdint.h>
65 #include <inttypes.h>
66 #include <assert.h>
67
68 #include <libnbd.h>
69
70 #define NR_SECTORS 32
71 #define SECTOR_SIZE 512
72
73 struct data {
74 uint64_t offset;
75 char sector[SECTOR_SIZE];
76 };
77
78 static int
79 hexdump (void *user_data, int *error)
80 {
81 struct data *data = user_data;
82 FILE *pp;
83
84 printf ("sector at offset 0x%" PRIx64 ":\n",
85 data->offset);
86 pp = popen ("hexdump -C", "w");
87 if (pp == NULL) {
88 perror ("popen: hexdump");
89 exit (EXIT_FAILURE);
90 }
91 fwrite (data->sector, SECTOR_SIZE, 1, pp);
92 pclose (pp);
93 printf ("\n");
94
95 /* Returning 1 from the callback automatically retires
96 * the command.
97 */
98 return 1;
99 }
100
101 int
102 main (int argc, char *argv[])
103 {
104 struct nbd_handle *nbd;
105 struct data data[NR_SECTORS];
106 size_t i;
107
108 if (argc != 2) {
109 fprintf (stderr, "%s socket\n", argv[0]);
110 exit (EXIT_FAILURE);
111 }
112
113 /* Create the libnbd handle. */
114 nbd = nbd_create ();
115 if (nbd == NULL) {
116 fprintf (stderr, "%s\n", nbd_get_error ());
117 exit (EXIT_FAILURE);
118 }
119
120 /* Connect to the NBD server over a Unix domain socket.
121 * This only starts the connection.
122 */
123 if (nbd_aio_connect_unix (nbd, argv[1]) == -1) {
124 fprintf (stderr, "%s\n", nbd_get_error ());
125 exit (EXIT_FAILURE);
126 }
127
128 /* Wait for the connection to complete. The use of
129 * nbd_poll here is only as an example. You could also
130 * integrate this with poll(2), glib or another main
131 * loop. Read libnbd(3) and the source file lib/poll.c.
132 */
133 while (!nbd_aio_is_ready (nbd)) {
134 if (nbd_poll (nbd, -1) == -1) {
135 fprintf (stderr, "%s\n", nbd_get_error ());
136 exit (EXIT_FAILURE);
137 }
138 }
139
140 assert (nbd_get_size (nbd) >= NR_SECTORS * SECTOR_SIZE);
141
142 /* Issue read commands for the first NR sectors. */
143 for (i = 0; i < NR_SECTORS; ++i) {
144 data[i].offset = i * SECTOR_SIZE;
145
146 /* The callback (hexdump) is called when the command
147 * completes. The buffer must continue to exist while
148 * the command is running.
149 */
150 if (nbd_aio_pread (nbd, data[i].sector, SECTOR_SIZE,
151 data[i].offset,
152 (nbd_completion_callback) {
153 .callback = hexdump,
154 .user_data = &data[i],
155 }, 0) == -1) {
156 fprintf (stderr, "%s\n", nbd_get_error ());
157 exit (EXIT_FAILURE);
158 }
159 }
160
161 /* Run the main loop until all the commands have
162 * completed and retired. Again the use of nbd_poll
163 * here is only as an example.
164 */
165 while (nbd_aio_in_flight (nbd) > 0) {
166 if (nbd_poll (nbd, -1) == -1) {
167 fprintf (stderr, "%s\n", nbd_get_error ());
168 exit (EXIT_FAILURE);
169 }
170 }
171
172 /* Close the libnbd handle. */
173 nbd_close (nbd);
174
175 exit (EXIT_SUCCESS);
176 }
177
179 nbd_aio_command_completed(3), nbd_aio_disconnect(3), nbd_create(3),
180 nbd_shutdown(3), libnbd(3).
181
183 Eric Blake
184
185 Richard W.M. Jones
186
188 Copyright (C) 2019-2021 Red Hat Inc.
189
191 This library is free software; you can redistribute it and/or modify it
192 under the terms of the GNU Lesser General Public License as published
193 by the Free Software Foundation; either version 2 of the License, or
194 (at your option) any later version.
195
196 This library is distributed in the hope that it will be useful, but
197 WITHOUT ANY WARRANTY; without even the implied warranty of
198 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
199 Lesser General Public License for more details.
200
201 You should have received a copy of the GNU Lesser General Public
202 License along with this library; if not, write to the Free Software
203 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
204 02110-1301 USA
205
206
207
208libnbd-1.7.12 2021-05-29 nbd_aio_in_flight(3)