c401cc
From 55f5ce01a0a43d8f4dabbdcb3fc48b0d3aea7cc3 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <55f5ce01a0a43d8f4dabbdcb3fc48b0d3aea7cc3@dist-git>
c401cc
From: Peter Krempa <pkrempa@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:54:55 +0100
c401cc
Subject: [PATCH] qemu: Split out formatting of network disk source URI
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
The snapshot code will need to use qemu-style formatted URIs of network
c401cc
disks. Split out the code to avoid duplication.
c401cc
c401cc
(cherry picked from commit a29d33ffcb81e78f197b294ce1669b58b926a9d6)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_command.c | 146 ++++++++++++++++++++++++++++--------------------
c401cc
 src/qemu/qemu_command.h |   6 ++
c401cc
 2 files changed, 91 insertions(+), 61 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
c401cc
index 2338b12..da4d2f8 100644
c401cc
--- a/src/qemu/qemu_command.c
c401cc
+++ b/src/qemu/qemu_command.c
c401cc
@@ -3547,106 +3547,125 @@ error:
c401cc
     return -1;
c401cc
 }
c401cc
 
c401cc
-static int
c401cc
-qemuBuildDriveURIString(virConnectPtr conn,
c401cc
-                        virDomainDiskDefPtr disk, virBufferPtr opt,
c401cc
-                        const char *scheme, virSecretUsageType secretUsageType)
c401cc
-{
c401cc
-    int ret = -1;
c401cc
-    int port = 0;
c401cc
-    char *secret = NULL;
c401cc
 
c401cc
-    char *tmpscheme = NULL;
c401cc
-    char *volimg = NULL;
c401cc
-    char *sock = NULL;
c401cc
-    char *user = NULL;
c401cc
-    char *builturi = NULL;
c401cc
-    const char *transp = NULL;
c401cc
-    virURI uri = {
c401cc
-        .port = port /* just to clear rest of bits */
c401cc
-    };
c401cc
+char *
c401cc
+qemuBuildNetworkDriveURI(int protocol,
c401cc
+                         const char *src,
c401cc
+                         size_t nhosts,
c401cc
+                         virDomainDiskHostDefPtr hosts,
c401cc
+                         const char *username,
c401cc
+                         const char *secret)
c401cc
+{
c401cc
+    char *ret = NULL;
c401cc
+    virURIPtr uri = NULL;
c401cc
 
c401cc
-    if (disk->nhosts != 1) {
c401cc
+    if (nhosts != 1) {
c401cc
         virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
-                       _("%s accepts only one host"), scheme);
c401cc
-        return -1;
c401cc
+                       _("protocol '%s' accepts only one host"),
c401cc
+                       virDomainDiskProtocolTypeToString(protocol));
c401cc
+        return NULL;
c401cc
     }
c401cc
 
c401cc
-    virBufferAddLit(opt, "file=");
c401cc
-    transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
c401cc
+    if (VIR_ALLOC(uri) < 0)
c401cc
+        return NULL;
c401cc
 
c401cc
-    if (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
c401cc
-        if (VIR_STRDUP(tmpscheme, scheme) < 0)
c401cc
+    if (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
c401cc
+        if (VIR_STRDUP(uri->scheme, virDomainDiskProtocolTypeToString(protocol)) < 0)
c401cc
             goto cleanup;
c401cc
     } else {
c401cc
-        if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0)
c401cc
+        if (virAsprintf(&uri->scheme, "%s+%s",
c401cc
+                        virDomainDiskProtocolTypeToString(protocol),
c401cc
+                        virDomainDiskProtocolTransportTypeToString(hosts->transport)) < 0)
c401cc
             goto cleanup;
c401cc
     }
c401cc
 
c401cc
-    if (disk->src && virAsprintf(&volimg, "/%s", disk->src) < 0)
c401cc
+    if (src &&
c401cc
+        virAsprintf(&uri->path, "/%s", src) < 0)
c401cc
+        goto cleanup;
c401cc
+
c401cc
+    if (hosts->port &&
c401cc
+        virStrToLong_i(hosts->port, NULL, 10, &uri->port) < 0) {
c401cc
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                       _("failed to parse port number '%s'"),
c401cc
+                       hosts->port);
c401cc
+        goto cleanup;
c401cc
+    }
c401cc
+
c401cc
+    if (hosts->socket &&
c401cc
+        virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
c401cc
         goto cleanup;
c401cc
 
c401cc
-    if (disk->hosts->port) {
c401cc
-        port = atoi(disk->hosts->port);
c401cc
+    if (username) {
c401cc
+        if (secret) {
c401cc
+            if (virAsprintf(&uri->user, "%s:%s", username, secret) < 0)
c401cc
+                goto cleanup;
c401cc
+        } else {
c401cc
+            if (VIR_STRDUP(uri->user, username) < 0)
c401cc
+                goto cleanup;
c401cc
+        }
c401cc
     }
c401cc
 
c401cc
-    if (disk->hosts->socket &&
c401cc
-        virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0)
c401cc
+    if (VIR_STRDUP(uri->server, hosts->name) < 0)
c401cc
         goto cleanup;
c401cc
 
c401cc
+    ret = virURIFormat(uri);
c401cc
+
c401cc
+cleanup:
c401cc
+    virURIFree(uri);
c401cc
+
c401cc
+    return ret;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static int
c401cc
+qemuBuildDriveURIString(virConnectPtr conn,
c401cc
+                        virDomainDiskDefPtr disk,
c401cc
+                        virBufferPtr opt,
c401cc
+                        int protocol,
c401cc
+                        virSecretUsageType secretUsageType)
c401cc
+{
c401cc
+    char *secret = NULL;
c401cc
+    char *builturi = NULL;
c401cc
+    int ret = -1;
c401cc
+
c401cc
+    virBufferAddLit(opt, "file=");
c401cc
+
c401cc
     if (disk->auth.username && secretUsageType != VIR_SECRET_USAGE_TYPE_NONE) {
c401cc
         /* Get the secret string using the virDomainDiskDef */
c401cc
-        if (!(secret = qemuGetSecretString(conn, scheme, false,
c401cc
+        if (!(secret = qemuGetSecretString(conn,
c401cc
+                                           virDomainDiskProtocolTypeToString(protocol),
c401cc
+                                           false,
c401cc
                                            disk->auth.secretType,
c401cc
                                            disk->auth.username,
c401cc
                                            disk->auth.secret.uuid,
c401cc
                                            disk->auth.secret.usage,
c401cc
                                            secretUsageType)))
c401cc
             goto cleanup;
c401cc
-        if (virAsprintf(&user, "%s:%s", disk->auth.username, secret) < 0)
c401cc
-            goto cleanup;
c401cc
     }
c401cc
 
c401cc
-    uri.scheme = tmpscheme; /* gluster+<transport> */
c401cc
-    uri.server = disk->hosts->name;
c401cc
-    uri.user = user;
c401cc
-    uri.port = port;
c401cc
-    uri.path = volimg;
c401cc
-    uri.query = sock;
c401cc
+    if (!(builturi = qemuBuildNetworkDriveURI(protocol,
c401cc
+                                              disk->src,
c401cc
+                                              disk->nhosts,
c401cc
+                                              disk->hosts,
c401cc
+                                              disk->auth.username,
c401cc
+                                              secret)))
c401cc
+        goto cleanup;
c401cc
 
c401cc
-    builturi = virURIFormat(&uri);
c401cc
     virBufferEscape(opt, ',', ",", "%s", builturi);
c401cc
 
c401cc
     ret = 0;
c401cc
 
c401cc
 cleanup:
c401cc
-    VIR_FREE(builturi);
c401cc
-    VIR_FREE(tmpscheme);
c401cc
-    VIR_FREE(volimg);
c401cc
-    VIR_FREE(sock);
c401cc
     VIR_FREE(secret);
c401cc
-    VIR_FREE(user);
c401cc
+    VIR_FREE(builturi);
c401cc
 
c401cc
     return ret;
c401cc
 }
c401cc
 
c401cc
-static int
c401cc
-qemuBuildGlusterString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
c401cc
-{
c401cc
-    return qemuBuildDriveURIString(conn, disk, opt, "gluster",
c401cc
-                                   VIR_SECRET_USAGE_TYPE_NONE);
c401cc
-}
c401cc
 
c401cc
 #define QEMU_DEFAULT_NBD_PORT "10809"
c401cc
 
c401cc
 static int
c401cc
-qemuBuildISCSIString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
c401cc
-{
c401cc
-    return qemuBuildDriveURIString(conn, disk, opt, "iscsi",
c401cc
-                                   VIR_SECRET_USAGE_TYPE_ISCSI);
c401cc
-}
c401cc
-
c401cc
-static int
c401cc
 qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
c401cc
 {
c401cc
     const char *transp;
c401cc
@@ -3662,7 +3681,8 @@ qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr op
c401cc
             && !disk->hosts->name)
c401cc
         || (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX
c401cc
             && disk->hosts->socket && disk->hosts->socket[0] != '/'))
c401cc
-        return qemuBuildDriveURIString(conn, disk, opt, "nbd",
c401cc
+        return qemuBuildDriveURIString(conn, disk, opt,
c401cc
+                                       VIR_DOMAIN_DISK_PROTOCOL_NBD,
c401cc
                                        VIR_SECRET_USAGE_TYPE_NONE);
c401cc
 
c401cc
     virBufferAddLit(opt, "file=nbd:");
c401cc
@@ -3829,12 +3849,16 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
                 virBufferAddChar(&opt, ',');
c401cc
                 break;
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
c401cc
-                if (qemuBuildGlusterString(conn, disk, &opt) < 0)
c401cc
+                if (qemuBuildDriveURIString(conn, disk, &opt,
c401cc
+                                            VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
c401cc
+                                            VIR_SECRET_USAGE_TYPE_NONE) < 0)
c401cc
                     goto error;
c401cc
                 virBufferAddChar(&opt, ',');
c401cc
                 break;
c401cc
             case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
c401cc
-                if (qemuBuildISCSIString(conn, disk, &opt) < 0)
c401cc
+                if (qemuBuildDriveURIString(conn, disk, &opt,
c401cc
+                                            VIR_DOMAIN_DISK_PROTOCOL_ISCSI,
c401cc
+                                            VIR_SECRET_USAGE_TYPE_ISCSI) < 0)
c401cc
                     goto error;
c401cc
                 virBufferAddChar(&opt, ',');
c401cc
                 break;
c401cc
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
c401cc
index 06c4b30..22b7aa7 100644
c401cc
--- a/src/qemu/qemu_command.h
c401cc
+++ b/src/qemu/qemu_command.h
c401cc
@@ -181,6 +181,12 @@ char * qemuBuildHubDevStr(virDomainDefPtr def,
c401cc
 char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
c401cc
                                virDomainRedirdevDefPtr dev,
c401cc
                                virQEMUCapsPtr qemuCaps);
c401cc
+char *qemuBuildNetworkDriveURI(int proto,
c401cc
+                               const char *src,
c401cc
+                               size_t nhosts,
c401cc
+                               virDomainDiskHostDefPtr hosts,
c401cc
+                               const char *username,
c401cc
+                               const char *secret);
c401cc
 
c401cc
 int qemuNetworkIfaceConnect(virDomainDefPtr def,
c401cc
                             virConnectPtr conn,
c401cc
-- 
c401cc
1.9.0
c401cc