Blob Blame History Raw
From 55f5ce01a0a43d8f4dabbdcb3fc48b0d3aea7cc3 Mon Sep 17 00:00:00 2001
Message-Id: <55f5ce01a0a43d8f4dabbdcb3fc48b0d3aea7cc3@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 26 Feb 2014 14:54:55 +0100
Subject: [PATCH] qemu: Split out formatting of network disk source URI

https://bugzilla.redhat.com/show_bug.cgi?id=1032370

The snapshot code will need to use qemu-style formatted URIs of network
disks. Split out the code to avoid duplication.

(cherry picked from commit a29d33ffcb81e78f197b294ce1669b58b926a9d6)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_command.c | 146 ++++++++++++++++++++++++++++--------------------
 src/qemu/qemu_command.h |   6 ++
 2 files changed, 91 insertions(+), 61 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2338b12..da4d2f8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3547,106 +3547,125 @@ error:
     return -1;
 }
 
-static int
-qemuBuildDriveURIString(virConnectPtr conn,
-                        virDomainDiskDefPtr disk, virBufferPtr opt,
-                        const char *scheme, virSecretUsageType secretUsageType)
-{
-    int ret = -1;
-    int port = 0;
-    char *secret = NULL;
 
-    char *tmpscheme = NULL;
-    char *volimg = NULL;
-    char *sock = NULL;
-    char *user = NULL;
-    char *builturi = NULL;
-    const char *transp = NULL;
-    virURI uri = {
-        .port = port /* just to clear rest of bits */
-    };
+char *
+qemuBuildNetworkDriveURI(int protocol,
+                         const char *src,
+                         size_t nhosts,
+                         virDomainDiskHostDefPtr hosts,
+                         const char *username,
+                         const char *secret)
+{
+    char *ret = NULL;
+    virURIPtr uri = NULL;
 
-    if (disk->nhosts != 1) {
+    if (nhosts != 1) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("%s accepts only one host"), scheme);
-        return -1;
+                       _("protocol '%s' accepts only one host"),
+                       virDomainDiskProtocolTypeToString(protocol));
+        return NULL;
     }
 
-    virBufferAddLit(opt, "file=");
-    transp = virDomainDiskProtocolTransportTypeToString(disk->hosts->transport);
+    if (VIR_ALLOC(uri) < 0)
+        return NULL;
 
-    if (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
-        if (VIR_STRDUP(tmpscheme, scheme) < 0)
+    if (hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_TCP) {
+        if (VIR_STRDUP(uri->scheme, virDomainDiskProtocolTypeToString(protocol)) < 0)
             goto cleanup;
     } else {
-        if (virAsprintf(&tmpscheme, "%s+%s", scheme, transp) < 0)
+        if (virAsprintf(&uri->scheme, "%s+%s",
+                        virDomainDiskProtocolTypeToString(protocol),
+                        virDomainDiskProtocolTransportTypeToString(hosts->transport)) < 0)
             goto cleanup;
     }
 
-    if (disk->src && virAsprintf(&volimg, "/%s", disk->src) < 0)
+    if (src &&
+        virAsprintf(&uri->path, "/%s", src) < 0)
+        goto cleanup;
+
+    if (hosts->port &&
+        virStrToLong_i(hosts->port, NULL, 10, &uri->port) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("failed to parse port number '%s'"),
+                       hosts->port);
+        goto cleanup;
+    }
+
+    if (hosts->socket &&
+        virAsprintf(&uri->query, "socket=%s", hosts->socket) < 0)
         goto cleanup;
 
