diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c index 80fc5d77f800dc5cad2c6ea0a158192980c534be..b317b841cdfa608362c92a4cafadeb0103866bf6 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 3f6aa36ef32c34f2f51dc20d17b576edeee28c58..b71b4a7d14dc0f8ed6580ab12fb27029c9d7a9b9 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 a249442dd215fd85a9050474a1bb8d6a4dd051aa..bbc292d0a1a2e3bb208d69bedee726b36dd4ee63 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -13616,3 +13616,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 ea0fce64a886eedd9362ebd20615543b70c159a1..41d3f1561dd99f74b33b45b1222fefebacc506b2 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 cb0373bf76f48435832a0abaadad15987bd45e28..c7eb62f10d9591f69ba70d7e60c17d35682e5681 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 */