c401cc
From 4e03a8226e814920b7fb5bb880777ab474f69fe5 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <4e03a8226e814920b7fb5bb880777ab474f69fe5@dist-git>
c401cc
From: Peter Krempa <pkrempa@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:55:01 +0100
c401cc
Subject: [PATCH] qemu: Refactor disk source string formatting
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
This patch adds function qemuGetDriveSourceString to produce
c401cc
qemu-compatible disk source strings that will enable to reuse the code
c401cc
and refactors building of the qemu commandline of disks to use this new
c401cc
helper.
c401cc
c401cc
(cherry picked from commit 0df53f0432ec59f9b4f417ab5662c7232b6d80da)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 src/qemu/qemu_command.c | 128 ++++++++++++++++++++++++++++++++----------------
c401cc
 1 file changed, 86 insertions(+), 42 deletions(-)
c401cc
c401cc
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
c401cc
index e1af654..749f97b 100644
c401cc
--- a/src/qemu/qemu_command.c
c401cc
+++ b/src/qemu/qemu_command.c
c401cc
@@ -3728,19 +3728,62 @@ cleanup:
c401cc
 
c401cc
 
c401cc
 static int
c401cc
-qemuBuildDriveURIString(virConnectPtr conn,
c401cc
-                        virDomainDiskDefPtr disk,
c401cc
-                        virBufferPtr opt)
c401cc
+qemuGetDriveSourceString(int type,
c401cc
+                         const char *src,
c401cc
+                         int protocol,
c401cc
+                         size_t nhosts,
c401cc
+                         virDomainDiskHostDefPtr hosts,
c401cc
+                         const char *username,
c401cc
+                         const char *secret,
c401cc
+                         char **path)
c401cc
 {
c401cc
+    *path = NULL;
c401cc
+
c401cc
+    switch ((enum virDomainDiskType) type) {
c401cc
+    case VIR_DOMAIN_DISK_TYPE_BLOCK:
c401cc
+    case VIR_DOMAIN_DISK_TYPE_FILE:
c401cc
+    case VIR_DOMAIN_DISK_TYPE_DIR:
c401cc
+        if (!src)
c401cc
+            return 1;
c401cc
+
c401cc
+        if (VIR_STRDUP(*path, src) < 0)
c401cc
+            return -1;
c401cc
+
c401cc
+        break;
c401cc
+
c401cc
+    case VIR_DOMAIN_DISK_TYPE_NETWORK:
c401cc
+        if (!(*path = qemuBuildNetworkDriveURI(protocol,
c401cc
+                                               src,
c401cc
+                                               nhosts,
c401cc
+                                               hosts,
c401cc
+                                               username,
c401cc
+                                               secret)))
c401cc
+            return -1;
c401cc
+        break;
c401cc
+
c401cc
+    case VIR_DOMAIN_DISK_TYPE_VOLUME:
c401cc
+    case VIR_DOMAIN_DISK_TYPE_LAST:
c401cc
+        break;
c401cc
+    }
c401cc
+
c401cc
+    return 0;
c401cc
+}
c401cc
+
c401cc
+static int
c401cc
+qemuDomainDiskGetSourceString(virConnectPtr conn,
c401cc
+                              virDomainDiskDefPtr disk,
c401cc
+                              char **source)
c401cc
+{
c401cc
+    int actualType = qemuDiskGetActualType(disk);
c401cc
     char *secret = NULL;
c401cc
-    char *builturi = NULL;
c401cc
     int ret = -1;
c401cc
 
c401cc
-    virBufferAddLit(opt, "file=");
c401cc
+    *source = NULL;
c401cc
 
c401cc
-    if ((disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI ||
c401cc
-         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) &&
c401cc
-        disk->auth.username) {
c401cc
+    if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
c401cc
+        disk->auth.username &&
c401cc
+        (disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI ||
c401cc
+         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD)) {
c401cc
         bool encode = false;
c401cc
         int secretType = VIR_SECRET_USAGE_TYPE_ISCSI;
c401cc
 
c401cc
@@ -3761,32 +3804,23 @@ qemuBuildDriveURIString(virConnectPtr conn,
c401cc
             goto cleanup;
c401cc
     }
c401cc
 
c401cc
-
c401cc
-    if (!(builturi = qemuBuildNetworkDriveURI(disk->protocol,
c401cc
-                                              disk->src,
c401cc
-                                              disk->nhosts,
c401cc
-                                              disk->hosts,
c401cc
-                                              disk->auth.username,
c401cc
-                                              secret)))
c401cc
-        goto cleanup;
c401cc
-
c401cc
-    virBufferEscape(opt, ',', ",", "%s", builturi);
c401cc
-    virBufferAddChar(opt, ',');
c401cc
-
c401cc
-    ret = 0;
c401cc
+    ret = qemuGetDriveSourceString(qemuDiskGetActualType(disk),
c401cc
+                                   disk->src,
c401cc
+                                   disk->protocol,
c401cc
+                                   disk->nhosts,
c401cc
+                                   disk->hosts,
c401cc
+                                   disk->auth.username,
c401cc
+                                   secret,
c401cc
+                                   source);
c401cc
 
c401cc
 cleanup:
c401cc
     VIR_FREE(secret);
c401cc
-    VIR_FREE(builturi);
c401cc
-
c401cc
     return ret;
c401cc
 }
c401cc
 
c401cc
 
c401cc
-
c401cc
-
c401cc
 char *
c401cc
-qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
+qemuBuildDriveStr(virConnectPtr conn,
c401cc
                   virDomainDiskDefPtr disk,
c401cc
                   bool bootable,
c401cc
                   virQEMUCapsPtr qemuCaps)
c401cc
@@ -3797,6 +3831,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
         virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
c401cc
     int idx = virDiskNameToIndex(disk->dst);
c401cc
     int busid = -1, unitid = -1;
c401cc
+    char *source = NULL;
c401cc
     int actualType = qemuDiskGetActualType(disk);
c401cc
 
c401cc
     if (idx < 0) {
c401cc
@@ -3877,15 +3912,18 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
         break;
c401cc
     }
c401cc
 
c401cc
-    /* disk->src is NULL when we use nbd disks */
c401cc
-    if ((disk->src ||
c401cc
-        (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
c401cc
-         disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) &&
c401cc
+    if (qemuDomainDiskGetSourceString(conn, disk, &source) < 0)
c401cc
+        goto error;
c401cc
+
c401cc
+    if (source &&
c401cc
         !((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
c401cc
            disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
c401cc
           disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
c401cc
 
c401cc
-        if (actualType == VIR_DOMAIN_DISK_TYPE_DIR) {
c401cc
+        virBufferAddLit(&opt, "file=");
c401cc
+
c401cc
+        switch (actualType) {
c401cc
+        case VIR_DOMAIN_DISK_TYPE_DIR:
c401cc
             /* QEMU only supports magic FAT format for now */
c401cc
             if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) {
c401cc
                 virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
@@ -3893,32 +3931,38 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
c401cc
                                virStorageFileFormatTypeToString(disk->format));
c401cc
                 goto error;
c401cc
             }
c401cc
+
c401cc
             if (!disk->readonly) {
c401cc
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
c401cc
                                _("cannot create virtual FAT disks in read-write mode"));
c401cc
                 goto error;
c401cc
             }
c401cc
+
c401cc
+            virBufferAddLit(&opt, "fat:");
c401cc
+
c401cc
             if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
c401cc
-                virBufferEscape(&opt, ',', ",", "file=fat:floppy:%s,",
c401cc
-                                disk->src);
c401cc
-            else
c401cc
-                virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
c401cc
+                virBufferAddLit(&opt, "floppy:");
c401cc
 
c401cc
-        } else if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK) {
c401cc
-            if (qemuBuildDriveURIString(conn, disk, &opt) < 0)
c401cc
-                goto error;
c401cc
-        } else {
c401cc
-            if ((actualType == VIR_DOMAIN_DISK_TYPE_BLOCK) &&
c401cc
-                (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
c401cc
+            break;
c401cc
+
c401cc
+        case VIR_DOMAIN_DISK_TYPE_BLOCK:
c401cc
+            if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
c401cc
                 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
c401cc
                                disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME ?
c401cc
                                _("tray status 'open' is invalid for block type volume") :
c401cc
                                _("tray status 'open' is invalid for block type disk"));
c401cc
                 goto error;
c401cc
             }
c401cc
-            virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
c401cc
+
c401cc
+            break;
c401cc
+
c401cc
+        default:
c401cc
+            break;
c401cc
         }
c401cc
+
c401cc
+        virBufferEscape(&opt, ',', ",", "%s,", source);
c401cc
     }
c401cc
+
c401cc
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
c401cc
         virBufferAddLit(&opt, "if=none");
c401cc
     else
c401cc
-- 
c401cc
1.9.0
c401cc