-    if (disk->hosts->port) {
-        port = atoi(disk->hosts->port);
+    if (username) {
+        if (secret) {
+            if (virAsprintf(&uri->user, "%s:%s", username, secret) < 0)
+                goto cleanup;
+        } else {
+            if (VIR_STRDUP(uri->user, username) < 0)
+                goto cleanup;
+        }
     }
 
-    if (disk->hosts->socket &&
-        virAsprintf(&sock, "socket=%s", disk->hosts->socket) < 0)
+    if (VIR_STRDUP(uri->server, hosts->name) < 0)
         goto cleanup;
 
+    ret = virURIFormat(uri);
+
+cleanup:
+    virURIFree(uri);
+
+    return ret;
+}
+
+
+static int
+qemuBuildDriveURIString(virConnectPtr conn,
+                        virDomainDiskDefPtr disk,
+                        virBufferPtr opt,
+                        int protocol,
+                        virSecretUsageType secretUsageType)
+{
+    char *secret = NULL;
+    char *builturi = NULL;
+    int ret = -1;
+
+    virBufferAddLit(opt, "file=");
+
     if (disk->auth.username && secretUsageType != VIR_SECRET_USAGE_TYPE_NONE) {
         /* Get the secret string using the virDomainDiskDef */
-        if (!(secret = qemuGetSecretString(conn, scheme, false,
+        if (!(secret = qemuGetSecretString(conn,
+                                           virDomainDiskProtocolTypeToString(protocol),
+                                           false,
                                            disk->auth.secretType,
                                            disk->auth.username,
                                            disk->auth.secret.uuid,
                                            disk->auth.secret.usage,
                                            secretUsageType)))
             goto cleanup;
-        if (virAsprintf(&user, "%s:%s", disk->auth.username, secret) < 0)
-            goto cleanup;
     }
 
-    uri.scheme = tmpscheme; /* gluster+<transport> */
-    uri.server = disk->hosts->name;
-    uri.user = user;
-    uri.port = port;
-    uri.path = volimg;
-    uri.query = sock;
+    if (!(builturi = qemuBuildNetworkDriveURI(protocol,
+                                              disk->src,
+                                              disk->nhosts,
+                                              disk->hosts,
+                                              disk->auth.username,
+                                              secret)))
+        goto cleanup;
 
-    builturi = virURIFormat(&uri);
     virBufferEscape(opt, ',', ",", "%s", builturi);
 
     ret = 0;
 
 cleanup:
-    VIR_FREE(builturi);
-    VIR_FREE(tmpscheme);
-    VIR_FREE(volimg);
-    VIR_FREE(sock);
     VIR_FREE(secret);
-    VIR_FREE(user);
+    VIR_FREE(builturi);
 
     return ret;
 }
 
-static int
-qemuBuildGlusterString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
-{
-    return qemuBuildDriveURIString(conn, disk, opt, "gluster",
-                                   VIR_SECRET_USAGE_TYPE_NONE);
-}
 
 #define QEMU_DEFAULT_NBD_PORT "10809"
 
 static int
-qemuBuildISCSIString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
-{
-    return qemuBuildDriveURIString(conn, disk, opt, "iscsi",
-                                   VIR_SECRET_USAGE_TYPE_ISCSI);
-}
-
-static int
 qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr opt)
 {
     const char *transp;
@@ -3662,7 +3681,8 @@ qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr op
             && !disk->hosts->name)
         || (disk->hosts->transport == VIR_DOMAIN_DISK_PROTO_TRANS_UNIX
             && disk->hosts->socket && disk->hosts->socket[0] != '/'))
-        return qemuBuildDriveURIString(conn, disk, opt, "nbd",
+        return qemuBuildDriveURIString(conn, disk, opt,
+                                       VIR_DOMAIN_DISK_PROTOCOL_NBD,
                                        VIR_SECRET_USAGE_TYPE_NONE);
 
     virBufferAddLit(opt, "file=nbd:");
@@ -3829,12 +3849,16 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
                 virBufferAddChar(&opt, ',');
                 break;
             case VIR_DOMAIN_DISK_PROTOCOL_GLUSTER:
-                if (qemuBuildGlusterString(conn, disk, &opt) < 0)
+                if (qemuBuildDriveURIString(conn, disk, &opt,
+                                            VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
+                                            VIR_SECRET_USAGE_TYPE_NONE) < 0)
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
             case VIR_DOMAIN_DISK_PROTOCOL_ISCSI:
-                if (qemuBuildISCSIString(conn, disk, &opt) < 0)
+                if (qemuBuildDriveURIString(conn, disk, &opt,
+                                            VIR_DOMAIN_DISK_PROTOCOL_ISCSI,
+                                            VIR_SECRET_USAGE_TYPE_ISCSI) < 0)
                     goto error;
                 virBufferAddChar(&opt, ',');
                 break;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 06c4b30..22b7aa7 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -181,6 +181,12 @@ char * qemuBuildHubDevStr(virDomainDefPtr def,
 char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
                                virDomainRedirdevDefPtr dev,
                                virQEMUCapsPtr qemuCaps);
+char *qemuBuildNetworkDriveURI(int proto,
+                               const char *src,
+                               size_t nhosts,
+                               virDomainDiskHostDefPtr hosts,
+                               const char *username,
+                               const char *secret);
 
 int qemuNetworkIfaceConnect(virDomainDefPtr def,
                             virConnectPtr conn,
-- 
1.9.0