Blob Blame History Raw
From 4e03a8226e814920b7fb5bb880777ab474f69fe5 Mon Sep 17 00:00:00 2001
Message-Id: <4e03a8226e814920b7fb5bb880777ab474f69fe5@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Wed, 26 Feb 2014 14:55:01 +0100
Subject: [PATCH] qemu: Refactor disk source string formatting

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

This patch adds function qemuGetDriveSourceString to produce
qemu-compatible disk source strings that will enable to reuse the code
and refactors building of the qemu commandline of disks to use this new
helper.

(cherry picked from commit 0df53f0432ec59f9b4f417ab5662c7232b6d80da)

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_command.c | 128 ++++++++++++++++++++++++++++++++----------------
 1 file changed, 86 insertions(+), 42 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e1af654..749f97b 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3728,19 +3728,62 @@ cleanup:
 
 
 static int
-qemuBuildDriveURIString(virConnectPtr conn,
-                        virDomainDiskDefPtr disk,
-                        virBufferPtr opt)
+qemuGetDriveSourceString(int type,
+                         const char *src,
+                         int protocol,
+                         size_t nhosts,
+                         virDomainDiskHostDefPtr hosts,
+                         const char *username,
+                         const char *secret,
+                         char **path)
 {
+    *path = NULL;
+
+    switch ((enum virDomainDiskType) type) {
+    case VIR_DOMAIN_DISK_TYPE_BLOCK:
+    case VIR_DOMAIN_DISK_TYPE_FILE:
+    case VIR_DOMAIN_DISK_TYPE_DIR:
+        if (!src)
+            return 1;
+
+        if (VIR_STRDUP(*path, src) < 0)
+            return -1;
+
+        break;
+
+    case VIR_DOMAIN_DISK_TYPE_NETWORK:
+        if (!(*path = qemuBuildNetworkDriveURI(protocol,
+                                               src,
+                                               nhosts,
+                                               hosts,
+                                               username,
+                                               secret)))
+            return -1;
+        break;
+
+    case VIR_DOMAIN_DISK_TYPE_VOLUME:
+    case VIR_DOMAIN_DISK_TYPE_LAST:
+        break;
+    }
+
+    return 0;
+}
+
+static int
+qemuDomainDiskGetSourceString(virConnectPtr conn,
+                              virDomainDiskDefPtr disk,
+                              char **source)
+{
+    int actualType = qemuDiskGetActualType(disk);
     char *secret = NULL;
-    char *builturi = NULL;
     int ret = -1;
 
-    virBufferAddLit(opt, "file=");
+    *source = NULL;
 
-    if ((disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI ||
-         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) &&
-        disk->auth.username) {
+    if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
+        disk->auth.username &&
+        (disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI ||
+         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD)) {
         bool encode = false;
         int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
 
@@ -3761,32 +3804,23 @@ qemuBuildDriveURIString(virConnectPtr conn,
             goto cleanup;
     }
 
-
-    if (!(builturi = qemuBuildNetworkDriveURI(disk->protocol,
-                                              disk->src,
-                                              disk->nhosts,
-                                              disk->hosts,
-                                              disk->auth.username,
-                                              secret)))
-        goto cleanup;
-
-    virBufferEscape(opt, ',', ",", "%s", builturi);
-    virBufferAddChar(opt, ',');
-
-    ret = 0;
+    ret = qemuGetDriveSourceString(qemuDiskGetActualType(disk),
+                                   disk->src,
+                                   disk->protocol,
+                                   disk->nhosts,
+                                   disk->hosts,
+                                   disk->auth.username,
+                                   secret,
+                                   source);
 
 cleanup:
     VIR_FREE(secret);
-    VIR_FREE(builturi);
-
     return ret;
 }
 
 
-
-
 char *
-qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
+qemuBuildDriveStr(virConnectPtr conn,
                   virDomainDiskDefPtr disk,
                   bool bootable,
                   virQEMUCapsPtr qemuCaps)
@@ -3797,6 +3831,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
         virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
     int idx = virDiskNameToIndex(disk->dst);
     int busid = -1, unitid = -1;
+    char *source = NULL;
     int actualType = qemuDiskGetActualType(disk);
 
     if (idx < 0) {
@@ -3877,15 +3912,18 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
         break;
     }
 
-    /* disk->src is NULL when we use nbd disks */
-    if ((disk->src ||
-        (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
-         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) &&
+    if (qemuDomainDiskGetSourceString(conn, disk, &source) < 0)
+        goto error;
+
+    if (source &&
         !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
            disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
           disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
 
-        if (actualType == VIR_DOMAIN_DISK_TYPE_DIR) {
+        virBufferAddLit(&opt, "file=");
+
+        switch (actualType) {
+        case VIR_DOMAIN_DISK_TYPE_DIR:
             /* QEMU only supports magic FAT format for now */
             if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) {
                 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -3893,32 +3931,38 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
                                virStorageFileFormatTypeToString(disk->format));
                 goto error;
             }
+
             if (!disk->readonly) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("cannot create virtual FAT disks in read-write mode"));
                 goto error;
             }
+
+            virBufferAddLit(&opt, "fat:");
+
             if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
-                virBufferEscape(&opt, ',', ",", "file=fat:floppy:%s,",
-                                disk->src);
-            else
-                virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
+                virBufferAddLit(&opt, "floppy:");
 
-        } else if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK) {
-            if (qemuBuildDriveURIString(conn, disk, &opt) < 0)
-                goto error;
-        } else {
-            if ((actualType == VIR_DOMAIN_DISK_TYPE_BLOCK) &&
-                (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
+            break;
+
+        case VIR_DOMAIN_DISK_TYPE_BLOCK:
+            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                                disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME ?
                                _("tray status 'open' is invalid for block type volume") :
                                _("tray status 'open' is invalid for block type disk"));
                 goto error;
             }
-            virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
+
+            break;
+
+        default:
+            break;
         }
+
+        virBufferEscape(&opt, ',', ",", "%s,", source);
     }
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
         virBufferAddLit(&opt, "if=none");
     else
-- 
1.9.0