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 static struct data data[NR_SECTORS];
119
120 int
121 main (int argc, char *argv[])
122 {
123 struct nbd_handle *nbd;
124 size_t i;
125
126 if (argc != 2) {
127 fprintf (stderr, "%s socket\n", argv[0]);
128 exit (EXIT_FAILURE);
129 }
130
131 /* Create the libnbd handle. */
132 nbd = nbd_create ();
133 if (nbd == NULL) {
134 fprintf (stderr, "%s\n", nbd_get_error ());
135 exit (EXIT_FAILURE);
136 }
137
138 /* Connect to the NBD server over a Unix domain socket.
139 * This only starts the connection.
140 */
141 if (nbd_aio_connect_unix (nbd, argv[1]) == -1) {
142 fprintf (stderr, "%s\n", nbd_get_error ());
143 exit (EXIT_FAILURE);
144 }
145
146 /* Wait for the connection to complete. The use of
147 * nbd_poll here is only as an example. You could also
148 * integrate this with poll(2), glib or another main
149 * loop. Read libnbd(3) and the source file lib/poll.c.
150 */
151 while (!nbd_aio_is_ready (nbd)) {
152 if (nbd_poll (nbd, -1) == -1) {
153 fprintf (stderr, "%s\n", nbd_get_error ());
154 exit (EXIT_FAILURE);
155 }
156 }
157
158 assert (nbd_get_size (nbd) >= NR_SECTORS * SECTOR_SIZE);
159
160 /* Issue read commands for the first NR sectors. */
161 for (i = 0; i < NR_SECTORS; ++i) {
162 data[i].offset = i * SECTOR_SIZE;
163
164 /* The callback (hexdump) is called when the command
165 * completes. The buffer must continue to exist while
166 * the command is running.
167 */
168 if (nbd_aio_pread (nbd, data[i].sector, SECTOR_SIZE,
169 data[i].offset,
170 (nbd_completion_callback) {
171 .callback = hexdump,
172 .user_data = &data[i],
173 }, 0) == -1) {
174 fprintf (stderr, "%s\n", nbd_get_error ());
175 exit (EXIT_FAILURE);
176 }
177 }
178
179 /* Run the main loop until all the commands have
180 * completed and retired. Again the use of nbd_poll
181 * here is only as an example.
182 */
183 while (nbd_aio_in_flight (nbd) > 0) {
184 if (nbd_poll (nbd, -1) == -1) {
185 fprintf (stderr, "%s\n", nbd_get_error ());
186 exit (EXIT_FAILURE);
187 }
188 }
189
190 /* Close the libnbd handle. */
191 nbd_close (nbd);
192
193 exit (EXIT_SUCCESS);
194 }
195
197 nbd_aio_command_completed(3), nbd_aio_pread_structured(3),
198 nbd_create(3), nbd_pread(3), nbd_set_strict_mode(3), "Issuing
199 asynchronous commands" in libnbd(3), libnbd(3).
200
202 Eric Blake
203
204 Richard W.M. Jones
205
207 Copyright (C) 2019-2021 Red Hat Inc.
208
210 This library is free software; you can redistribute it and/or modify it
211 under the terms of the GNU Lesser General Public License as published
212 by the Free Software Foundation; either version 2 of the License, or
213 (at your option) any later version.
214
215 This library is distributed in the hope that it will be useful, but
216 WITHOUT ANY WARRANTY; without even the implied warranty of
217 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
218 Lesser General Public License for more details.
219
220 You should have received a copy of the GNU Lesser General Public
221 License along with this library; if not, write to the Free Software
222 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
223 02110-1301 USA
224
225
226
227libnbd-1.10.1 2021-10-25 nbd_aio_pread(3)