I'm easily able to provoke NBD_REP_ERR_TLS_REQD (use nbd_set_tls(0) to
talk to a server that requires encryption) and NBD_REP_ERR_UNKNOWN
(forget to use nbd_set_export_name for qemu-nbd); it's nice to display
a useful error for these rather than "unknown reply from NBD_OPT_GO:
0x80000005" or similar. Other errors are less common, but as long as
we're decoding things, it doesn't hurt to decode everything in the
protocol.
---
I'm pushing this one now (I mentioned it on IRC earlier today).
generator/states-newstyle-opt-go.c | 32 +++++++++++++++++++++++++++---
lib/nbd-protocol.h | 22 +++++++++++---------
2 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/generator/states-newstyle-opt-go.c b/generator/states-newstyle-opt-go.c
index 91a85ef..e245c75 100644
--- a/generator/states-newstyle-opt-go.c
+++ b/generator/states-newstyle-opt-go.c
@@ -147,9 +147,35 @@
SET_NEXT_STATE (%^OPT_EXPORT_NAME.START);
return 0;
default:
- if (handle_reply_error (h) == 0)
- set_error (0, "handshake: unknown reply from NBD_OPT_GO: 0x%" PRIx32,
- reply);
+ if (handle_reply_error (h) == 0) {
+ /* Decode expected known errors into a nicer string */
+ switch (reply) {
+ case NBD_REP_ERR_POLICY:
+ case NBD_REP_ERR_PLATFORM:
+ set_error (0, "handshake: server policy prevents NBD_OPT_GO");
+ break;
+ case NBD_REP_ERR_INVALID:
+ case NBD_REP_ERR_TOO_BIG:
+ set_error (EINVAL, "handshake: server rejected NBD_OPT_GO as
invalid");
+ break;
+ case NBD_REP_ERR_TLS_REQD:
+ set_error (ENOTSUP, "handshake: server requires TLS encryption
first");
+ break;
+ case NBD_REP_ERR_UNKNOWN:
+ set_error (ENOENT, "handshake: server has no export named
'%s'",
+ h->export_name);
+ break;
+ case NBD_REP_ERR_SHUTDOWN:
+ set_error (ESHUTDOWN, "handshake: server is shutting down");
+ break;
+ case NBD_REP_ERR_BLOCK_SIZE_REQD:
+ set_error (EINVAL, "handshake: server requires specific block sizes");
+ break;
+ default:
+ set_error (0, "handshake: unknown reply from NBD_OPT_GO: 0x%" PRIx32,
+ reply);
+ }
+ }
SET_NEXT_STATE (%.DEAD);
return -1;
}
diff --git a/lib/nbd-protocol.h b/lib/nbd-protocol.h
index 405af3e..3e3fb4e 100644
--- a/lib/nbd-protocol.h
+++ b/lib/nbd-protocol.h
@@ -123,15 +123,19 @@ struct nbd_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
--
2.20.1