qemuDomainRemoveDiskDevice() called
qemuBlockStorageSourceChainDetachPrepareBlockdev() unconditionally. A
CD-ROM with no media has an empty source (path == NULL), for which
virStorageSourceIsEmpty() returns true while virStorageSourceIsBacking()
still returns true, so the chain walk prepared a blockdev-del for a node
that was never created in QEMU. Detaching such a device produced an
internal error, either
"Failed to find node with node-name='libvirt-N-storage'" (when a prior
eject had left a stale node name in the source) or
"argument key 'node-name' must not have null value".
Guard the detach preparation with virStorageSourceIsEmpty(), as the
old-media detach in qemuDomainChangeMediaBlockdev() already does. The
following qemuBlockStorageSourceChainDetach() and access revoke are
already guarded by a non-NULL diskBackend, so an empty source is left
untouched.
Signed-off-by: Mitsuru Kariya <Mitsuru.Kariya@oss.nttdata.com>
---
src/qemu/qemu_hotplug.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 5be567b510..c2cd5496e0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4861,7 +4861,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
diskPriv->blockjob->disk = NULL;
g_clear_pointer(&diskPriv->blockjob, virObjectUnref);
} else {
- if (!(diskBackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(disk->src)))
+ if (!virStorageSourceIsEmpty(disk->src) &&
+ !(diskBackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(disk->src)))
goto cleanup;
}
--
2.43.0
On Mon, Jul 20, 2026 at 16:06:23 +0900, Mitsuru Kariya via Devel wrote:
> qemuDomainRemoveDiskDevice() called
> qemuBlockStorageSourceChainDetachPrepareBlockdev() unconditionally. A
> CD-ROM with no media has an empty source (path == NULL), for which
The condition for a source being empty is a bit more complex, because
NBD network devices can be full and have NULL path.
> virStorageSourceIsEmpty() returns true while virStorageSourceIsBacking()
> still returns true, so the chain walk prepared a blockdev-del for a node
Yeah, unfortunately due to historical reasons an empty drive is of type
_FILE and empty path.
> that was never created in QEMU. Detaching such a device produced an
> internal error, either
> "Failed to find node with node-name='libvirt-N-storage'" (when a prior
> eject had left a stale node name in the source) or
> "argument key 'node-name' must not have null value".
>
> Guard the detach preparation with virStorageSourceIsEmpty(), as the
> old-media detach in qemuDomainChangeMediaBlockdev() already does. The
> following qemuBlockStorageSourceChainDetach() and access revoke are
> already guarded by a non-NULL diskBackend, so an empty source is left
> untouched.
>
> Signed-off-by: Mitsuru Kariya <Mitsuru.Kariya@oss.nttdata.com>
> ---
> src/qemu/qemu_hotplug.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 5be567b510..c2cd5496e0 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -4861,7 +4861,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
> diskPriv->blockjob->disk = NULL;
> g_clear_pointer(&diskPriv->blockjob, virObjectUnref);
> } else {
> - if (!(diskBackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(disk->src)))
> + if (!virStorageSourceIsEmpty(disk->src) &&
> + !(diskBackend = qemuBlockStorageSourceChainDetachPrepareBlockdev(disk->src)))
> goto cleanup;
> }
I'll drop the node about path==NULL because the rest is explanatory
enough.
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
© 2016 - 2026 Red Hat, Inc.