If we tried NBD_OPT_SET_META_CONTEXT, and the NBD server rejected our
attempt with an error message, then we should capture (or skip) that
message off the wire in order to go on without base:allocation, the
same as if the server had not sent a message. This requires a new
state.
---
generator/generator | 7 +++++++
.../states-newstyle-opt-set-meta-context.c | 21 ++++++++++++-------
2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/generator/generator b/generator/generator
index 3faa272..4d42185 100755
--- a/generator/generator
+++ b/generator/generator
@@ -491,6 +491,13 @@ and newstyle_opt_set_meta_context_state_machine = [
external_events = [ NotifyRead, "" ];
};
+ State {
+ default_state with
+ name = "RECV_SKIP_PAYLOAD";
+ comment = "Ignore newstyle NBD_OPT_SET_META_CONTEXT option reply payload";
+ external_events = [ NotifyRead, "" ];
+ };
+
State {
default_state with
name = "FINISH";
diff --git a/generator/states-newstyle-opt-set-meta-context.c
b/generator/states-newstyle-opt-set-meta-context.c
index 5a445b2..b815701 100644
--- a/generator/states-newstyle-opt-set-meta-context.c
+++ b/generator/states-newstyle-opt-set-meta-context.c
@@ -150,14 +150,11 @@ const char base_allocation[] = "base:allocation";
SET_NEXT_STATE (%RECV_REPLY_PAYLOAD);
break;
default:
- /* Anything else is an error, ignore it if the len == 0. */
- if (len != 0) {
- /* We could probably recover from this with some effort. */
- SET_NEXT_STATE (%.DEAD);
- set_error (0, "handshake: unknown option reply (%" PRIu32
")", reply);
- return -1;
- }
- SET_NEXT_STATE (%FINISH);
+ /* Anything else is an error, ignore it */
+ debug (conn->h, "base:allocation is not supported by this server");
+ conn->rbuf = NULL;
+ conn->rlen = len;
+ SET_NEXT_STATE (%RECV_SKIP_PAYLOAD);
}
}
return 0;
@@ -181,6 +178,14 @@ const char base_allocation[] = "base:allocation";
}
return 0;
+ NEWSTYLE.OPT_SET_META_CONTEXT.RECV_SKIP_PAYLOAD:
+ switch (recv_into_rbuf (conn)) {
+ case -1: SET_NEXT_STATE (%.DEAD); return -1;
+ case 0: SET_NEXT_STATE (%FINISH);
+ /* XXX: capture instead of skip server's payload to NBD_REP_ERR*? */
+ }
+ return 0;
+
NEWSTYLE.OPT_SET_META_CONTEXT.FINISH:
/* Jump to the next option. */
SET_NEXT_STATE (%^OPT_GO.START);
--
2.20.1