c401cc
From fc5386bf423e746c5263060032f0385424e6db25 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <fc5386bf423e746c5263060032f0385424e6db25@dist-git>
c401cc
From: Peter Krempa <pkrempa@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:54:59 +0100
c401cc
Subject: [PATCH] qemu: Split out NBD command generation
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
(cherry picked from commit d94fd0c9c245ca30b1c70a9bb854e81ee5ab37da)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_command.c | 117 +++++++++++++++++++++++++-----------------------
c401cc
 1 file changed, 61 insertions(+), 56 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
c401cc
index f45b681..c1dab06 100644
c401cc
--- a/src/qemu/qemu_command.c
c401cc
+++ b/src/qemu/qemu_command.c
c401cc
@@ -3586,7 +3586,7 @@ qemuNetworkDriveGetPort(int protocol,
c401cc
     return -1;
c401cc
 }
c401cc
 
c401cc
-
c401cc
+#define QEMU_DEFAULT_NBD_PORT "10809"
c401cc
 
c401cc
 char *
c401cc
 qemuBuildNetworkDriveURI(int protocol,
c401cc
@@ -3597,12 +3597,69 @@ qemuBuildNetworkDriveURI(int protocol,
c401cc
                          const char *secret)
c401cc
 {
c401cc
     char *ret = NULL;
c401cc
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
c401cc
     virURIPtr uri = NULL;
c401cc
 
c401cc
     switch ((enum virDomainDiskProtocol) protocol) {
c401cc
+        case VIR_DOMAIN_DISK_PROTOCOL_NBD:
c401cc
+            if (nhosts != 1) {
c401cc
+                virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                               _("protocol '%s' accepts only one host"),
c401cc
+                               virDomainDiskProtocolTypeToString(protocol));
c401cc
+                goto cleanup;
c401cc
+            }
c401cc
+
c401cc
+            if (!((hosts->name && strchr(hosts->name, ':')) ||
c401cc
+                  (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP &&
c401cc
+                   !hosts->name) ||
c401cc
+                  (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX &&
c401cc
+                   hosts->socket &&
c401cc
+                   hosts->socket[0] != '/'))) {
c401cc
+
c401cc
+                virBufferAddLit(&buf, "nbd:");
c401cc
+
c401cc
+                switch (hosts->transport) {
c401cc
+                case VIR_DOMAIN_DISK_PROTO_TRANS_TCP:
c401cc
+                    virBufferStrcat(&buf, hosts->name, NULL);
c401cc
+                    virBufferAsprintf(&buf, ":%s",
c401cc
+                                      hosts->port ? hosts->port :
c401cc
+                                      QEMU_DEFAULT_NBD_PORT);
c401cc
+                    break;
c401cc
+
c401cc
+                case VIR_DOMAIN_DISK_PROTO_TRANS_UNIX:
c401cc
+                    if (!hosts->socket) {
c401cc
+                        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
c401cc
+                                       _("socket attribute required for "
c401cc
+                                         "unix transport"));
c401cc
+                        goto cleanup;
c401cc
+                    }
c401cc
+
c401cc
+                    virBufferAsprintf(&buf, "unix:%s", hosts->socket);
c401cc
+                    break;
c401cc
+
c401cc
+                default:
c401cc
+                    virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                                   _("nbd does not support transport '%s'"),
c401cc
+                                   virDomainDiskProtocolTransportTypeToString(hosts->transport));
c401cc
+                    goto cleanup;
c401cc
+                }
c401cc
+
c401cc
+                if (src)
c401cc
+                    virBufferAsprintf(&buf, ":exportname=%s", src);
c401cc
+
c401cc
+                if (virBufferError(&buf) < 0) {
c401cc
+                    virReportOOMError();
c401cc
+                    goto cleanup;
c401cc
+                }
c401cc
+
c401cc
+                ret = virBufferContentAndReset(&buf;;
c401cc
+                goto cleanup;
c401cc
+            }
c401cc
+            /* fallthrough */
c401cc
+            /* NBD code uses same formatting scheme as others in some cases */
c401cc
+
c401cc
         case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
c401cc
         case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
c401cc
-        case VIR_DOMAIN_DISK_PROTOCOL_NBD:
c401cc
             if (nhosts != 1) {
c401cc
                 virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
                                _("protocol '%s' accepts only one host"),
c401cc
@@ -3687,6 +3744,7 @@ qemuBuildNetworkDriveURI(int protocol,
c401cc
     }
c401cc
 
c401cc
 cleanup:
c401cc
+    virBufferFreeAndReset(&buf;;
c401cc
     virURIFree(uri);
c401cc
 
c401cc
     return ret;
c401cc
@@ -3740,56 +3798,6 @@ cleanup:
c401cc
 }
c401cc
 
c401cc
 
c401cc
-#define QEMU_DEFAULT_NBD_PORT "10809"
c401cc
-
c401cc
-static int
c401cc
-qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
c401cc
-{
c401cc
-    const char *transp;
c401cc
-
c401cc
-    if (disk->nhosts != 1) {
c401cc
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
c401cc
-                       _("nbd accepts only one host"));
c401cc
-        return -1;
c401cc
-    }
c401cc
-
c401cc
-    if ((disk->hosts->name && strchr(disk->hosts->name, ':')) ||
c401cc
-        (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP && !disk->hosts->name) ||
c401cc
-        (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX && disk->hosts->socket && disk->hosts->socket[0] != '/'))
c401cc
-        return qemuBuildDriveURIString(conn, disk, opt);
c401cc
-
c401cc
-    virBufferAddLit(opt, "file=nbd:");
c401cc
-
c401cc
-    switch (disk->hosts->transport) {
c401cc
-    case VIR_DOMAIN_DISK_PROTO_TRANS_TCP:
c401cc
-        if (disk->hosts->name)
c401cc
-            virBufferEscape(opt, ',', ",", "%s", disk->hosts->name);
c401cc
-        virBufferEscape(opt, ',', ",", ":%s",
c401cc
-                        disk->hosts->port ? disk->hosts->port :
c401cc
-                        QEMU_DEFAULT_NBD_PORT);
c401cc
-        break;
c401cc
-    case VIR_DOMAIN_DISK_PROTO_TRANS_UNIX:
c401cc
-        if (!disk->hosts->socket) {
c401cc
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
c401cc
-                           _("socket attribute required for unix transport"));
c401cc
-            return -1;
c401cc
-        }
c401cc
-        virBufferEscape(opt, ',', ",", "unix:%s", disk->hosts->socket);
c401cc
-        break;
c401cc
-    default:
c401cc
-        transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
c401cc
-        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
-                       _("nbd does not support transport '%s'"), transp);
c401cc
-        break;
c401cc
-    }
c401cc
-
c401cc
-    if (disk->src)
c401cc
-        virBufferEscape(opt, ',', ",", ":exportname=%s", disk->src);
c401cc
-
c401cc
-    virBufferAddChar(opt, ',');
c401cc
-
c401cc
-    return 0;
c401cc
-}
c401cc
 
c401cc
 
c401cc
 char *
c401cc
@@ -3912,10 +3920,6 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
                 virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
c401cc
         } else if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK) {
c401cc
             switch (disk->protocol) {
c401cc
-            case VIR_DOMAIN_DISK_PROTOCOL_NBD:
c401cc
-                if (qemuBuildNBDString(conn, disk, &opt) < 0)
c401cc
-                    goto error;
c401cc
-                break;
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_RBD:
c401cc
                 virBufferAddLit(&opt, "file=");
c401cc
                 if (qemuBuildRBDString(conn, disk, &opt) < 0)
c401cc
@@ -3923,6 +3927,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
                 virBufferAddChar(&opt, ',');
c401cc
                 break;
c401cc
 
c401cc
+            case VIR_DOMAIN_DISK_PROTOCOL_NBD:
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_SHEEPDOG:
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
c401cc
-- 
c401cc
1.9.0
c401cc