Blob Blame History Raw
From e1b18fb8e327e01dbc062f86d7e23e288f441228 Mon Sep 17 00:00:00 2001
Message-Id: <e1b18fb8e327e01dbc062f86d7e23e288f441228@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 2 Aug 2016 13:42:03 +0200
Subject: [PATCH] qemu: command: Add infrastructure for object specified disk
 sources

To allow richer definitions of disk sources add infrastructure that will
allow to register functionst generating a JSON object based definition.

This infrastructure will then convert the definition to the proper
command line syntax and use it in cases where it's necessary. This will
allow to keep legacy definitions for back-compat when possible and use
the new definitions for the configurations requiring them.

(cherry picked from commit f444101729db35979857f317f46908bea3750488)
https://bugzilla.redhat.com/show_bug.cgi?id=1247521 [gluster multi-host]
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_command.c  | 83 ++++++++++++++++++++++++++++++++++++------------
 src/util/virqemu.c       | 21 ++++++++++++
 src/util/virqemu.h       |  2 ++
 4 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 533cf55..b7a1663 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2196,6 +2196,7 @@ virQEMUBuildBufferEscapeComma;
 virQEMUBuildCommandLineJSON;
 virQEMUBuildCommandLineJSONArrayBitmap;
 virQEMUBuildCommandLineJSONArrayNumbered;
+virQEMUBuildDriveCommandlineFromJSON;
 virQEMUBuildLuksOpts;
 virQEMUBuildObjectCommandlineFromJSON;
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a3e838c..b33c39c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -916,6 +916,34 @@ qemuBuildNetworkDriveStr(virStorageSourcePtr src,
 }
 
 
+static int
+qemuGetDriveSourceProps(virStorageSourcePtr src,
+                        virJSONValuePtr *props)
+{
+    int actualType = virStorageSourceGetActualType(src);
+    virJSONValuePtr fileprops = NULL;
+
+    *props = NULL;
+
+    switch ((virStorageType) actualType) {
+    case VIR_STORAGE_TYPE_BLOCK:
+    case VIR_STORAGE_TYPE_FILE:
+    case VIR_STORAGE_TYPE_DIR:
+    case VIR_STORAGE_TYPE_VOLUME:
+    case VIR_STORAGE_TYPE_NONE:
+    case VIR_STORAGE_TYPE_LAST:
+    case VIR_STORAGE_TYPE_NETWORK:
+        break;
+    }
+
+    if (fileprops &&
+        virJSONValueObjectCreate(props, "a:file", fileprops, NULL) < 0)
+        return -1;
+
+    return 0;
+}
+
+
 int
 qemuGetDriveSourceString(virStorageSourcePtr src,
                          qemuDomainSecretInfoPtr secinfo,
@@ -1101,14 +1129,19 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
     qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
     qemuDomainSecretInfoPtr secinfo = diskPriv->secinfo;
     qemuDomainSecretInfoPtr encinfo = diskPriv->encinfo;
+    virJSONValuePtr srcprops = NULL;
     char *source = NULL;
     int ret = -1;
 
-    if (qemuGetDriveSourceString(disk->src, secinfo, &source) < 0)
+    if (qemuGetDriveSourceProps(disk->src, &srcprops) < 0)
+        goto cleanup;
+
+    if (!srcprops &&
+        qemuGetDriveSourceString(disk->src, secinfo, &source) < 0)
         goto cleanup;
 
     /* nothing to format if the drive is empty */
-    if (!source ||
+    if (!(source || srcprops) ||
         ((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
           disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
          disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
@@ -1125,31 +1158,38 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
         goto cleanup;
     }
 
-    virBufferAddLit(buf, "file=");
+    if (source) {
+        virBufferAddLit(buf, "file=");
 
-    /* for now the DIR based storage is handled by the magic FAT format */
-    if (actualType == VIR_STORAGE_TYPE_DIR) {
-        if (disk->src->format > 0 &&
-            disk->src->format != VIR_STORAGE_FILE_FAT) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("unsupported disk driver type for '%s'"),
-                           virStorageFileFormatTypeToString(disk->src->format));
-            goto cleanup;
+        /* for now the DIR based storage is handled by the magic FAT format */
+        if (actualType == VIR_STORAGE_TYPE_DIR) {
+            if (disk->src->format > 0 &&
+                disk->src->format != VIR_STORAGE_FILE_FAT) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("unsupported disk driver type for '%s'"),
+                               virStorageFileFormatTypeToString(disk->src->format));
+                goto cleanup;
+            }
+
+            if (!disk->src->readonly) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("cannot create virtual FAT disks in read-write mode"));
+                goto cleanup;
+            }
+
+            virBufferAddLit(buf, "fat:");
+
+            if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+                virBufferAddLit(buf, "floppy:");
         }
 
-        if (!disk->src->readonly) {
-            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                           _("cannot create virtual FAT disks in read-write mode"));
+        virQEMUBuildBufferEscapeComma(buf, source);
+    } else {
+        if (!(source = virQEMUBuildDriveCommandlineFromJSON(srcprops)))
             goto cleanup;
-        }
 
-        virBufferAddLit(buf, "fat:");
-
-        if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
-            virBufferAddLit(buf, "floppy:");
+        virBufferAdd(buf, source, -1);
     }
-
-    virQEMUBuildBufferEscapeComma(buf, source);
     virBufferAddLit(buf, ",");
 
     if (secinfo && secinfo->type == VIR_DOMAIN_SECRET_INFO_TYPE_AES) {
@@ -1170,6 +1210,7 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
 
  cleanup:
     VIR_FREE(source);
+    virJSONValueFree(srcprops);
     return ret;
 }
 
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index 20410f7..a1ba562 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -264,6 +264,27 @@ virQEMUBuildObjectCommandlineFromJSON(const char *type,
 }
 
 
+char *
+virQEMUBuildDriveCommandlineFromJSON(const virJSONValue *srcdef)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    char *ret = NULL;
+
+    if (virQEMUBuildCommandLineJSON(srcdef, &buf,
+                                    virQEMUBuildCommandLineJSONArrayNumbered) < 0)
+        goto cleanup;
+
+    if (virBufferCheckError(&buf) < 0)
+        goto cleanup;
+
+    ret = virBufferContentAndReset(&buf);
+
+ cleanup:
+    virBufferFreeAndReset(&buf);
+    return ret;
+}
+
+
 /**
  * virQEMUBuildBufferEscapeComma:
  * @buf: buffer to append the escaped string
diff --git a/src/util/virqemu.h b/src/util/virqemu.h
index 40cd9b8..f3c2b69 100644
--- a/src/util/virqemu.h
+++ b/src/util/virqemu.h
@@ -47,6 +47,8 @@ char *virQEMUBuildObjectCommandlineFromJSON(const char *type,
                                             const char *alias,
                                             virJSONValuePtr props);
 
+char *virQEMUBuildDriveCommandlineFromJSON(const virJSONValue *src);
+
 void virQEMUBuildBufferEscapeComma(virBufferPtr buf, const char *str);
 void virQEMUBuildLuksOpts(virBufferPtr buf,
                           virStorageEncryptionInfoDefPtr enc,
-- 
2.9.2