1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#ifndef NBD_H
21#define NBD_H
22
23#include "block/export.h"
24#include "io/channel-socket.h"
25#include "crypto/tlscreds.h"
26#include "qapi/error.h"
27#include "qemu/bswap.h"
28
29typedef struct NBDExport NBDExport;
30typedef struct NBDClient NBDClient;
31typedef struct NBDClientConnection NBDClientConnection;
32
33extern const BlockExportDriver blk_exp_nbd;
34
35
36
37typedef struct NBDOption {
38 uint64_t magic;
39 uint32_t option;
40 uint32_t length;
41} QEMU_PACKED NBDOption;
42
43typedef struct NBDOptionReply {
44 uint64_t magic;
45 uint32_t option;
46 uint32_t type;
47 uint32_t length;
48} QEMU_PACKED NBDOptionReply;
49
50typedef struct NBDOptionReplyMetaContext {
51 NBDOptionReply h;
52 uint32_t context_id;
53
54} QEMU_PACKED NBDOptionReplyMetaContext;
55
56
57typedef enum NBDMode {
58
59 NBD_MODE_OLDSTYLE,
60 NBD_MODE_EXPORT_NAME,
61 NBD_MODE_SIMPLE,
62 NBD_MODE_STRUCTURED,
63
64} NBDMode;
65
66
67
68
69
70
71typedef struct NBDRequest {
72 uint64_t cookie;
73 uint64_t from;
74 uint32_t len;
75 uint16_t flags;
76 uint16_t type;
77} NBDRequest;
78
79typedef struct NBDSimpleReply {
80 uint32_t magic;
81 uint32_t error;
82 uint64_t cookie;
83} QEMU_PACKED NBDSimpleReply;
84
85
86typedef struct NBDStructuredReplyChunk {
87 uint32_t magic;
88 uint16_t flags;
89 uint16_t type;
90 uint64_t cookie;
91 uint32_t length;
92} QEMU_PACKED NBDStructuredReplyChunk;
93
94typedef union NBDReply {
95 NBDSimpleReply simple;
96 NBDStructuredReplyChunk structured;
97 struct {
98
99
100
101
102
103 uint32_t magic;
104 uint32_t _skip;
105 uint64_t cookie;
106 } QEMU_PACKED;
107} NBDReply;
108
109
110typedef struct NBDStructuredReadData {
111
112 uint64_t offset;
113
114} QEMU_PACKED NBDStructuredReadData;
115
116
117typedef struct NBDStructuredReadHole {
118
119 uint64_t offset;
120 uint32_t length;
121} QEMU_PACKED NBDStructuredReadHole;
122
123
124typedef struct NBDStructuredError {
125
126 uint32_t error;
127 uint16_t message_length;
128} QEMU_PACKED NBDStructuredError;
129
130
131typedef struct NBDStructuredMeta {
132
133 uint32_t context_id;
134
135} QEMU_PACKED NBDStructuredMeta;
136
137
138typedef struct NBDExtent {
139 uint32_t length;
140 uint32_t flags;
141} QEMU_PACKED NBDExtent;
142
143
144
145enum {
146 NBD_FLAG_HAS_FLAGS_BIT = 0,
147 NBD_FLAG_READ_ONLY_BIT = 1,
148 NBD_FLAG_SEND_FLUSH_BIT = 2,
149 NBD_FLAG_SEND_FUA_BIT = 3,
150 NBD_FLAG_ROTATIONAL_BIT = 4,
151
152 NBD_FLAG_SEND_TRIM_BIT = 5,
153 NBD_FLAG_SEND_WRITE_ZEROES_BIT = 6,
154 NBD_FLAG_SEND_DF_BIT = 7,
155 NBD_FLAG_CAN_MULTI_CONN_BIT = 8,
156 NBD_FLAG_SEND_RESIZE_BIT = 9,
157 NBD_FLAG_SEND_CACHE_BIT = 10,
158 NBD_FLAG_SEND_FAST_ZERO_BIT = 11,
159};
160
161#define NBD_FLAG_HAS_FLAGS (1 << NBD_FLAG_HAS_FLAGS_BIT)
162#define NBD_FLAG_READ_ONLY (1 << NBD_FLAG_READ_ONLY_BIT)
163#define NBD_FLAG_SEND_FLUSH (1 << NBD_FLAG_SEND_FLUSH_BIT)
164#define NBD_FLAG_SEND_FUA (1 << NBD_FLAG_SEND_FUA_BIT)
165#define NBD_FLAG_ROTATIONAL (1 << NBD_FLAG_ROTATIONAL_BIT)
166#define NBD_FLAG_SEND_TRIM (1 << NBD_FLAG_SEND_TRIM_BIT)
167#define NBD_FLAG_SEND_WRITE_ZEROES (1 << NBD_FLAG_SEND_WRITE_ZEROES_BIT)
168#define NBD_FLAG_SEND_DF (1 << NBD_FLAG_SEND_DF_BIT)
169#define NBD_FLAG_CAN_MULTI_CONN (1 << NBD_FLAG_CAN_MULTI_CONN_BIT)
170#define NBD_FLAG_SEND_RESIZE (1 << NBD_FLAG_SEND_RESIZE_BIT)
171#define NBD_FLAG_SEND_CACHE (1 << NBD_FLAG_SEND_CACHE_BIT)
172#define NBD_FLAG_SEND_FAST_ZERO (1 << NBD_FLAG_SEND_FAST_ZERO_BIT)
173
174
175
176#define NBD_FLAG_FIXED_NEWSTYLE (1 << 0)
177#define NBD_FLAG_NO_ZEROES (1 << 1)
178
179
180
181#define NBD_FLAG_C_FIXED_NEWSTYLE (1 << 0)
182#define NBD_FLAG_C_NO_ZEROES (1 << 1)
183
184
185#define NBD_OPT_EXPORT_NAME (1)
186#define NBD_OPT_ABORT (2)
187#define NBD_OPT_LIST (3)
188
189#define NBD_OPT_STARTTLS (5)
190#define NBD_OPT_INFO (6)
191#define NBD_OPT_GO (7)
192#define NBD_OPT_STRUCTURED_REPLY (8)
193#define NBD_OPT_LIST_META_CONTEXT (9)
194#define NBD_OPT_SET_META_CONTEXT (10)
195
196
197#define NBD_REP_ERR(value) ((UINT32_C(1) << 31) | (value))
198
199#define NBD_REP_ACK (1)
200#define NBD_REP_SERVER (2)
201#define NBD_REP_INFO (3)
202#define NBD_REP_META_CONTEXT (4)
203
204#define NBD_REP_ERR_UNSUP NBD_REP_ERR(1)
205#define NBD_REP_ERR_POLICY NBD_REP_ERR(2)
206#define NBD_REP_ERR_INVALID NBD_REP_ERR(3)
207#define NBD_REP_ERR_PLATFORM NBD_REP_ERR(4)
208#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR(5)
209#define NBD_REP_ERR_UNKNOWN NBD_REP_ERR(6)
210#define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR(7)
211#define NBD_REP_ERR_BLOCK_SIZE_REQD NBD_REP_ERR(8)
212
213
214#define NBD_INFO_EXPORT 0
215#define NBD_INFO_NAME 1
216#define NBD_INFO_DESCRIPTION 2
217#define NBD_INFO_BLOCK_SIZE 3
218
219
220#define NBD_CMD_FLAG_FUA (1 << 0)
221#define NBD_CMD_FLAG_NO_HOLE (1 << 1)
222#define NBD_CMD_FLAG_DF (1 << 2)
223#define NBD_CMD_FLAG_REQ_ONE (1 << 3)
224
225#define NBD_CMD_FLAG_FAST_ZERO (1 << 4)
226
227
228enum {
229 NBD_CMD_READ = 0,
230 NBD_CMD_WRITE = 1,
231 NBD_CMD_DISC = 2,
232 NBD_CMD_FLUSH = 3,
233 NBD_CMD_TRIM = 4,
234 NBD_CMD_CACHE = 5,
235 NBD_CMD_WRITE_ZEROES = 6,
236 NBD_CMD_BLOCK_STATUS = 7,
237};
238
239#define NBD_DEFAULT_PORT 10809
240
241
242#define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024)
243
244
245
246
247
248
249#define NBD_MAX_STRING_SIZE 4096
250
251
252#define NBD_SIMPLE_REPLY_MAGIC 0x67446698
253#define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef
254
255
256#define NBD_REPLY_FLAG_DONE (1 << 0)
257
258
259#define NBD_REPLY_ERR(value) ((1 << 15) | (value))
260
261#define NBD_REPLY_TYPE_NONE 0
262#define NBD_REPLY_TYPE_OFFSET_DATA 1
263#define NBD_REPLY_TYPE_OFFSET_HOLE 2
264#define NBD_REPLY_TYPE_BLOCK_STATUS 5
265#define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1)
266#define NBD_REPLY_TYPE_ERROR_OFFSET NBD_REPLY_ERR(2)
267
268
269#define NBD_STATE_HOLE (1 << 0)
270#define NBD_STATE_ZERO (1 << 1)
271
272
273#define NBD_STATE_DIRTY (1 << 0)
274
275
276
277static inline bool nbd_reply_type_is_error(int type)
278{
279 return type & (1 << 15);
280}
281
282
283
284
285
286#define NBD_SUCCESS 0
287#define NBD_EPERM 1
288#define NBD_EIO 5
289#define NBD_ENOMEM 12
290#define NBD_EINVAL 22
291#define NBD_ENOSPC 28
292#define NBD_EOVERFLOW 75
293#define NBD_ENOTSUP 95
294#define NBD_ESHUTDOWN 108
295
296
297typedef struct NBDExportInfo {
298
299 bool request_sizes;
300 char *x_dirty_bitmap;
301
302
303
304 char *name;
305
306
307
308 bool structured_reply;
309 bool base_allocation;
310
311
312
313 uint64_t size;
314 uint16_t flags;
315 uint32_t min_block;
316 uint32_t opt_block;
317 uint32_t max_block;
318
319 uint32_t context_id;
320
321
322 char *description;
323 int n_contexts;
324 char **contexts;
325} NBDExportInfo;
326
327int nbd_receive_negotiate(AioContext *aio_context, QIOChannel *ioc,
328 QCryptoTLSCreds *tlscreds,
329 const char *hostname, QIOChannel **outioc,
330 NBDExportInfo *info, Error **errp);
331void nbd_free_export_list(NBDExportInfo *info, int count);
332int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
333 const char *hostname, NBDExportInfo **info,
334 Error **errp);
335int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,
336 Error **errp);
337int nbd_send_request(QIOChannel *ioc, NBDRequest *request);
338int coroutine_fn nbd_receive_reply(BlockDriverState *bs, QIOChannel *ioc,
339 NBDReply *reply, Error **errp);
340int nbd_client(int fd);
341int nbd_disconnect(int fd);
342int nbd_errno_to_system_errno(int err);
343
344void nbd_export_set_on_eject_blk(BlockExport *exp, BlockBackend *blk);
345
346AioContext *nbd_export_aio_context(NBDExport *exp);
347NBDExport *nbd_export_find(const char *name);
348
349void nbd_client_new(QIOChannelSocket *sioc,
350 QCryptoTLSCreds *tlscreds,
351 const char *tlsauthz,
352 void (*close_fn)(NBDClient *, bool));
353void nbd_client_get(NBDClient *client);
354void nbd_client_put(NBDClient *client);
355
356void nbd_server_is_qemu_nbd(int max_connections);
357bool nbd_server_is_running(void);
358int nbd_server_max_connections(void);
359void nbd_server_start(SocketAddress *addr, const char *tls_creds,
360 const char *tls_authz, uint32_t max_connections,
361 Error **errp);
362void nbd_server_start_options(NbdServerOptions *arg, Error **errp);
363
364
365
366
367static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
368 const char *desc, Error **errp)
369{
370 ERRP_GUARD();
371 int ret = qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
372
373 if (ret < 0) {
374 if (desc) {
375 error_prepend(errp, "Failed to read %s: ", desc);
376 }
377 return ret;
378 }
379
380 return 0;
381}
382
383#define DEF_NBD_READ_N(bits) \
384static inline int nbd_read##bits(QIOChannel *ioc, \
385 uint##bits##_t *val, \
386 const char *desc, Error **errp) \
387{ \
388 int ret = nbd_read(ioc, val, sizeof(*val), desc, errp); \
389 if (ret < 0) { \
390 return ret; \
391 } \
392 *val = be##bits##_to_cpu(*val); \
393 return 0; \
394}
395
396DEF_NBD_READ_N(16)
397DEF_NBD_READ_N(32)
398DEF_NBD_READ_N(64)
399
400#undef DEF_NBD_READ_N
401
402static inline bool nbd_reply_is_simple(NBDReply *reply)
403{
404 return reply->magic == NBD_SIMPLE_REPLY_MAGIC;
405}
406
407static inline bool nbd_reply_is_structured(NBDReply *reply)
408{
409 return reply->magic == NBD_STRUCTURED_REPLY_MAGIC;
410}
411
412const char *nbd_reply_type_lookup(uint16_t type);
413const char *nbd_opt_lookup(uint32_t opt);
414const char *nbd_rep_lookup(uint32_t rep);
415const char *nbd_info_lookup(uint16_t info);
416const char *nbd_cmd_lookup(uint16_t info);
417const char *nbd_err_lookup(int err);
418const char *nbd_mode_lookup(NBDMode mode);
419
420
421void nbd_client_connection_enable_retry(NBDClientConnection *conn);
422
423NBDClientConnection *nbd_client_connection_new(const SocketAddress *saddr,
424 bool do_negotiation,
425 const char *export_name,
426 const char *x_dirty_bitmap,
427 QCryptoTLSCreds *tlscreds,
428 const char *tlshostname);
429void nbd_client_connection_release(NBDClientConnection *conn);
430
431QIOChannel *coroutine_fn
432nbd_co_establish_connection(NBDClientConnection *conn, NBDExportInfo *info,
433 bool blocking, Error **errp);
434
435void nbd_co_establish_connection_cancel(NBDClientConnection *conn);
436
437#endif
438