1nbd_aio_pread(3) LIBNBD nbd_aio_pread(3)
2
3
4
6 nbd_aio_pread - read from the NBD server
7
9 #include <libnbd.h>
10
11 typedef struct {
12 int (*callback) (void *user_data, int *error);
13 void *user_data;
14 void (*free) (void *user_data);
15 } nbd_completion_callback;
16
17 int64_t nbd_aio_pread (struct nbd_handle *h, void *buf,
18 size_t count, uint64_t offset,
19 nbd_completion_callback completion_callback,
20 uint32_t flags);
21
23 Issue a read command to the NBD server.
24
25 To check if the command completed, call nbd_aio_command_completed(3).
26 Or supply the optional "completion_callback" which will be invoked as
27 described in "Completion callbacks" in libnbd(3).
28
29 Note that you must ensure "buf" is valid until the command has
30 completed. Other parameters behave as documented in nbd_pread(3).
31
32 By default, libnbd will reject attempts to use this function with
33 parameters that are likely to result in server failure, such as
34 requesting an unknown command flag. The nbd_set_strict_mode(3)
35 function can be used to alter which scenarios should await a server
36 reply rather than failing fast.
37
39 This call returns the 64 bit cookie of the command. The cookie is ≥ 1.
40 Cookies are unique (per libnbd handle, not globally).
41
43 On error "-1" is returned.
44
45 Refer to "ERROR HANDLING" in libnbd(3) for how to get further details
46 of the error.
47
49 The handle must be connected with the server, otherwise this call will
50 return an error.
51
53 This function first appeared in libnbd 1.0.
54
55 If you need to test if this function is available at compile time check
56 if the following macro is defined:
57
58 #define LIBNBD_HAVE_NBD_AIO_PREAD 1
59
61 This example is also available as examples/aio-connect-read.c in the
62 libnbd source code.
63
64 /* This example shows how to use the AIO (asynchronous) low
65 * level API to connect to a server and read the disk.
66 *
67 * Here are a few ways to try this example:
68 *
69 * nbdkit -U - linuxdisk . \
70 * --run './aio-connect-read $unixsocket'
71 *
72 * nbdkit -U - floppy . \
73 * --run './aio-connect-read $unixsocket'
74 *
75 * nbdkit -U - pattern size=1M \
76 * --run './aio-connect-read $unixsocket'
77 */
78
79 #include <stdio.h>
80 #include <stdlib.h>
81 #include <stdint.h>
82 #include <inttypes.h>
83 #include <assert.h>
84
85 #include <libnbd.h>
86
87 #define NR_SECTORS 32
88 #define SECTOR_SIZE 512
89
90 struct data {
91 uint64_t offset;
92 char sector[SECTOR_SIZE];
93 };
94
95 static int
96 hexdump (void *user_data, int *error)
97 {
98 struct data *data = user_data;
99 FILE *pp;
100
101 printf ("sector at offset 0x%" PRIx64 ":\n",
102 data->offset);
103 pp = popen ("hexdump -C", "w");
104 if (pp == NULL) {
105 perror ("popen: hexdump");
106 exit (EXIT_FAILURE);
107 }
108 fwrite (data->sector, SECTOR_SIZE, 1, pp);
109 pclose (pp);
110 printf ("\n");
111
112 /* Returning 1 from the callback automatically retires
113 * the command.
114 */
115 return 1;
116 }
117
118 int
119 main (int argc, char *argv[])
120 {
121 struct nbd_handle *nbd;
122 struct data data[NR_SECTORS];
123 size_t i;
124
125 if (argc != 2) {
126 fprintf (stderr, "%s socket\n", argv[0]);
127 exit (EXIT_FAILURE);
128 }
129
130 /* Create the libnbd handle. */
131 nbd = nbd_create ();
132 if (nbd == NULL) {
133 fprintf (stderr, "%s\n", nbd_get_error ());
134 exit (EXIT_FAILURE);
135 }
136
137 /* Connect to the NBD server over a Unix domain socket.
138 * This only starts the connection.
139 */
140 if (nbd_aio_connect_unix (nbd, argv[1]) == -1) {
141 fprintf (stderr, "%s\n", nbd_get_error ());
142 exit (EXIT_FAILURE);
143 }
144
145 /* Wait for the connection to complete. The use of
146 * nbd_poll here is only as an example. You could also
147 * integrate this with poll(2), glib or another main
148 * loop. Read libnbd(3) and the source file lib/poll.c.
149 */
150 while (!nbd_aio_is_ready (nbd)) {
151 if (nbd_poll (nbd, -1) == -1) {
152 fprintf (stderr, "%s\n", nbd_get_error ());
153 exit (EXIT_FAILURE);
154 }
155 }
156
157 assert (nbd_get_size (nbd) >= NR_SECTORS * SECTOR_SIZE);
158
159 /* Issue read commands for the first NR sectors. */
160 for (i = 0; i < NR_SECTORS; ++i) {
161 data[i].offset = i * SECTOR_SIZE;
162
163 /* The callback (hexdump) is called when the command
164 * completes. The buffer must continue to exist while
165 * the command is running.
166 */
167 if (nbd_aio_pread (nbd, data[i].sector, SECTOR_SIZE,
168 data[i].offset,
169 (nbd_completion_callback) {
170 .callback = hexdump,
171 .user_data = &data[i],
172 }, 0) == -1) {
173 fprintf (stderr, "%s\n", nbd_get_error ());
174 exit (EXIT_FAILURE);
175 }
176 }
177
178 /* Run the main loop until all the commands have
179 * completed and retired. Again the use of nbd_poll
180 * here is only as an example.
181 */
182 while (nbd_aio_in_flight (nbd) > 0) {
183 if (nbd_poll (nbd, -1) == -1) {
184 fprintf (stderr, "%s\n", nbd_get_error ());
185 exit (EXIT_FAILURE);
186 }
187 }
188
189 /* Close the libnbd handle. */
190 nbd_close (nbd);
191
192 exit (EXIT_SUCCESS);
193 }
194
196 nbd_aio_command_completed(3), nbd_aio_pread_structured(3),
197 nbd_create(3), nbd_pread(3), nbd_set_strict_mode(3), "Issuing
198 asynchronous commands" in libnbd(3), libnbd(3).
199
201 Eric Blake
202
203 Richard W.M. Jones
204
206 Copyright (C) 2019-2021 Red Hat Inc.
207
209 This library is free software; you can redistribute it and/or modify it
210 under the terms of the GNU Lesser General Public License as published
211 by the Free Software Foundation; either version 2 of the License, or
212 (at your option) any later version.
213
214 This library is distributed in the hope that it will be useful, but
215 WITHOUT ANY WARRANTY; without even the implied warranty of
216 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
217 Lesser General Public License for more details.
218
219 You should have received a copy of the GNU Lesser General Public
220 License along with this library; if not, write to the Free Software
221 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
222 02110-1301 USA
223
224
225
226libnbd-1.7.12 2021-05-29 nbd_aio_pread(3)