[Libguestfs] [nbdkit PATCH 1/5] protocol: Support NBD_FLAG_NO_ZEROES

Eric Blake
2017-01-20T20:16:18Z

The upstream NBD protocol allows a reduction in the length of the
handshake by both sides agreeing to skip the 124 bytes of padding
in the final server reply.

Signed-off-by: Eric Blake <eblake@redhat.com>
---
 src/connections.c | 14 +++++++++++---
 src/protocol.h    |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/connections.c b/src/connections.c
index 840e315..16c6584 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <endian.h>
 #include <sys/types.h>
+#include <stddef.h>

 #include <pthread.h>

@@ -390,7 +391,7 @@ _negotiate_handshake_newstyle (struct connection *conn)
   uint16_t eflags;
   int fl;

-  gflags = NBD_FLAG_FIXED_NEWSTYLE;
+  gflags = NBD_FLAG_FIXED_NEWSTYLE | NBD_FLAG_NO_ZEROES;

   debug ("newstyle negotiation: flags: global 0x%x", gflags);

@@ -409,8 +410,12 @@ _negotiate_handshake_newstyle (struct connection *conn)
     return -1;
   }
   cflags = be32toh (cflags);
-  /* ... which other than printing out, we ignore. */
+  /* ... which we check for accuracy. */
   debug ("newstyle negotiation: client flags: 0x%x", cflags);
+  if (cflags & ~gflags) {
+    nbdkit_error ("client requested unknown flags 0x%x", cflags);
+    return -1;
+  }

   /* Receive newstyle options. */
   if (_negotiate_handshake_newstyle_options (conn) == -1)
@@ -469,7 +474,10 @@ _negotiate_handshake_newstyle (struct connection *conn)
   handshake_finish.eflags = htobe16 (eflags);

   if (xwrite (conn->sockout,
-              &handshake_finish, sizeof handshake_finish) == -1) {
+              &handshake_finish,
+	      (cflags & NBD_FLAG_NO_ZEROES)
+	      ? offsetof (struct new_handshake_finish, zeroes)
+	      : sizeof handshake_finish) == -1) {
     nbdkit_error ("write: %m");
     return -1;
   }
diff --git a/src/protocol.h b/src/protocol.h
index c885d9e..23630a9 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -84,6 +84,7 @@ struct new_handshake_finish {

 /* Global flags. */
 #define NBD_FLAG_FIXED_NEWSTYLE 1
+#define NBD_FLAG_NO_ZEROES      2

 /* Per-export flags. */
 #define NBD_FLAG_HAS_FLAGS   1
--
2.9.3