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