]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: command: format disk source commandline for -blockdev
authorPeter Krempa <pkrempa@redhat.com>
Thu, 7 Jun 2018 11:17:24 +0000 (13:17 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 21 Aug 2018 13:46:06 +0000 (15:46 +0200)
Format the backing chain onto the commandline using the 'json' syntax
with -blockdev.

The command line formatter needs only minor tweaks to add the new
entries but we now need to initialize the structures that are used for
every layer of the backing chain.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_command.c

index 0d614cd8090c22713c76c6ac31610901d1eccdaa..086167ce0ab2dcd6de90cf964ed34895568009b7 100644 (file)
@@ -2262,6 +2262,8 @@ static int
 qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
                                                  qemuBlockStorageSourceAttachDataPtr data)
 {
+    char *tmp;
+
     if (qemuBuildObjectCommandline(cmd, data->prmgrProps) < 0 ||
         qemuBuildObjectCommandline(cmd, data->authsecretProps) < 0 ||
         qemuBuildObjectCommandline(cmd, data->encryptsecretProps) < 0 ||
@@ -2271,6 +2273,22 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
     if (data->driveCmd)
         virCommandAddArgList(cmd, "-drive", data->driveCmd, NULL);
 
+    if (data->storageProps) {
+        if (!(tmp = virJSONValueToString(data->storageProps, false)))
+            return -1;
+
+        virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
+        VIR_FREE(tmp);
+    }
+
+    if (data->formatProps) {
+        if (!(tmp = virJSONValueToString(data->formatProps, false)))
+            return -1;
+
+        virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
+        VIR_FREE(tmp);
+    }
+
     return 0;
 }
 
@@ -2280,20 +2298,70 @@ qemuBuildDiskSourceCommandLine(virCommandPtr cmd,
                                virDomainDiskDefPtr disk,
                                virQEMUCapsPtr qemuCaps)
 {
-    qemuBlockStorageSourceAttachDataPtr data = NULL;
+    qemuBlockStorageSourceAttachDataPtr *data = NULL;
+    size_t ndata = 0;
+    qemuBlockStorageSourceAttachDataPtr tmp = NULL;
+    virJSONValuePtr copyOnReadProps = NULL;
+    virStorageSourcePtr n;
+    char *str = NULL;
+    size_t i;
     int ret = -1;
 
-    if (!(data = qemuBuildStorageSourceAttachPrepareDrive(disk, qemuCaps)))
-        return -1;
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_BLOCKDEV)) {
+        if (virStorageSourceIsEmpty(disk->src)) {
+            ret = 0;
+            goto cleanup;
+        }
 
-    if (qemuBuildStorageSourceAttachPrepareCommon(disk->src, data, qemuCaps) < 0 ||
-        qemuBuildBlockStorageSourceAttachDataCommandline(cmd, data) < 0)
-        goto cleanup;
+        for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
+            if (!(tmp = qemuBlockStorageSourceAttachPrepareBlockdev(n)))
+                goto cleanup;
+
+            if (qemuBuildStorageSourceAttachPrepareCommon(n, tmp, qemuCaps) < 0)
+                goto cleanup;
+
+            if (VIR_APPEND_ELEMENT(data, ndata, tmp) < 0)
+                goto cleanup;
+        }
+
+        if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON &&
+            !(copyOnReadProps = qemuBlockStorageGetCopyOnReadProps(disk)))
+            goto cleanup;
+    } else {
+        if (!(tmp = qemuBuildStorageSourceAttachPrepareDrive(disk, qemuCaps)))
+            goto cleanup;
+
+        if (qemuBuildStorageSourceAttachPrepareCommon(disk->src, tmp,
+                                                      qemuCaps) < 0)
+            goto cleanup;
+
+        if (VIR_APPEND_ELEMENT(data, ndata, tmp) < 0)
+            goto cleanup;
+    }
+
+    for (i = ndata; i > 0; i--) {
+        if (qemuBuildBlockStorageSourceAttachDataCommandline(cmd,
+                                                             data[i - 1]) < 0)
+            goto cleanup;
+    }
+
+    if (copyOnReadProps) {
+        if (!(str = virJSONValueToString(copyOnReadProps, false)))
+            goto cleanup;
+
+        virCommandAddArgList(cmd, "-blockdev", str, NULL);
+        VIR_FREE(str);
+    }
 
     ret = 0;
 
  cleanup:
-    qemuBlockStorageSourceAttachDataFree(data);
+    for (i = 0; i < ndata; i++)
+        qemuBlockStorageSourceAttachDataFree(data[i]);
+    VIR_FREE(data);
+    qemuBlockStorageSourceAttachDataFree(tmp);
+    virJSONValueFree(copyOnReadProps);
+    VIR_FREE(str);
     return ret;
 }