|
|
7711c0 |
From eead0dbc83d4f8e8da21017976a353c513c3b2b3 Mon Sep 17 00:00:00 2001
|
|
|
7711c0 |
From: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Date: Wed, 27 Mar 2019 17:22:46 +0100
|
|
|
7711c0 |
Subject: [PATCH 108/163] nbd/client: Split out nbd_receive_one_meta_context()
|
|
|
7711c0 |
|
|
|
7711c0 |
RH-Author: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Message-id: <20190327172308.31077-34-jsnow@redhat.com>
|
|
|
7711c0 |
Patchwork-id: 85193
|
|
|
7711c0 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 33/55] nbd/client: Split out nbd_receive_one_meta_context()
|
|
|
7711c0 |
Bugzilla: 1691009
|
|
|
7711c0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
From: Eric Blake <eblake@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
Extract portions of nbd_negotiate_simple_meta_context() to
|
|
|
7711c0 |
a new function nbd_receive_one_meta_context() that copies the
|
|
|
7711c0 |
pattern of nbd_receive_list() for performing the argument
|
|
|
7711c0 |
validation of one reply. The error message when the server
|
|
|
7711c0 |
replies with more than one context changes slightly, but
|
|
|
7711c0 |
that shouldn't happen in the common case.
|
|
|
7711c0 |
|
|
|
7711c0 |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
7711c0 |
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
Message-Id: <20190117193658.16413-13-eblake@redhat.com>
|
|
|
7711c0 |
(cherry picked from commit 0182c1aed9e6a9314023c7264c5c264da2f4a4ce)
|
|
|
7711c0 |
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
---
|
|
|
7711c0 |
nbd/client.c | 147 ++++++++++++++++++++++++++++++++++---------------------
|
|
|
7711c0 |
nbd/trace-events | 2 +-
|
|
|
7711c0 |
2 files changed, 91 insertions(+), 58 deletions(-)
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/nbd/client.c b/nbd/client.c
|
|
|
7711c0 |
index 96da68e..c7bb708 100644
|
|
|
7711c0 |
--- a/nbd/client.c
|
|
|
7711c0 |
+++ b/nbd/client.c
|
|
|
7711c0 |
@@ -669,7 +669,86 @@ static int nbd_send_meta_query(QIOChannel *ioc, uint32_t opt,
|
|
|
7711c0 |
return ret;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
-/* nbd_negotiate_simple_meta_context:
|
|
|
7711c0 |
+/*
|
|
|
7711c0 |
+ * nbd_receive_one_meta_context:
|
|
|
7711c0 |
+ * Called in a loop to receive and trace one set/list meta context reply.
|
|
|
7711c0 |
+ * Pass non-NULL @name or @id to collect results back to the caller, which
|
|
|
7711c0 |
+ * must eventually call g_free().
|
|
|
7711c0 |
+ * return 1 if name is set and iteration must continue,
|
|
|
7711c0 |
+ * 0 if iteration is complete (including if option is unsupported),
|
|
|
7711c0 |
+ * -1 with errp set for any error
|
|
|
7711c0 |
+ */
|
|
|
7711c0 |
+static int nbd_receive_one_meta_context(QIOChannel *ioc,
|
|
|
7711c0 |
+ uint32_t opt,
|
|
|
7711c0 |
+ char **name,
|
|
|
7711c0 |
+ uint32_t *id,
|
|
|
7711c0 |
+ Error **errp)
|
|
|
7711c0 |
+{
|
|
|
7711c0 |
+ int ret;
|
|
|
7711c0 |
+ NBDOptionReply reply;
|
|
|
7711c0 |
+ char *local_name = NULL;
|
|
|
7711c0 |
+ uint32_t local_id;
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (nbd_receive_option_reply(ioc, opt, &reply, errp) < 0) {
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ ret = nbd_handle_reply_err(ioc, &reply, errp);
|
|
|
7711c0 |
+ if (ret <= 0) {
|
|
|
7711c0 |
+ return ret;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (reply.type == NBD_REP_ACK) {
|
|
|
7711c0 |
+ if (reply.length != 0) {
|
|
|
7711c0 |
+ error_setg(errp, "Unexpected length to ACK response");
|
|
|
7711c0 |
+ nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ return 0;
|
|
|
7711c0 |
+ } else if (reply.type != NBD_REP_META_CONTEXT) {
|
|
|
7711c0 |
+ error_setg(errp, "Unexpected reply type %u (%s), expected %u (%s)",
|
|
|
7711c0 |
+ reply.type, nbd_rep_lookup(reply.type),
|
|
|
7711c0 |
+ NBD_REP_META_CONTEXT, nbd_rep_lookup(NBD_REP_META_CONTEXT));
|
|
|
7711c0 |
+ nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (reply.length <= sizeof(local_id) ||
|
|
|
7711c0 |
+ reply.length > NBD_MAX_BUFFER_SIZE) {
|
|
|
7711c0 |
+ error_setg(errp, "Failed to negotiate meta context, server "
|
|
|
7711c0 |
+ "answered with unexpected length %" PRIu32,
|
|
|
7711c0 |
+ reply.length);
|
|
|
7711c0 |
+ nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (nbd_read(ioc, &local_id, sizeof(local_id), errp) < 0) {
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ local_id = be32_to_cpu(local_id);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ reply.length -= sizeof(local_id);
|
|
|
7711c0 |
+ local_name = g_malloc(reply.length + 1);
|
|
|
7711c0 |
+ if (nbd_read(ioc, local_name, reply.length, errp) < 0) {
|
|
|
7711c0 |
+ g_free(local_name);
|
|
|
7711c0 |
+ return -1;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ local_name[reply.length] = '\0';
|
|
|
7711c0 |
+ trace_nbd_opt_meta_reply(nbd_opt_lookup(opt), local_name, local_id);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ if (name) {
|
|
|
7711c0 |
+ *name = local_name;
|
|
|
7711c0 |
+ } else {
|
|
|
7711c0 |
+ g_free(local_name);
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ if (id) {
|
|
|
7711c0 |
+ *id = local_id;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+ return 1;
|
|
|
7711c0 |
+}
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+/*
|
|
|
7711c0 |
+ * nbd_negotiate_simple_meta_context:
|
|
|
7711c0 |
* Request the server to set the meta context for export @info->name
|
|
|
7711c0 |
* using @info->x_dirty_bitmap with a fallback to "base:allocation",
|
|
|
7711c0 |
* setting @info->context_id to the resulting id. Fail if the server
|
|
|
7711c0 |
@@ -690,50 +769,21 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
|
|
|
7711c0 |
* function should lose the term _simple.
|
|
|
7711c0 |
*/
|
|
|
7711c0 |
int ret;
|
|
|
7711c0 |
- NBDOptionReply reply;
|
|
|
7711c0 |
const char *context = info->x_dirty_bitmap ?: "base:allocation";
|
|
|
7711c0 |
bool received = false;
|
|
|
7711c0 |
+ char *name = NULL;
|
|
|
7711c0 |
|
|
|
7711c0 |
if (nbd_send_meta_query(ioc, NBD_OPT_SET_META_CONTEXT,
|
|
|
7711c0 |
info->name, context, errp) < 0) {
|
|
|
7711c0 |
return -1;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply,
|
|
|
7711c0 |
- errp) < 0)
|
|
|
7711c0 |
- {
|
|
|
7711c0 |
+ ret = nbd_receive_one_meta_context(ioc, NBD_OPT_SET_META_CONTEXT,
|
|
|
7711c0 |
+ &name, &info->context_id, errp);
|
|
|
7711c0 |
+ if (ret < 0) {
|
|
|
7711c0 |
return -1;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- ret = nbd_handle_reply_err(ioc, &reply, errp);
|
|
|
7711c0 |
- if (ret <= 0) {
|
|
|
7711c0 |
- return ret;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- if (reply.type == NBD_REP_META_CONTEXT) {
|
|
|
7711c0 |
- char *name;
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- if (reply.length != sizeof(info->context_id) + strlen(context)) {
|
|
|
7711c0 |
- error_setg(errp, "Failed to negotiate meta context '%s', server "
|
|
|
7711c0 |
- "answered with unexpected length %" PRIu32, context,
|
|
|
7711c0 |
- reply.length);
|
|
|
7711c0 |
- nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
- return -1;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- if (nbd_read(ioc, &info->context_id, sizeof(info->context_id),
|
|
|
7711c0 |
- errp) < 0) {
|
|
|
7711c0 |
- return -1;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
- info->context_id = be32_to_cpu(info->context_id);
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- reply.length -= sizeof(info->context_id);
|
|
|
7711c0 |
- name = g_malloc(reply.length + 1);
|
|
|
7711c0 |
- if (nbd_read(ioc, name, reply.length, errp) < 0) {
|
|
|
7711c0 |
- g_free(name);
|
|
|
7711c0 |
- return -1;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
- name[reply.length] = '\0';
|
|
|
7711c0 |
+ if (ret == 1) {
|
|
|
7711c0 |
if (strcmp(context, name)) {
|
|
|
7711c0 |
error_setg(errp, "Failed to negotiate meta context '%s', server "
|
|
|
7711c0 |
"answered with different context '%s'", context,
|
|
|
7711c0 |
@@ -743,36 +793,19 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
|
|
|
7711c0 |
return -1;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
g_free(name);
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- trace_nbd_opt_meta_reply(context, info->context_id);
|
|
|
7711c0 |
received = true;
|
|
|
7711c0 |
|
|
|
7711c0 |
- /* receive NBD_REP_ACK */
|
|
|
7711c0 |
- if (nbd_receive_option_reply(ioc, NBD_OPT_SET_META_CONTEXT, &reply,
|
|
|
7711c0 |
- errp) < 0)
|
|
|
7711c0 |
- {
|
|
|
7711c0 |
+ ret = nbd_receive_one_meta_context(ioc, NBD_OPT_SET_META_CONTEXT,
|
|
|
7711c0 |
+ NULL, NULL, errp);
|
|
|
7711c0 |
+ if (ret < 0) {
|
|
|
7711c0 |
return -1;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- ret = nbd_handle_reply_err(ioc, &reply, errp);
|
|
|
7711c0 |
- if (ret <= 0) {
|
|
|
7711c0 |
- return ret;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
}
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- if (reply.type != NBD_REP_ACK) {
|
|
|
7711c0 |
- error_setg(errp, "Unexpected reply type %u (%s), expected %u (%s)",
|
|
|
7711c0 |
- reply.type, nbd_rep_lookup(reply.type),
|
|
|
7711c0 |
- NBD_REP_ACK, nbd_rep_lookup(NBD_REP_ACK));
|
|
|
7711c0 |
+ if (ret != 0) {
|
|
|
7711c0 |
+ error_setg(errp, "Server answered with more than one context");
|
|
|
7711c0 |
nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
return -1;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
- if (reply.length) {
|
|
|
7711c0 |
- error_setg(errp, "Unexpected length to ACK response");
|
|
|
7711c0 |
- nbd_send_opt_abort(ioc);
|
|
|
7711c0 |
- return -1;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
-
|
|
|
7711c0 |
return received;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/nbd/trace-events b/nbd/trace-events
|
|
|
7711c0 |
index 59521e4..b4802c1 100644
|
|
|
7711c0 |
--- a/nbd/trace-events
|
|
|
7711c0 |
+++ b/nbd/trace-events
|
|
|
7711c0 |
@@ -13,7 +13,7 @@ nbd_receive_query_exports_success(const char *wantname) "Found desired export na
|
|
|
7711c0 |
nbd_receive_starttls_new_client(void) "Setting up TLS"
|
|
|
7711c0 |
nbd_receive_starttls_tls_handshake(void) "Starting TLS handshake"
|
|
|
7711c0 |
nbd_opt_meta_request(const char *optname, const char *context, const char *export) "Requesting %s %s for export %s"
|
|
|
7711c0 |
-nbd_opt_meta_reply(const char *context, uint32_t id) "Received mapping of context %s to id %" PRIu32
|
|
|
7711c0 |
+nbd_opt_meta_reply(const char *optname, const char *context, uint32_t id) "Received %s mapping of %s to id %" PRIu32
|
|
|
7711c0 |
nbd_receive_negotiate(void *tlscreds, const char *hostname) "Receiving negotiation tlscreds=%p hostname=%s"
|
|
|
7711c0 |
nbd_receive_negotiate_magic(uint64_t magic) "Magic is 0x%" PRIx64
|
|
|
7711c0 |
nbd_receive_negotiate_server_flags(uint32_t globalflags) "Global flags are 0x%" PRIx32
|
|
|
7711c0 |
--
|
|
|
7711c0 |
1.8.3.1
|
|
|
7711c0 |
|