qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PATCH 08/15] nbd: make server compliant with fixed newstyl


From: Daniel P. Berrange
Subject: [Qemu-block] [PATCH 08/15] nbd: make server compliant with fixed newstyle spec
Date: Fri, 27 Nov 2015 12:20:46 +0000

If the client does not request the fixed new style protocol,
then we should only accept NBD_OPT_EXPORT_NAME. All other
options are only valid when fixed new style has been activated.

The qemu-nbd client doesn't currently request fixed new style
protocol, but this change won't break qemu-nbd, because it
fortunately only ever uses NBD_OPT_EXPORT_NAME, so was never
triggering the non-compliant server behaviour.

Signed-off-by: Daniel P. Berrange <address@hidden>
---
 nbd.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 45 insertions(+), 23 deletions(-)

diff --git a/nbd.c b/nbd.c
index bdfc45e..09a32a9 100644
--- a/nbd.c
+++ b/nbd.c
@@ -486,6 +486,7 @@ static int nbd_receive_options(NBDClient *client)
 {
     QIOChannel *ioc = client->ioc;
     uint32_t flags;
+    bool fixedNewstyle = false;
 
     /* Client sends:
         [ 0 ..   3]   client flags
@@ -507,14 +508,19 @@ static int nbd_receive_options(NBDClient *client)
     }
     TRACE("Checking client flags");
     be32_to_cpus(&flags);
-    if (flags != 0 && flags != NBD_FLAG_C_FIXED_NEWSTYLE) {
-        LOG("Bad client flags received");
+    if (flags & NBD_FLAG_C_FIXED_NEWSTYLE) {
+        TRACE("Support supports fixed newstyle handshake");
+        fixedNewstyle = true;
+        flags &= ~NBD_FLAG_C_FIXED_NEWSTYLE;
+    }
+    if (flags != 0) {
+        TRACE("Unknown client flags 0x%x received", flags);
         return -EIO;
     }
 
     while (1) {
         int ret;
-        uint32_t tmp, length;
+        uint32_t clientflags, length;
         uint64_t magic;
 
         if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) {
@@ -527,10 +533,12 @@ static int nbd_receive_options(NBDClient *client)
             return -EINVAL;
         }
 
-        if (read_sync(ioc, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+        if (read_sync(ioc, &clientflags, sizeof(clientflags)) !=
+            sizeof(clientflags)) {
             LOG("read failed");
             return -EINVAL;
         }
+        clientflags = be32_to_cpu(clientflags);
 
         if (read_sync(ioc, &length, sizeof(length)) != sizeof(length)) {
             LOG("read failed");
@@ -538,26 +546,40 @@ static int nbd_receive_options(NBDClient *client)
         }
         length = be32_to_cpu(length);
 
-        TRACE("Checking option");
-        switch (be32_to_cpu(tmp)) {
-        case NBD_OPT_LIST:
-            ret = nbd_handle_list(client, length);
-            if (ret < 0) {
-                return ret;
+        TRACE("Checking option 0x%x", clientflags);
+        if (fixedNewstyle) {
+            switch (clientflags) {
+            case NBD_OPT_LIST:
+                ret = nbd_handle_list(client, length);
+                if (ret < 0) {
+                    return ret;
+                }
+                break;
+
+            case NBD_OPT_ABORT:
+                return -EINVAL;
+
+            case NBD_OPT_EXPORT_NAME:
+                return nbd_handle_export_name(client, length);
+
+            default:
+                TRACE("Unsupported option 0x%x", clientflags);
+                nbd_send_rep(client->ioc, NBD_REP_ERR_UNSUP, clientflags);
+                return -EINVAL;
+            }
+        } else {
+            /*
+             * If broken new-style we should drop the connection
+             * for anything except NBD_OPT_EXPORT_NAME
+             */
+            switch (clientflags) {
+            case NBD_OPT_EXPORT_NAME:
+                return nbd_handle_export_name(client, length);
+
+            default:
+                TRACE("Unsupported option 0x%x", clientflags);
+                return -EINVAL;
             }
-            break;
-
-        case NBD_OPT_ABORT:
-            return -EINVAL;
-
-        case NBD_OPT_EXPORT_NAME:
-            return nbd_handle_export_name(client, length);
-
-        default:
-            tmp = be32_to_cpu(tmp);
-            LOG("Unsupported option 0x%x", tmp);
-            nbd_send_rep(client->ioc, NBD_REP_ERR_UNSUP, tmp);
-            return -EINVAL;
         }
     }
 }
-- 
2.5.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]