Diff against libnbd’s copy of this file, and change this one until it
matches.
---
common/protocol/nbd-protocol.h | 76 +++++++++++++++++-----------
server/protocol-handshake-newstyle.c | 26 +++++-----
server/protocol-handshake-oldstyle.c | 4 +-
server/protocol.c | 25 ++++-----
tests/test-layers.c | 14 ++---
5 files changed, 81 insertions(+), 64 deletions(-)
diff --git a/common/protocol/nbd-protocol.h b/common/protocol/nbd-protocol.h
index 60d35d0..724ffb6 100644
--- a/common/protocol/nbd-protocol.h
+++ b/common/protocol/nbd-protocol.h
@@ -40,37 +40,46 @@
* these structures.
*/
+#define NBD_MAX_STRING 4096 /* Maximum length of a string field */
+
/* Old-style handshake. */
-struct old_handshake {
+struct nbd_old_handshake {
char nbdmagic[8]; /* "NBDMAGIC" */
- uint64_t version; /* OLD_VERSION */
+ uint64_t version; /* NBD_OLD_VERSION */
uint64_t exportsize;
uint16_t gflags; /* global flags */
uint16_t eflags; /* per-export flags */
char zeroes[124]; /* must be sent as zero bytes */
} __attribute__((packed));
-#define OLD_VERSION UINT64_C(0x420281861253)
+#define NBD_OLD_VERSION UINT64_C(0x420281861253)
/* New-style handshake. */
-struct new_handshake {
+struct nbd_new_handshake {
char nbdmagic[8]; /* "NBDMAGIC" */
- uint64_t version; /* NEW_VERSION */
+ uint64_t version; /* NBD_NEW_VERSION */
uint16_t gflags; /* global flags */
} __attribute__((packed));
-#define NEW_VERSION UINT64_C(0x49484156454F5054)
+#define NBD_NEW_VERSION UINT64_C(0x49484156454F5054)
/* New-style handshake option (sent by the client to us). */
-struct new_option {
+struct nbd_new_option {
uint64_t version; /* NEW_VERSION */
uint32_t option; /* NBD_OPT_* */
uint32_t optlen; /* option data length */
/* option data follows */
} __attribute__((packed));
+/* Newstyle handshake OPT_EXPORT_NAME reply message. */
+struct nbd_export_name_option_reply {
+ uint64_t exportsize; /* size of export */
+ uint16_t eflags; /* per-export flags */
+ char zeroes[124]; /* optional zeroes */
+} __attribute__((packed));;
+
/* Fixed newstyle handshake reply message. */
-struct fixed_new_option_reply {
+struct nbd_fixed_new_option_reply {
uint64_t magic; /* NBD_REP_MAGIC */
uint32_t option; /* option we are replying to */
uint32_t reply; /* NBD_REP_* */
@@ -110,33 +119,37 @@ struct fixed_new_option_reply {
#define NBD_REP_ERR(val) (0x80000000 | (val))
#define NBD_REP_IS_ERR(val) (!!((val) & 0x80000000))
-#define NBD_REP_ACK 1
-#define NBD_REP_SERVER 2
-#define NBD_REP_INFO 3
-#define NBD_REP_META_CONTEXT 4
-#define NBD_REP_ERR_UNSUP NBD_REP_ERR (1)
-#define NBD_REP_ERR_POLICY NBD_REP_ERR (2)
-#define NBD_REP_ERR_INVALID NBD_REP_ERR (3)
-#define NBD_REP_ERR_PLATFORM NBD_REP_ERR (4)
-#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR (5)
+#define NBD_REP_ACK 1
+#define NBD_REP_SERVER 2
+#define NBD_REP_INFO 3
+#define NBD_REP_META_CONTEXT 4
+#define NBD_REP_ERR_UNSUP NBD_REP_ERR (1)
+#define NBD_REP_ERR_POLICY NBD_REP_ERR (2)
+#define NBD_REP_ERR_INVALID NBD_REP_ERR (3)
+#define NBD_REP_ERR_PLATFORM NBD_REP_ERR (4)
+#define NBD_REP_ERR_TLS_REQD NBD_REP_ERR (5)
+#define NBD_REP_ERR_UNKNOWN NBD_REP_ERR (6)
+#define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR (7)
+#define NBD_REP_ERR_BLOCK_SIZE_REQD NBD_REP_ERR (8)
+#define NBD_REP_ERR_TOO_BIG NBD_REP_ERR (9)
#define NBD_INFO_EXPORT 0
/* NBD_INFO_EXPORT reply (follows fixed_new_option_reply). */
-struct fixed_new_option_reply_info_export {
+struct nbd_fixed_new_option_reply_info_export {
uint16_t info; /* NBD_INFO_EXPORT */
uint64_t exportsize; /* size of export */
uint16_t eflags; /* per-export flags */
} __attribute__((packed));
/* NBD_REP_META_CONTEXT reply (follows fixed_new_option_reply). */
-struct fixed_new_option_reply_meta_context {
+struct nbd_fixed_new_option_reply_meta_context {
uint32_t context_id; /* metadata context ID */
/* followed by a string */
} __attribute__((packed));
/* NBD_REPLY_TYPE_BLOCK_STATUS block descriptor. */
-struct block_descriptor {
+struct nbd_block_descriptor {
uint32_t length; /* length of block */
uint32_t status_flags; /* block type (hole etc) */
} __attribute__((packed));
@@ -144,14 +157,14 @@ struct block_descriptor {
/* New-style handshake server reply when using NBD_OPT_EXPORT_NAME.
* Modern clients use NBD_OPT_GO instead of this.
*/
-struct new_handshake_finish {
+struct nbd_new_handshake_finish {
uint64_t exportsize;
uint16_t eflags; /* per-export flags */
char zeroes[124]; /* must be sent as zero bytes */
} __attribute__((packed));
/* Request (client -> server). */
-struct request {
+struct nbd_request {
uint32_t magic; /* NBD_REQUEST_MAGIC. */
uint16_t flags; /* Request flags. */
uint16_t type; /* Request type. */
@@ -161,14 +174,14 @@ struct request {
} __attribute__((packed));
/* Simple reply (server -> client). */
-struct simple_reply {
+struct nbd_simple_reply {
uint32_t magic; /* NBD_SIMPLE_REPLY_MAGIC. */
uint32_t error; /* NBD_SUCCESS or one of NBD_E*. */
uint64_t handle; /* Opaque handle. */
} __attribute__((packed));
/* Structured reply (server -> client). */
-struct structured_reply {
+struct nbd_structured_reply {
uint32_t magic; /* NBD_STRUCTURED_REPLY_MAGIC. */
uint16_t flags; /* NBD_REPLY_FLAG_* */
uint16_t type; /* NBD_REPLY_TYPE_* */
@@ -176,15 +189,20 @@ struct structured_reply {
uint32_t length; /* Length of payload which follows. */
} __attribute__((packed));
-struct structured_reply_offset_data {
+struct nbd_structured_reply_offset_data {
uint64_t offset; /* offset */
/* Followed by data. */
} __attribute__((packed));
-struct structured_reply_error {
+struct nbd_structured_reply_offset_hole {
+ uint64_t offset;
+ uint32_t length; /* Length of hole. */
+} __attribute__((packed));
+
+struct nbd_structured_reply_error {
uint32_t error; /* NBD_E* error number */
uint16_t len; /* Length of human readable error. */
- /* Followed by human readable error string. */
+ /* Followed by human readable error string, and possibly more structure. */
} __attribute__((packed));
#define NBD_REQUEST_MAGIC 0x25609513
@@ -221,9 +239,7 @@ struct structured_reply_error {
#define NBD_CMD_FLAG_REQ_ONE (1<<3)
#define NBD_CMD_FLAG_FAST_ZERO (1<<4)
-/* Error codes (previously errno).
- * See
http://git.qemu.org/?p=qemu.git;a=commitdiff;h=ca4414804114fd0095b317785b...
- */
+/* NBD error codes. */
#define NBD_SUCCESS 0
#define NBD_EPERM 1
#define NBD_EIO 5
diff --git a/server/protocol-handshake-newstyle.c b/server/protocol-handshake-newstyle.c
index 104796a..413dcf0 100644
--- a/server/protocol-handshake-newstyle.c
+++ b/server/protocol-handshake-newstyle.c
@@ -55,7 +55,7 @@ static int
send_newstyle_option_reply (struct connection *conn,
uint32_t option, uint32_t reply)
{
- struct fixed_new_option_reply fixed_new_option_reply;
+ struct nbd_fixed_new_option_reply fixed_new_option_reply;
fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC);
fixed_new_option_reply.option = htobe32 (option);
@@ -83,7 +83,7 @@ static int
send_newstyle_option_reply_exportname (struct connection *conn,
uint32_t option, uint32_t reply)
{
- struct fixed_new_option_reply fixed_new_option_reply;
+ struct nbd_fixed_new_option_reply fixed_new_option_reply;
size_t name_len = strlen (exportname);
uint32_t len;
@@ -119,8 +119,8 @@ send_newstyle_option_reply_info_export (struct connection *conn,
uint32_t option, uint32_t reply,
uint16_t info, uint64_t exportsize)
{
- struct fixed_new_option_reply fixed_new_option_reply;
- struct fixed_new_option_reply_info_export export;
+ struct nbd_fixed_new_option_reply fixed_new_option_reply;
+ struct nbd_fixed_new_option_reply_info_export export;
fixed_new_option_reply.magic = htobe64 (NBD_REP_MAGIC);
fixed_new_option_reply.option = htobe32 (option);
@@ -147,8 +147,8 @@ send_newstyle_option_reply_meta_context (struct connection *conn,
uint32_t context_id,
const char *name)
{
- struct fixed_new_option_reply fixed_new_option_reply;
- struct fixed_new_option_reply_meta_context context;
+ struct nbd_fixed_new_option_reply fixed_new_option_reply;
+ struct nbd_fixed_new_option_reply_meta_context context;
const size_t namelen = strlen (name);
debug ("newstyle negotiation: %s: replying with %s id %d",
@@ -213,13 +213,13 @@ finish_newstyle_options (struct connection *conn, uint64_t
*exportsize)
static int
negotiate_handshake_newstyle_options (struct connection *conn)
{
- struct new_option new_option;
+ struct nbd_new_option new_option;
size_t nr_options;
uint64_t version;
uint32_t option;
uint32_t optlen;
char data[MAX_OPTION_LENGTH+1];
- struct new_handshake_finish handshake_finish;
+ struct nbd_new_handshake_finish handshake_finish;
const char *optname;
uint64_t exportsize;
@@ -229,10 +229,10 @@ negotiate_handshake_newstyle_options (struct connection *conn)
return -1;
version = be64toh (new_option.version);
- if (version != NEW_VERSION) {
+ if (version != NBD_NEW_VERSION) {
nbdkit_error ("unknown option version %" PRIx64
", expecting %" PRIx64,
- version, NEW_VERSION);
+ version, NBD_NEW_VERSION);
return -1;
}
@@ -296,7 +296,7 @@ negotiate_handshake_newstyle_options (struct connection *conn)
if (conn->send (conn,
&handshake_finish,
(conn->cflags & NBD_FLAG_NO_ZEROES)
- ? offsetof (struct new_handshake_finish, zeroes)
+ ? offsetof (struct nbd_new_handshake_finish, zeroes)
: sizeof handshake_finish, 0) == -1) {
nbdkit_error ("write: %s: %m", optname);
return -1;
@@ -670,7 +670,7 @@ negotiate_handshake_newstyle_options (struct connection *conn)
int
protocol_handshake_newstyle (struct connection *conn)
{
- struct new_handshake handshake;
+ struct nbd_new_handshake handshake;
uint16_t gflags;
gflags = (NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES) & mask_handshake;
@@ -678,7 +678,7 @@ protocol_handshake_newstyle (struct connection *conn)
debug ("newstyle negotiation: flags: global 0x%x", gflags);
memcpy (handshake.nbdmagic, "NBDMAGIC", 8);
- handshake.version = htobe64 (NEW_VERSION);
+ handshake.version = htobe64 (NBD_NEW_VERSION);
handshake.gflags = htobe16 (gflags);
if (conn->send (conn, &handshake, sizeof handshake, 0) == -1) {
diff --git a/server/protocol-handshake-oldstyle.c b/server/protocol-handshake-oldstyle.c
index 87cb265..8faa4f0 100644
--- a/server/protocol-handshake-oldstyle.c
+++ b/server/protocol-handshake-oldstyle.c
@@ -46,7 +46,7 @@
int
protocol_handshake_oldstyle (struct connection *conn)
{
- struct old_handshake handshake;
+ struct nbd_old_handshake handshake;
uint64_t exportsize;
uint16_t gflags, eflags;
@@ -61,7 +61,7 @@ protocol_handshake_oldstyle (struct connection *conn)
memset (&handshake, 0, sizeof handshake);
memcpy (handshake.nbdmagic, "NBDMAGIC", 8);
- handshake.version = htobe64 (OLD_VERSION);
+ handshake.version = htobe64 (NBD_OLD_VERSION);
handshake.exportsize = htobe64 (exportsize);
handshake.gflags = htobe16 (gflags);
handshake.eflags = htobe16 (eflags);
diff --git a/server/protocol.c b/server/protocol.c
index 8df5ed5..89fbdfa 100644
--- a/server/protocol.c
+++ b/server/protocol.c
@@ -367,7 +367,7 @@ send_simple_reply (struct connection *conn,
uint32_t error)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->write_lock);
- struct simple_reply reply;
+ struct nbd_simple_reply reply;
int r;
int f = (cmd == NBD_CMD_READ && !error) ? SEND_MORE : 0;
@@ -404,8 +404,8 @@ send_structured_reply_read (struct connection *conn,
* that yet we acquire the lock for the whole function.
*/
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->write_lock);
- struct structured_reply reply;
- struct structured_reply_offset_data offset_data;
+ struct nbd_structured_reply reply;
+ struct nbd_structured_reply_offset_data offset_data;
int r;
assert (cmd == NBD_CMD_READ);
@@ -442,7 +442,7 @@ send_structured_reply_read (struct connection *conn,
/* Convert a list of extents into NBD_REPLY_TYPE_BLOCK_STATUS blocks.
* The rules here are very complicated. Read the spec carefully!
*/
-static struct block_descriptor *
+static struct nbd_block_descriptor *
extents_to_block_descriptors (struct nbdkit_extents *extents,
uint16_t flags,
uint32_t count, uint64_t offset,
@@ -451,13 +451,14 @@ extents_to_block_descriptors (struct nbdkit_extents *extents,
const bool req_one = flags & NBD_CMD_FLAG_REQ_ONE;
const size_t nr_extents = nbdkit_extents_count (extents);
size_t i;
- struct block_descriptor *blocks;
+ struct nbd_block_descriptor *blocks;
/* This is checked in server/plugins.c. */
assert (nr_extents >= 1);
/* We may send fewer than nr_extents blocks, but never more. */
- blocks = calloc (req_one ? 1 : nr_extents, sizeof (struct block_descriptor));
+ blocks = calloc (req_one ? 1 : nr_extents,
+ sizeof (struct nbd_block_descriptor));
if (blocks == NULL) {
nbdkit_error ("calloc: %m");
return NULL;
@@ -528,8 +529,8 @@ send_structured_reply_block_status (struct connection *conn,
struct nbdkit_extents *extents)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->write_lock);
- struct structured_reply reply;
- CLEANUP_FREE struct block_descriptor *blocks = NULL;
+ struct nbd_structured_reply reply;
+ CLEANUP_FREE struct nbd_block_descriptor *blocks = NULL;
size_t nr_blocks;
uint32_t context_id;
size_t i;
@@ -548,7 +549,7 @@ send_structured_reply_block_status (struct connection *conn,
reply.flags = htobe16 (NBD_REPLY_FLAG_DONE);
reply.type = htobe16 (NBD_REPLY_TYPE_BLOCK_STATUS);
reply.length = htobe32 (sizeof context_id +
- nr_blocks * sizeof (struct block_descriptor));
+ nr_blocks * sizeof (struct nbd_block_descriptor));
r = conn->send (conn, &reply, sizeof reply, SEND_MORE);
if (r == -1) {
@@ -583,8 +584,8 @@ send_structured_reply_error (struct connection *conn,
uint32_t error)
{
ACQUIRE_LOCK_FOR_CURRENT_SCOPE (&conn->write_lock);
- struct structured_reply reply;
- struct structured_reply_error error_data;
+ struct nbd_structured_reply reply;
+ struct nbd_structured_reply_error error_data;
int r;
reply.magic = htobe32 (NBD_STRUCTURED_REPLY_MAGIC);
@@ -616,7 +617,7 @@ int
protocol_recv_request_send_reply (struct connection *conn)
{
int r;
- struct request request;
+ struct nbd_request request;
uint16_t cmd, flags;
uint32_t magic, count, error = 0;
uint64_t offset;
diff --git a/tests/test-layers.c b/tests/test-layers.c
index 1097f15..e82cbea 100644
--- a/tests/test-layers.c
+++ b/tests/test-layers.c
@@ -86,13 +86,13 @@ main (int argc, char *argv[])
int err;
pthread_t thread;
int sock;
- struct new_handshake handshake;
+ struct nbd_new_handshake handshake;
uint32_t cflags;
- struct new_option option;
- struct new_handshake_finish handshake_finish;
+ struct nbd_new_option option;
+ struct nbd_new_handshake_finish handshake_finish;
uint16_t eflags;
- struct request request;
- struct simple_reply reply;
+ struct nbd_request request;
+ struct nbd_simple_reply reply;
char data[512];
#ifndef HAVE_EXIT_WITH_PARENT
@@ -175,7 +175,7 @@ main (int argc, char *argv[])
exit (EXIT_FAILURE);
}
if (memcmp (handshake.nbdmagic, "NBDMAGIC", 8) != 0 ||
- be64toh (handshake.version) != NEW_VERSION) {
+ be64toh (handshake.version) != NBD_NEW_VERSION) {
fprintf (stderr, "%s: unexpected NBDMAGIC or version\n",
program_name);
exit (EXIT_FAILURE);
@@ -189,7 +189,7 @@ main (int argc, char *argv[])
}
/* Send NBD_OPT_EXPORT_NAME with no export name. */
- option.version = htobe64 (NEW_VERSION);
+ option.version = htobe64 (NBD_NEW_VERSION);
option.option = htobe32 (NBD_OPT_EXPORT_NAME);
option.optlen = htobe32 (0);
if (send (sock, &option, sizeof option, 0) != sizeof option) {
--
2.23.0