On 08/03/2016 04:49 PM, Eduardo Habkost wrote:
Hi,
I am collecting some material for my KVM Forum talk, and I am
interested in hearing from libvirt developers about instances
where machine-type-specific information is needed by libvirt, and
the info is not provided by QEMU.
I found some instances where machine-type capabilities are
hardcoded in libvirt itself (see below[1]), but I would like to
know if you have other examples. They may be about things that
are already done by libvirt today, or about things that you would
like to do in the future.
(I'm guessing this first one may be what put you onto the topic in the
first place, but for completeness' sake...)
Without actually instantiating a virtual machine of a particular type,
It's not possible to know whether that machinetype has a legacy-pci root
bus, or a PCIe root complex (or neither). This means we have to guess,
and it has big implications. In some cases our guess is 100% correct
(i440fx and q35 machinetypes inqemu-system-x86_64) but in other cases we
may or may not be right (the aarch64 "virt" machinetype, which as I
understand may or may not have a PCIe root complex, depending on the
qemu version?)
This in turn leads to differences in which PCI controllers are available
for a machinetype (e.g., even though the ioh3420 (pcie-root-port) device
is advertised as available in qemu-system_x86_64, it's only actually
usable for q35-based machinetypes; same for pxb-pcie, and the xio3130
upstream/downstream ports.
Same thing goes for some other integrated devices - Q35-based
machinetypes include an AHCI controller while i440fx machinetypes (as
well as "sun4u" and "g3beige") include an IDE controller, and these
are
at fixed addresses (and can't be removed).
And then there is the Q35 machinetype vs. fdc. Yeah, sure nobody in this
age should be using a floppy disk (even emulated), but even within
different versions of the q35 machinetype, a floppy disk controller may
or may not be present (see qemuDominMachineNeedsFDC()).
You may say that libvirt could solve this problem when probing qemu
capabilities by simply instantiating a virtual machine and then
examining its devices, but (I've been told) this is too expensive
(especially since we'd need to do it for every machinetype that was
used, although admittedly we've been caching the results for quite
awhile now, so the impact may not be as great as it once was).
[1] Examples where machine-type names are hardcoded in libvirt:
Keep in mind that some of those places we're checking os.machine are
actually utility functions whose only job is to check the machinetype
and return true/false, and they're called from several other places. For
example qemuDomainMachineIsQ35(), qemuDomainMachineIs440FX(), and
qeuDomainMachineIsVirt() (which actually checks if the arch is armv7l or
aarch64 *and* machinetype is "virt*").
Which points out - it's a slightly different issue (since in these cases
at least it's a different qemu binary), but you may also want to look at
places where we examine "os.arch" and make a decision based on that.
src/qemu/qemu_capabilities.c: STREQ(def->os.machine, "ppce500"))
src/qemu/qemu_capabilities.c: STREQ(def->os.machine, "prep"))
src/qemu/qemu_capabilities.c: STREQ(def->os.machine, "bamboo"))
src/qemu/qemu_capabilities.c: if (STREQ(def->os.machine,
"mpc8544ds"))
src/qemu/qemu_capabilities.c: if (STREQ(machines[i]->name, "none"))
src/qemu/qemu_capabilities.c: STREQ(def->os.machine, "isapc");
src/qemu/qemu_capabilities.c: (STRNEQ(machine, "pseries") &&
!STRPREFIX(machine, "pseries-")))
src/qemu/qemu_capabilities.c: (STRNEQ(machine, "pseries") &&
!STRPREFIX(machine, "pseries-")))
src/qemu/qemu_capabilities.c: if (STRNEQ(domCaps->machine, "virt")
&&
src/qemu/qemu_capabilities.c: !STRPREFIX(domCaps->machine, "virt-"))
src/qemu/qemu_command.c: if (STRPREFIX(def->os.machine, "s390-virtio")
&&
src/qemu/qemu_domain.c: if (STREQ(def->os.machine, "isapc")) {
src/qemu/qemu_domain.c: if (STREQ(def->os.machine, "versatilepb"))
src/qemu/qemu_domain.c: return (STRPREFIX(def->os.machine, "pc-q35") ||
src/qemu/qemu_domain.c: STREQ(def->os.machine, "q35"));
src/qemu/qemu_domain.c: return (STREQ(def->os.machine, "pc") ||
src/qemu/qemu_domain.c: STRPREFIX(def->os.machine, "pc-0.") ||
src/qemu/qemu_domain.c: STRPREFIX(def->os.machine, "pc-1.") ||
src/qemu/qemu_domain.c: STRPREFIX(def->os.machine, "pc-i440") ||
src/qemu/qemu_domain.c: STRPREFIX(def->os.machine, "rhel"));
src/qemu/qemu_domain.c: char *p = STRSKIP(def->os.machine, "pc-q35-");
src/qemu/qemu_domain.c: return STRPREFIX(def->os.machine, "s390-ccw");
src/qemu/qemu_domain.c: if (STRNEQ(def->os.machine, "virt") &&
src/qemu/qemu_domain.c: !STRPREFIX(def->os.machine, "virt-"))
src/qemu/qemu_domain.c: if (STRNEQ(def->os.machine, "pseries")
&&
src/qemu/qemu_domain.c: !STRPREFIX(def->os.machine, "pseries-"))
src/qemu/qemu_domain.c: STREQ(def->os.machine, "malta") ||
src/qemu/qemu_domain.c: STREQ(def->os.machine, "sun4u") ||
src/qemu/qemu_domain.c: STREQ(def->os.machine, "g3beige");
src/qemu/qemu_domain_address.c: if (!(STRPREFIX(def->os.machine,
"vexpress-") ||
src/qemu/qemu_domain_address.c: if (STREQ(def->os.machine,
"versatilepb"))