[PATCH 17/20] qemu: Refuse blockjobs on disk bus='sd' with -blockdev

Peter Krempa pkrempa at redhat.com
Wed May 6 12:08:32 UTC 2020


We still have to use -drive to instantiate sd disks. Combining that with
the new logic for blockjobs would be very complicated and not worth it
given that 'sd' cards work only on few rarely used machine types of
non-common architectures and libvirt didn't implement support for 'sd'
bus controllers. This will allow us to use -blockdev for other kinds on
such machines while sacrificing block jobs.

Note: this is currently no-op as we mask-out the QEMU_CAPS_BLOCKDEV
capability if any of the disks has bus='sd'.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_backup.c     |  3 +++
 src/qemu/qemu_checkpoint.c |  3 +++
 src/qemu/qemu_domain.c     | 26 ++++++++++++++++++++++++++
 src/qemu/qemu_domain.h     |  4 ++++
 src/qemu/qemu_driver.c     | 22 ++++++++++++++++++----
 5 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
index 80fc5d77f8..b317b841cd 100644
--- a/src/qemu/qemu_backup.c
+++ b/src/qemu/qemu_backup.c
@@ -315,6 +315,9 @@ qemuBackupDiskPrepareDataOne(virDomainObjPtr vm,
         return -1;
     }

+    if (!qemuDomainDiskBlockJobIsSupported(vm, dd->domdisk))
+        return -1;
+
     if (!dd->store->format)
         dd->store->format = VIR_STORAGE_FILE_QCOW2;

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 3f6aa36ef3..b71b4a7d14 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -445,6 +445,9 @@ qemuCheckpointPrepare(virQEMUDriverPtr driver,
                                vm->def->disks[i]->src->format));
             return -1;
         }
+
+        if (!qemuDomainDiskBlockJobIsSupported(vm, vm->def->disks[i]))
+            return -1;
     }

     return 0;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 01f2792401..395cc3daee 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13620,3 +13620,29 @@ qemuDomainInitializePflashStorageSource(virDomainObjPtr vm)

     return 0;
 }
+
+
+/**
+ * qemuDomainDiskBlockJobIsSupported:
+ *
+ * Returns true if block jobs are supported on @disk by @vm or false and reports
+ * an error otherwise.
+ *
+ * Note that this does not verify whether other block jobs are running etc.
+ */
+bool
+qemuDomainDiskBlockJobIsSupported(virDomainObjPtr vm,
+                                  virDomainDiskDefPtr disk)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV) &&
+        qemuDiskBusIsSD(disk->bus)) {
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("block jobs are not supported on disk '%s' using bus 'sd'"),
+                       disk->dst);
+        return false;
+    }
+
+    return true;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index ea0fce64a8..41d3f1561d 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1293,3 +1293,7 @@ qemuDomainMakeCPUMigratable(virCPUDefPtr cpu);

 int
 qemuDomainInitializePflashStorageSource(virDomainObjPtr vm);
+
+bool
+qemuDomainDiskBlockJobIsSupported(virDomainObjPtr vm,
+                                  virDomainDiskDefPtr disk);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cb0373bf76..c7eb62f10d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14603,7 +14603,8 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi


 static int
-qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk,
+qemuDomainSnapshotPrepareDiskExternalActive(virDomainObjPtr vm,
+                                            virDomainSnapshotDiskDefPtr snapdisk,
                                             virDomainDiskDefPtr domdisk,
                                             bool blockdev)
 {
@@ -14616,6 +14617,9 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
         return -1;
     }

+    if (!qemuDomainDiskBlockJobIsSupported(vm, domdisk))
+        return -1;
+
     switch ((virStorageType)actualType) {
     case VIR_STORAGE_TYPE_BLOCK:
     case VIR_STORAGE_TYPE_FILE:
@@ -14671,7 +14675,8 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk


 static int
-qemuDomainSnapshotPrepareDiskExternal(virDomainDiskDefPtr disk,
+qemuDomainSnapshotPrepareDiskExternal(virDomainObjPtr vm,
+                                      virDomainDiskDefPtr disk,
                                       virDomainSnapshotDiskDefPtr snapdisk,
                                       bool active,
                                       bool reuse,
@@ -14698,7 +14703,7 @@ qemuDomainSnapshotPrepareDiskExternal(virDomainDiskDefPtr disk,
         if (qemuDomainSnapshotPrepareDiskExternalInactive(snapdisk, disk) < 0)
             return -1;
     } else {
-        if (qemuDomainSnapshotPrepareDiskExternalActive(snapdisk, disk, blockdev) < 0)
+        if (qemuDomainSnapshotPrepareDiskExternalActive(vm, snapdisk, disk, blockdev) < 0)
             return -1;
     }

@@ -14857,7 +14862,7 @@ qemuDomainSnapshotPrepare(virDomainObjPtr vm,
                 return -1;
             }

-            if (qemuDomainSnapshotPrepareDiskExternal(dom_disk, disk,
+            if (qemuDomainSnapshotPrepareDiskExternal(vm, dom_disk, disk,
                                                       active, reuse, blockdev) < 0)
                 return -1;

@@ -17444,6 +17449,9 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm,
     if (qemuDomainDiskBlockJobIsActive(disk))
         goto endjob;

+    if (!qemuDomainDiskBlockJobIsSupported(vm, disk))
+        goto endjob;
+
     if (base &&
         (virStorageFileParseChainIndex(disk->dst, base, &baseIndex) < 0 ||
          !(baseSource = virStorageFileChainLookup(disk->src, disk->src,
@@ -18002,6 +18010,9 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     if (qemuDomainDiskBlockJobIsActive(disk))
         goto endjob;

+    if (!qemuDomainDiskBlockJobIsSupported(vm, disk))
+        goto endjob;
+
     if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN &&
         qemuDomainDefValidateDiskLunSource(mirror) < 0)
         goto endjob;
@@ -18483,6 +18494,9 @@ qemuDomainBlockCommit(virDomainPtr dom,
     if (virDomainObjCheckActive(vm) < 0)
         goto endjob;

+    if (!qemuDomainDiskBlockJobIsSupported(vm, disk))
+        goto endjob;
+
     blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);

     /* Convert bandwidth MiB to bytes, if necessary */
-- 
2.26.2




More information about the libvir-list mailing list