Blame SOURCES/kvm-nbd-client-Split-out-nbd_receive_one_meta_context.patch

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