qemuDomainChangeEjectableMedia() ran qemuDomainPrepareDiskSource() and the surrounding image setup (backing chain detection, storage access, managed PR) unconditionally. When ejecting to no media the new source is empty, and qemuDomainPrepareDiskSource() still assigned it node names that are never realized in QEMU, leaving a stale name in the disk source that a later detach would then try to blockdev-del.
Wrap the image setup in a virStorageSourceIsEmpty() check, mirroring qemuDomainAttachDeviceDiskLiveInternal(), and only revoke storage access on rollback when it was actually granted, using a releaseSeclabel flag as the attach path already does. Signed-off-by: Mitsuru Kariya <[email protected]> --- src/qemu/qemu_hotplug.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index c2cd5496e0..b96ff24cbf 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -612,6 +612,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriver *driver, qemuDomainObjPrivate *priv = vm->privateData; virStorageSource *oldsrc = disk->src; qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + bool releaseSeclabel = false; int rc; if (diskPriv->blockjob && qemuBlockJobIsRunning(diskPriv->blockjob)) { @@ -625,17 +626,21 @@ qemuDomainChangeEjectableMedia(virQEMUDriver *driver, if (virDomainDiskTranslateSourcePool(disk) < 0) goto rollback; - if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL) < 0) - goto rollback; + if (!virStorageSourceIsEmpty(newsrc)) { + if (qemuDomainDetermineDiskChain(driver, vm, disk, NULL) < 0) + goto rollback; - if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0) - goto rollback; + if (qemuDomainPrepareDiskSource(disk, priv, cfg) < 0) + goto rollback; - if (qemuDomainStorageSourceChainAccessAllow(driver, vm, newsrc) < 0) - goto rollback; + if (qemuDomainStorageSourceChainAccessAllow(driver, vm, newsrc) < 0) + goto rollback; - if (qemuHotplugAttachManagedPR(vm, newsrc, VIR_ASYNC_JOB_NONE) < 0) - goto rollback; + releaseSeclabel = true; + + if (qemuHotplugAttachManagedPR(vm, newsrc, VIR_ASYNC_JOB_NONE) < 0) + goto rollback; + } rc = qemuDomainChangeMediaBlockdev(vm, disk, oldsrc, newsrc, force); @@ -653,7 +658,8 @@ qemuDomainChangeEjectableMedia(virQEMUDriver *driver, return 0; rollback: - ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm, newsrc)); + if (releaseSeclabel) + ignore_value(qemuDomainStorageSourceChainAccessRevoke(driver, vm, newsrc)); qemuHotplugRemoveManagedPR(vm, newsrc, VIR_ASYNC_JOB_NONE); -- 2.43.0
