qemu: hotplug: Don't try to setup disk image when hotplugging empty cdrom drive

Originally the disk hotplug code didn't know how to attach a CD-ROM
drive, thus didn't have the necessary logic to handle empty cdroms.

Other disks can't be empty which is enforced by the parser validation
logic.

When support for hotplugging cdroms was added the code was not adjusted
to deal with empty drives thus attempted to setup the blockdev backend
for it.

Fixes: 3078799fef
Resolves: https://issues.redhat.com/browse/RHEL-16870
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2023-11-21 14:59:37 +01:00
parent fe42189d76
commit 894c6c5c16

View File

@ -662,53 +662,55 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
g_autoptr(qemuSnapshotDiskContext) transientDiskSnapshotCtxt = NULL;
bool origReadonly = disk->src->readonly;
if (disk->transient)
disk->src->readonly = true;
if (!virStorageSourceIsEmpty(disk->src)) {
if (disk->transient)
disk->src->readonly = true;
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
if (!(data = qemuBuildStorageSourceChainAttachPrepareChardev(disk)))
return -1;
} else {
if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src)))
return -1;
if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) {
if (!(data->copyOnReadProps = qemuBlockStorageGetCopyOnReadProps(disk)))
if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_VHOST_USER) {
if (!(data = qemuBuildStorageSourceChainAttachPrepareChardev(disk)))
return -1;
} else {
if (!(data = qemuBuildStorageSourceChainAttachPrepareBlockdev(disk->src)))
return -1;
data->copyOnReadNodename = g_strdup(QEMU_DOMAIN_DISK_PRIVATE(disk)->nodeCopyOnRead);
if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) {
if (!(data->copyOnReadProps = qemuBlockStorageGetCopyOnReadProps(disk)))
return -1;
data->copyOnReadNodename = g_strdup(QEMU_DOMAIN_DISK_PRIVATE(disk)->nodeCopyOnRead);
}
}
}
disk->src->readonly = origReadonly;
disk->src->readonly = origReadonly;
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
return -1;
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
return -1;
rc = qemuBlockStorageSourceChainAttach(priv->mon, data);
rc = qemuBlockStorageSourceChainAttach(priv->mon, data);
qemuDomainObjExitMonitor(vm);
qemuDomainObjExitMonitor(vm);
if (rc < 0)
goto rollback;
if (disk->transient) {
g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
g_autoptr(GHashTable) blockNamedNodeData = NULL;
if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
if (rc < 0)
goto rollback;
if (!(transientDiskSnapshotCtxt = qemuDomainAttachDiskGenericTransient(vm, disk, blockNamedNodeData, asyncJob)))
goto rollback;
if (disk->transient) {
g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
g_autoptr(GHashTable) blockNamedNodeData = NULL;
if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, asyncJob)))
goto rollback;
if (!(transientDiskSnapshotCtxt = qemuDomainAttachDiskGenericTransient(vm, disk, blockNamedNodeData, asyncJob)))
goto rollback;
if (qemuSnapshotDiskCreate(transientDiskSnapshotCtxt) < 0)
goto rollback;
if (qemuSnapshotDiskCreate(transientDiskSnapshotCtxt) < 0)
goto rollback;
QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated = true;
backend = qemuBlockStorageSourceDetachPrepare(disk->src);
ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, backend));
QEMU_DOMAIN_DISK_PRIVATE(disk)->transientOverlayCreated = true;
backend = qemuBlockStorageSourceDetachPrepare(disk->src);
ignore_value(VIR_INSERT_ELEMENT(data->srcdata, 0, data->nsrcdata, backend));
}
}
if (!(devprops = qemuBuildDiskDeviceProps(vm->def, disk, priv->qemuCaps)))
@ -995,28 +997,30 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver *driver,
goto cleanup;
}
if (qemuDomainStorageSourceChainAccessAllow(driver, vm, disk->src) < 0)
goto cleanup;
releaseSeclabel = true;
if (qemuAssignDeviceDiskAlias(vm->def, disk) < 0)
goto cleanup;
if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0)
goto cleanup;
if (!virStorageSourceIsEmpty(disk->src)) {
if (qemuDomainStorageSourceChainAccessAllow(driver, vm, disk->src) < 0)
goto cleanup;
if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL) < 0)
goto cleanup;
releaseSeclabel = true;
if (qemuProcessPrepareHostStorageDisk(vm, disk) < 0)
goto cleanup;
if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0)
goto cleanup;
if (qemuHotplugAttachManagedPR(vm, disk->src, VIR_ASYNC_JOB_NONE) < 0)
goto cleanup;
if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL) < 0)
goto cleanup;
if (qemuNbdkitStartStorageSource(driver, vm, disk->src) < 0)
goto cleanup;
if (qemuProcessPrepareHostStorageDisk(vm, disk) < 0)
goto cleanup;
if (qemuHotplugAttachManagedPR(vm, disk->src, VIR_ASYNC_JOB_NONE) < 0)
goto cleanup;
if (qemuNbdkitStartStorageSource(driver, vm, disk->src) < 0)
goto cleanup;
}
ret = qemuDomainAttachDiskGeneric(vm, disk, VIR_ASYNC_JOB_NONE);