mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +00:00
qemu_capabilities: Introduce virQEMUCapsCacheLookupDefault
virConnectGetDomainCapabilities needs to lookup QEMU capabilities matching a specified binary, architecture, virt type, and machine type while using default values when any of the parameters are not provided by the user. Let's extract the lookup code into virQEMUCapsCacheLookupDefault to make it reusable. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
d0ff5ce43b
commit
da3bfc9ffc
@ -4555,6 +4555,124 @@ virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virQEMUCapsCacheLookupDefault:
|
||||
* @cache: QEMU capabilities cache
|
||||
* @binary: optional path to QEMU binary
|
||||
* @archStr: optional guest architecture
|
||||
* @virttypeStr: optional virt type
|
||||
* @machine: optional machine type
|
||||
* @retArch: if non-NULL, guest architecture will be returned here
|
||||
* @retVirttype: if non-NULL, domain virt type will be returned here
|
||||
* @retMachine: if non-NULL, canonical machine type will be returned here
|
||||
*
|
||||
* Looks up the QEMU binary specified by @binary and @archStr, checks it can
|
||||
* provide the required @virttypeStr and @machine and returns its capabilities.
|
||||
* Sensible defaults are used for any argument which is NULL (the function can
|
||||
* even be called with all NULL arguments).
|
||||
*
|
||||
* Returns QEMU capabilities matching the requirements, NULL on error.
|
||||
*/
|
||||
virQEMUCapsPtr
|
||||
virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
|
||||
const char *binary,
|
||||
const char *archStr,
|
||||
const char *virttypeStr,
|
||||
const char *machine,
|
||||
virArch *retArch,
|
||||
virDomainVirtType *retVirttype,
|
||||
const char **retMachine)
|
||||
{
|
||||
int virttype = VIR_DOMAIN_VIRT_NONE;
|
||||
int arch = virArchFromHost();
|
||||
virDomainVirtType capsType;
|
||||
virQEMUCapsPtr qemuCaps = NULL;
|
||||
virQEMUCapsPtr ret = NULL;
|
||||
|
||||
if (virttypeStr &&
|
||||
(virttype = virDomainVirtTypeFromString(virttypeStr)) < 0) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unknown virttype: %s"), virttypeStr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (archStr &&
|
||||
(arch = virArchFromString(archStr)) == VIR_ARCH_NONE) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unknown architecture: %s"), archStr);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (binary) {
|
||||
virArch arch_from_caps;
|
||||
|
||||
if (!(qemuCaps = virQEMUCapsCacheLookup(cache, binary)))
|
||||
goto cleanup;
|
||||
|
||||
arch_from_caps = virQEMUCapsGetArch(qemuCaps);
|
||||
|
||||
if (arch_from_caps != arch &&
|
||||
!((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
|
||||
(ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
|
||||
(ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
|
||||
(ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("architecture from emulator '%s' doesn't "
|
||||
"match given architecture '%s'"),
|
||||
virArchToString(arch_from_caps),
|
||||
virArchToString(arch));
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
if (!(qemuCaps = virQEMUCapsCacheLookupByArch(cache, arch)))
|
||||
goto cleanup;
|
||||
|
||||
binary = virQEMUCapsGetBinary(qemuCaps);
|
||||
}
|
||||
|
||||
if (machine) {
|
||||
/* Turn @machine into canonical name */
|
||||
machine = virQEMUCapsGetCanonicalMachine(qemuCaps, machine);
|
||||
|
||||
if (!virQEMUCapsIsMachineSupported(qemuCaps, machine)) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("the machine '%s' is not supported by emulator '%s'"),
|
||||
machine, binary);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
machine = virQEMUCapsGetDefaultMachine(qemuCaps);
|
||||
}
|
||||
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
|
||||
capsType = VIR_DOMAIN_VIRT_KVM;
|
||||
else
|
||||
capsType = VIR_DOMAIN_VIRT_QEMU;
|
||||
|
||||
if (virttype == VIR_DOMAIN_VIRT_NONE)
|
||||
virttype = capsType;
|
||||
|
||||
if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("KVM is not supported by '%s' on this host"),
|
||||
binary);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (retArch)
|
||||
*retArch = arch;
|
||||
if (retVirttype)
|
||||
*retVirttype = virttype;
|
||||
if (retMachine)
|
||||
*retMachine = machine;
|
||||
|
||||
VIR_STEAL_PTR(ret, qemuCaps);
|
||||
|
||||
cleanup:
|
||||
virObjectUnref(qemuCaps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
virQEMUCapsSupportsVmport(virQEMUCapsPtr qemuCaps,
|
||||
const virDomainDef *def)
|
||||
|
@ -563,6 +563,14 @@ virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virFileCachePtr cache,
|
||||
const char *machineType);
|
||||
virQEMUCapsPtr virQEMUCapsCacheLookupByArch(virFileCachePtr cache,
|
||||
virArch arch);
|
||||
virQEMUCapsPtr virQEMUCapsCacheLookupDefault(virFileCachePtr cache,
|
||||
const char *binary,
|
||||
const char *archStr,
|
||||
const char *virttypeStr,
|
||||
const char *machine,
|
||||
virArch *retArch,
|
||||
virDomainVirtType *retVirttype,
|
||||
const char **retMachine);
|
||||
|
||||
virCapsPtr virQEMUCapsInit(virFileCachePtr cache);
|
||||
|
||||
|
@ -19393,10 +19393,9 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
||||
char *ret = NULL;
|
||||
virQEMUDriverPtr driver = conn->privateData;
|
||||
virQEMUCapsPtr qemuCaps = NULL;
|
||||
int virttype = VIR_DOMAIN_VIRT_NONE;
|
||||
virDomainVirtType capsType;
|
||||
virArch arch;
|
||||
virDomainVirtType virttype;
|
||||
virDomainCapsPtr domCaps = NULL;
|
||||
int arch = virArchFromHost(); /* virArch */
|
||||
virQEMUDriverConfigPtr cfg = NULL;
|
||||
virCapsPtr caps = NULL;
|
||||
|
||||
@ -19410,80 +19409,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
||||
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
|
||||
goto cleanup;
|
||||
|
||||
if (virttype_str &&
|
||||
(virttype = virDomainVirtTypeFromString(virttype_str)) < 0) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unknown virttype: %s"),
|
||||
virttype_str);
|
||||
qemuCaps = virQEMUCapsCacheLookupDefault(driver->qemuCapsCache,
|
||||
emulatorbin,
|
||||
arch_str,
|
||||
virttype_str,
|
||||
machine,
|
||||
&arch, &virttype, &machine);
|
||||
if (!qemuCaps)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (arch_str && (arch = virArchFromString(arch_str)) == VIR_ARCH_NONE) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("unknown architecture: %s"),
|
||||
arch_str);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (emulatorbin) {
|
||||
virArch arch_from_caps;
|
||||
|
||||
if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
|
||||
emulatorbin)))
|
||||
goto cleanup;
|
||||
|
||||
arch_from_caps = virQEMUCapsGetArch(qemuCaps);
|
||||
|
||||
if (arch_from_caps != arch &&
|
||||
!((ARCH_IS_X86(arch) && ARCH_IS_X86(arch_from_caps)) ||
|
||||
(ARCH_IS_PPC(arch) && ARCH_IS_PPC(arch_from_caps)) ||
|
||||
(ARCH_IS_ARM(arch) && ARCH_IS_ARM(arch_from_caps)) ||
|
||||
(ARCH_IS_S390(arch) && ARCH_IS_S390(arch_from_caps)))) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("architecture from emulator '%s' doesn't "
|
||||
"match given architecture '%s'"),
|
||||
virArchToString(arch_from_caps),
|
||||
virArchToString(arch));
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache,
|
||||
arch)))
|
||||
goto cleanup;
|
||||
|
||||
emulatorbin = virQEMUCapsGetBinary(qemuCaps);
|
||||
}
|
||||
|
||||
if (machine) {
|
||||
/* Turn @machine into canonical name */
|
||||
machine = virQEMUCapsGetCanonicalMachine(qemuCaps, machine);
|
||||
|
||||
if (!virQEMUCapsIsMachineSupported(qemuCaps, machine)) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("the machine '%s' is not supported by emulator '%s'"),
|
||||
machine, emulatorbin);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
machine = virQEMUCapsGetDefaultMachine(qemuCaps);
|
||||
}
|
||||
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
|
||||
capsType = VIR_DOMAIN_VIRT_KVM;
|
||||
else
|
||||
capsType = VIR_DOMAIN_VIRT_QEMU;
|
||||
|
||||
if (virttype == VIR_DOMAIN_VIRT_NONE)
|
||||
virttype = capsType;
|
||||
|
||||
if (virttype == VIR_DOMAIN_VIRT_KVM && capsType == VIR_DOMAIN_VIRT_QEMU) {
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("KVM is not supported by '%s' on this host"),
|
||||
emulatorbin);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
|
||||
if (!(domCaps = virDomainCapsNew(virQEMUCapsGetBinary(qemuCaps), machine,
|
||||
arch, virttype)))
|
||||
goto cleanup;
|
||||
|
||||
if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
|
||||
|
Loading…
x
Reference in New Issue
Block a user