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