When calling virConnectGetDomainCapabilities() (exposed as virsh domcapabilities) users have option to specify whatever sub-set of { emulatorbin, arch, machine, virttype } they want. Then we have a logic (hidden in virQEMUCapsCacheLookupDefault()) that picks qemuCaps that satisfy values passed by user. And whatever was not specified is then set to the default value as specified by picked qemuCaps. For instance: if no machine type was provided but emulatorbin was, then the machine type is set to the default one as defined by the emulatorbin.
Or, when just virttype was set then the remaining three values are set to their respective defaults. Except, we have a crasher in this case: # virsh domcapabilities --virttype hvf error: Disconnected from qemu:///system due to end of file error: failed to get emulator capabilities error: End of file while reading data: Input/output error This is because for 'hvf' virttype (at least my) QEMU does not have any machine type. Therefore, @machine is set to NULL and the rest of the code does not expect that. What we can do about this is to validate all arguments. Well, except for the emulatorbin which is obtained from passed qemuCaps. This also fixes the issue when domcapabilities for a virttype of a different driver are requested, or a different arch. Signed-off-by: Michal Privoznik <mpriv...@redhat.com> --- v2 of: https://listman.redhat.com/archives/libvir-list/2022-December/236460.html diff to v1: - validate @arch, @virttype as well, not just @machine src/qemu/qemu_conf.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index ae5bbcd138..6760bef14c 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1454,6 +1454,27 @@ virQEMUDriverGetDomainCapabilities(virQEMUDriver *driver, g_autoptr(virDomainCaps) domCaps = NULL; const char *path = virQEMUCapsGetBinary(qemuCaps); + if (!virQEMUCapsIsArchSupported(qemuCaps, arch)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Emulator '%s' does not support arch '%s'"), + path, virArchToString(arch)); + return NULL; + } + + if (!virQEMUCapsIsVirtTypeSupported(qemuCaps, virttype)) { + virReportError(VIR_ERR_INVALID_ARG, + _("Emulator '%s' does not support virt type '%s'"), + path, virDomainVirtTypeToString(virttype)); + return NULL; + } + + if (!virQEMUCapsIsMachineSupported(qemuCaps, virttype, machine)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Emulator '%s' does not support machine type '%s'"), + path, NULLSTR(machine)); + return NULL; + } + if (!(domCaps = virDomainCapsNew(path, machine, arch, virttype))) return NULL; -- 2.38.2