Eric Blake
2019-Jun-28 01:13 UTC
[Libguestfs] [libnbd PATCH] opt-go: Better decoding of known errors
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
Apparently Analagous Threads
- [PATCH nbdkit 3/4] common/protocol: Update nbd-protocol.h so it matches libnbd’s copy.
- [PATCH nbdkit v2] protocol: Implement NBD_OPT_GO.
- [PATCH nbdkit 2/4] common/protocol: Remove protostrings.sed, use bash+sed instead.
- [PATCH nbdkit 0/4] common/protocol: Unify public <nbd-protocol.h>
- [libnbd PATCH 7/7] states: Capture NBD_REP_ERR message