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
24#include "qemu-common.h"
25#include "qemu/option.h"
26#include "io/channel-socket.h"
27#include "crypto/tlscreds.h"
28
29
30
31struct nbd_option {
32 uint64_t magic;
33 uint32_t option;
34 uint32_t length;
35} QEMU_PACKED;
36typedef struct nbd_option nbd_option;
37
38struct nbd_opt_reply {
39 uint64_t magic;
40 uint32_t option;
41 uint32_t type;
42 uint32_t length;
43} QEMU_PACKED;
44typedef struct nbd_opt_reply nbd_opt_reply;
45
46
47
48
49
50
51struct NBDRequest {
52 uint64_t handle;
53 uint64_t from;
54 uint32_t len;
55 uint16_t flags;
56 uint16_t type;
57};
58typedef struct NBDRequest NBDRequest;
59
60typedef struct NBDSimpleReply {
61 uint32_t magic;
62 uint32_t error;
63 uint64_t handle;
64} QEMU_PACKED NBDSimpleReply;
65
66
67typedef struct NBDStructuredReplyChunk {
68 uint32_t magic;
69 uint16_t flags;
70 uint16_t type;
71 uint64_t handle;
72 uint32_t length;
73} QEMU_PACKED NBDStructuredReplyChunk;
74
75typedef union NBDReply {
76 NBDSimpleReply simple;
77 NBDStructuredReplyChunk structured;
78 struct {
79
80
81
82
83 uint32_t magic;
84 uint32_t _skip;
85 uint64_t handle;
86 } QEMU_PACKED;
87} NBDReply;
88
89
90typedef struct NBDStructuredReadData {
91 NBDStructuredReplyChunk h;
92 uint64_t offset;
93
94} QEMU_PACKED NBDStructuredReadData;
95
96
97typedef struct NBDStructuredReadHole {
98 NBDStructuredReplyChunk h;
99 uint64_t offset;
100 uint32_t length;
101} QEMU_PACKED NBDStructuredReadHole;
102
103
104typedef struct NBDStructuredError {
105 NBDStructuredReplyChunk h;
106 uint32_t error;
107 uint16_t message_length;
108} QEMU_PACKED NBDStructuredError;
109
110
111
112#define NBD_FLAG_HAS_FLAGS (1 << 0)
113#define NBD_FLAG_READ_ONLY (1 << 1)
114#define NBD_FLAG_SEND_FLUSH (1 << 2)
115#define NBD_FLAG_SEND_FUA (1 << 3)
116#define NBD_FLAG_ROTATIONAL (1 << 4)
117
118#define NBD_FLAG_SEND_TRIM (1 << 5)
119#define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6)
120#define NBD_FLAG_SEND_DF (1 << 7)
121
122
123
124#define NBD_FLAG_FIXED_NEWSTYLE (1 << 0)
125#define NBD_FLAG_NO_ZEROES (1 << 1)
126
127
128
129#define NBD_FLAG_C_FIXED_NEWSTYLE (1 << 0)
130#define NBD_FLAG_C_NO_ZEROES (1 << 1)
131
132
133#define NBD_OPT_EXPORT_NAME (1)
134#define NBD_OPT_ABORT (2)
135#define NBD_OPT_LIST (3)
136
137#define NBD_OPT_STARTTLS (5)
138#define NBD_OPT_INFO (6)
139#define NBD_OPT_GO (7)
140#define NBD_OPT_STRUCTURED_REPLY (8)
141
142
143#define NBD_REP_ERR(value) ((UINT32_C(1) << 31) | (value))
144
145#define NBD_REP_ACK (1)
146#define NBD_REP_SERVER (2)
147#define NBD_REP_INFO (3)
148
149#define NBD_REP_ERR_UNSUP NBD_REP_ERR(1)
150#define NBD_REP_ERR_POLICY NBD_REP_ERR(2)
151#define NBD_REP_ERR_INVALID NBD_REP_ERR(3)
152#define NBD_REP_ERR_PLATFORM NBD_REP_ERR(4)
153#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR(5)
154#define NBD_REP_ERR_UNKNOWN NBD_REP_ERR(6)
155#define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR(7)
156#define NBD_REP_ERR_BLOCK_SIZE_REQD NBD_REP_ERR(8)
157
158
159#define NBD_INFO_EXPORT 0
160#define NBD_INFO_NAME 1
161#define NBD_INFO_DESCRIPTION 2
162#define NBD_INFO_BLOCK_SIZE 3
163
164
165#define NBD_CMD_FLAG_FUA (1 << 0)
166#define NBD_CMD_FLAG_NO_HOLE (1 << 1)
167#define NBD_CMD_FLAG_DF (1 << 2)
168
169
170enum {
171 NBD_CMD_READ = 0,
172 NBD_CMD_WRITE = 1,
173 NBD_CMD_DISC = 2,
174 NBD_CMD_FLUSH = 3,
175 NBD_CMD_TRIM = 4,
176
177 NBD_CMD_WRITE_ZEROES = 6,
178};
179
180#define NBD_DEFAULT_PORT 10809
181
182
183#define NBD_MAX_BUFFER_SIZE (32 * 1024 * 1024)
184
185
186
187
188
189
190#define NBD_MAX_NAME_SIZE 256
191
192
193#define NBD_SIMPLE_REPLY_MAGIC 0x67446698
194#define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef
195
196
197#define NBD_REPLY_FLAG_DONE (1 << 0)
198
199
200#define NBD_REPLY_ERR(value) ((1 << 15) | (value))
201
202#define NBD_REPLY_TYPE_NONE 0
203#define NBD_REPLY_TYPE_OFFSET_DATA 1
204#define NBD_REPLY_TYPE_OFFSET_HOLE 2
205#define NBD_REPLY_TYPE_ERROR NBD_REPLY_ERR(1)
206#define NBD_REPLY_TYPE_ERROR_OFFSET NBD_REPLY_ERR(2)
207
208static inline bool nbd_reply_type_is_error(int type)
209{
210 return type & (1 << 15);
211}
212
213
214
215
216
217#define NBD_SUCCESS 0
218#define NBD_EPERM 1
219#define NBD_EIO 5
220#define NBD_ENOMEM 12
221#define NBD_EINVAL 22
222#define NBD_ENOSPC 28
223#define NBD_EOVERFLOW 75
224#define NBD_ESHUTDOWN 108
225
226
227struct NBDExportInfo {
228
229 bool request_sizes;
230
231
232
233 bool structured_reply;
234
235
236 uint64_t size;
237 uint16_t flags;
238 uint32_t min_block;
239 uint32_t opt_block;
240 uint32_t max_block;
241};
242typedef struct NBDExportInfo NBDExportInfo;
243
244int nbd_receive_negotiate(QIOChannel *ioc, const char *name,
245 QCryptoTLSCreds *tlscreds, const char *hostname,
246 QIOChannel **outioc, NBDExportInfo *info,
247 Error **errp);
248int nbd_init(int fd, QIOChannelSocket *sioc, NBDExportInfo *info,
249 Error **errp);
250int nbd_send_request(QIOChannel *ioc, NBDRequest *request);
251int nbd_receive_reply(QIOChannel *ioc, NBDReply *reply, Error **errp);
252int nbd_client(int fd);
253int nbd_disconnect(int fd);
254int nbd_errno_to_system_errno(int err);
255
256typedef struct NBDExport NBDExport;
257typedef struct NBDClient NBDClient;
258
259NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t size,
260 uint16_t nbdflags, void (*close)(NBDExport *),
261 bool writethrough, BlockBackend *on_eject_blk,
262 Error **errp);
263void nbd_export_close(NBDExport *exp);
264void nbd_export_get(NBDExport *exp);
265void nbd_export_put(NBDExport *exp);
266
267BlockBackend *nbd_export_get_blockdev(NBDExport *exp);
268
269NBDExport *nbd_export_find(const char *name);
270void nbd_export_set_name(NBDExport *exp, const char *name);
271void nbd_export_set_description(NBDExport *exp, const char *description);
272void nbd_export_close_all(void);
273
274void nbd_client_new(NBDExport *exp,
275 QIOChannelSocket *sioc,
276 QCryptoTLSCreds *tlscreds,
277 const char *tlsaclname,
278 void (*close_fn)(NBDClient *, bool));
279void nbd_client_get(NBDClient *client);
280void nbd_client_put(NBDClient *client);
281
282void nbd_server_start(SocketAddress *addr, const char *tls_creds,
283 Error **errp);
284
285
286
287
288
289static inline int nbd_read(QIOChannel *ioc, void *buffer, size_t size,
290 Error **errp)
291{
292 return qio_channel_read_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
293}
294
295static inline bool nbd_reply_is_simple(NBDReply *reply)
296{
297 return reply->magic == NBD_SIMPLE_REPLY_MAGIC;
298}
299
300static inline bool nbd_reply_is_structured(NBDReply *reply)
301{
302 return reply->magic == NBD_STRUCTURED_REPLY_MAGIC;
303}
304
305const char *nbd_reply_type_lookup(uint16_t type);
306
307#endif
308