aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/nbd-client.c4
-rw-r--r--include/block/nbd.h2
-rw-r--r--nbd/client.c53
3 files changed, 28 insertions, 31 deletions
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 3309376bc1..813539676d 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -249,11 +249,11 @@ static int nbd_parse_blockstatus_payload(NBDClientSession *client,
}
context_id = payload_advance32(&payload);
- if (client->info.meta_base_allocation_id != context_id) {
+ if (client->info.context_id != context_id) {
error_setg(errp, "Protocol error: unexpected context id %d for "
"NBD_REPLY_TYPE_BLOCK_STATUS, when negotiated context "
"id is %d", context_id,
- client->info.meta_base_allocation_id);
+ client->info.context_id);
return -EINVAL;
}
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 00d3eb57d9..be19aac2fc 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -276,7 +276,7 @@ struct NBDExportInfo {
uint32_t opt_block;
uint32_t max_block;
- uint32_t meta_base_allocation_id;
+ uint32_t context_id;
};
typedef struct NBDExportInfo NBDExportInfo;
diff --git a/nbd/client.c b/nbd/client.c
index 8227e69478..77993890f0 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -630,26 +630,30 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
}
/* nbd_negotiate_simple_meta_context:
- * Set one meta context. Simple means that reply must contain zero (not
- * negotiated) or one (negotiated) contexts. More contexts would be considered
- * as a protocol error. It's also implied that meta-data query equals queried
- * context name, so, if server replies with something different than @context,
- * it is considered an error too.
- * return 1 for successful negotiation, context_id is set
+ * Request the server to set the meta context for export @info->name
+ * using @info->x_dirty_bitmap with a fallback to "base:allocation",
+ * setting @info->context_id to the resulting id. Fail if the server
+ * responds with more than one context or with a context different
+ * than the query.
+ * return 1 for successful negotiation,
* 0 if operation is unsupported,
* -1 with errp set for any other error
*/
static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
- const char *export,
- const char *context,
- uint32_t *context_id,
+ NBDExportInfo *info,
Error **errp)
{
+ /*
+ * TODO: Removing the x_dirty_bitmap hack will mean refactoring
+ * this function to request and store ids for multiple contexts
+ * (both base:allocation and a dirty bitmap), at which point this
+ * function should lose the term _simple.
+ */
int ret;
NBDOptionReply reply;
- uint32_t received_id = 0;
+ const char *context = info->x_dirty_bitmap ?: "base:allocation";
bool received = false;
- uint32_t export_len = strlen(export);
+ uint32_t export_len = strlen(info->name);
uint32_t context_len = strlen(context);
uint32_t data_len = sizeof(export_len) + export_len +
sizeof(uint32_t) + /* number of queries */
@@ -657,9 +661,9 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
char *data = g_malloc(data_len);
char *p = data;
- trace_nbd_opt_meta_request(context, export);
+ trace_nbd_opt_meta_request(context, info->name);
stl_be_p(p, export_len);
- memcpy(p += sizeof(export_len), export, export_len);
+ memcpy(p += sizeof(export_len), info->name, export_len);
stl_be_p(p += export_len, 1);
stl_be_p(p += sizeof(uint32_t), context_len);
memcpy(p += sizeof(context_len), context, context_len);
@@ -685,7 +689,7 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
if (reply.type == NBD_REP_META_CONTEXT) {
char *name;
- if (reply.length != sizeof(received_id) + context_len) {
+ if (reply.length != sizeof(info->context_id) + context_len) {
error_setg(errp, "Failed to negotiate meta context '%s', server "
"answered with unexpected length %" PRIu32, context,
reply.length);
@@ -693,12 +697,13 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
return -1;
}
- if (nbd_read(ioc, &received_id, sizeof(received_id), errp) < 0) {
+ if (nbd_read(ioc, &info->context_id, sizeof(info->context_id),
+ errp) < 0) {
return -1;
}
- received_id = be32_to_cpu(received_id);
+ info->context_id = be32_to_cpu(info->context_id);
- reply.length -= sizeof(received_id);
+ reply.length -= sizeof(info->context_id);
name = g_malloc(reply.length + 1);
if (nbd_read(ioc, name, reply.length, errp) < 0) {
g_free(name);
@@ -715,7 +720,7 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
}
g_free(name);
- trace_nbd_opt_meta_reply(context, received_id);
+ trace_nbd_opt_meta_reply(context, info->context_id);
received = true;
/* receive NBD_REP_ACK */
@@ -744,12 +749,7 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
return -1;
}
- if (received) {
- *context_id = received_id;
- return 1;
- }
-
- return 0;
+ return received;
}
int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
@@ -848,10 +848,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
}
if (info->structured_reply && base_allocation) {
- result = nbd_negotiate_simple_meta_context(
- ioc, info->name,
- info->x_dirty_bitmap ?: "base:allocation",
- &info->meta_base_allocation_id, errp);
+ result = nbd_negotiate_simple_meta_context(ioc, info, errp);
if (result < 0) {
goto fail;
}