
On Wed, Mar 14, 2007 at 11:59:57AM +0000, Richard W.M. Jones wrote:
My thoughts are that capabilities need to return the following information about the underlying driver/hypervisor:
* Host CPU flags (1,8) * List of guest architectures supported. For each of these: - Model of virtualised CPU (10,13) example: x86_64 - Name of the virtualised machine (if applic.) example: pc - Virtualised CPU features: PAE, ... - Fullvirt flag: can we run an unmodified OS as a guest? (2,9) or Paravirt: what sort of paravirt API does a guest need (eg. xen, pvops, VMI, ...)? - The <domain type='?'> for this guest example: kqemu - The <domain><os><type machine='?'> for this guest (if applic.) example: pc - Suggested emulator and loader paths (5) - Driver-specific flags which libvirt clients would not be required to understand, but could be used to enhance libvirt clients. examples: uses kqemu, uses kvm (3,4,11)
(Notes: (a) I have flattened qemu's nested arch/machine list, because I there is not a natural hierarchy. (b) The guest architectures list is a Cartesian product, although at the moment the worst case (qemu) would only have about 14 entries. An alternate way to do this is discussed at the end. (c) The host CPU model is already provided by virNodeGetInfo).
Currently this shows a Cartesian product of (arch,ostype,domaintype,flags) but I think we should reduce it to merely (arch,ostype) and use a slightly more heirarchical structure. The domaintype & flags only really add a slight specialization of the basic (arch,ostype) info, so I think it is worthwhile. Also rather than having '<paravirt>xen</paravirt>' and '<fullyvirt/>' I think we should just call it 'os_type' since this info is used to populate the <os><type>..</type></os> field in the domain XML. A second reason is that KVM is very likely to blur the boundaries between paravirt & fullyvirt. ie, KVM is in its heart a fullyvirt system, but it supports various paravirt extensions - a fullyvirt guest OS can detect these paravirt extensions & make use of them on the fly. So its better not to express a hard paravirt/fullyvirt split in the XML. So I'm suggesting just <os_type>xen</os_type> and <os_type>hvm</os_type>
Example: Xen ------------
For Xen the primary source for capabilities are the files /sys/hypervisor/properties/capabilities and /proc/cpuinfo. A Xen driver might present the following description of its capabilities:
<capabilities> <host> <cpu_flags> <cpu_flag> vmx </cpu_flag> <cpu_flag> pae </cpu_flag> <!-- etc --> </cpu_flags> </host>
<guest_architectures> <guest_architecture> <model> x86_64 </model> <paravirt> xen </paravirt> <domain_type> xen </domain_type> <emulator> /usr/lib/xen/bin/qemu-dm </emulator> </guest_architecture>
<guest_architecture> <model> i686 </model> <pae/> <paravirt> xen </paravirt> <domain_type> xen </domain_type> <emulator> /usr/lib/xen/bin/qemu-dm </emulator> </guest_architecture>
<guest_architecture> <model> i686 </model> <fullvirt/> <domain_type> xen </domain_type> <loader> /usr/lib/xen/boot/hvmloader </loader> <emulator> /usr/lib/xen/bin/qemu-dm </emulator> </guest_architecture>
<guest_architecture> <model> i686 </model> <pae/> <fullvirt/> <domain_type> xen </domain_type> <loader> /usr/lib/xen/boot/hvmloader </loader> <emulator> /usr/lib/xen/bin/qemu-dm </emulator> </guest_architecture>
<guest_architecture> <model> x86_64 </model> <fullvirt/> <domain_type> xen </domain_type> <loader> /usr/lib/xen/boot/hvmloader </loader> <emulator> /usr/lib/xen/bin/qemu-dm </emulator> </guest_architecture> </guest_architectures> </capabilities>
This would look like: <capabilities> <host> <cpu> <arch>x86_64</arch> <features> <vmx/> <pae/> </features> </cpu> </host> <!-- xen-3.0-x86_64p --> <guest> <os_type>xen</os_type> <arch name="x86_64"> <wordsize>64</wordsize> <domain type="xen"/> </arch> <features> <pae/> </features> </guest> <!-- xen-3.0-x86_32p --> <guest> <os_type>xen</os_type> <arch name="i686"> <wordsize>32</wordsize> <domain type="xen"/> </arch> <features> <pae/> </features> </guest> <!-- hvm-3.0-x86_64p --> <guest> <os_type>hvm</os_type> <arch name="x86_64"> <machine >pc</machine> <machine>isapc</machine> <emulator>/usr/lib/xen/qemu-dm</emulator> <loader>/usr/lib/xen/hvmloader</loader> <domain type="xen"/> </arch> <features> <pae/> <nonpae/> </features> </guest> <!-- hvm-3.0-x86_64p --> <guest> <os_type>hvm</os_type> <arch name="i686"> <machine >pc</machine> <machine>isapc</machine> <emulator>/usr/lib/xen/qemu-dm</emulator> <loader>/usr/lib/xen/hvmloader</loader> <domain type="xen"/> </arch> <features> <pae/> <nonpae/> </features> </guest> </capabilities> Notice I have an expliciyt '<nonpae/>' flag, because PAE is really a tri-state. A domain can support PAE, or none-PAE or both.
Example: qemu + kqemu + kvm ---------------------------
Qemu has by far the longest list of supported guest architectures. Out of the box it supports 10 distinct machine types and then you can add 4 extra machine types if the kernel can do kqemu and kvm, making 14 in all. Below I have abbreviated this list for clarity.
<capabilities> <host> <cpu_flags> <cpu_flag> vmx </cpu_flag> <cpu_flag> pae </cpu_flag> <!-- etc --> </cpu_flags> </host>
<guest_architectures> <guest_architecture> <model> sparc </model> <machine> sun4m </machine> <fullvirt/> <domain_type> qemu </domain_type> <machine_type> sun4m </machine_type> <emulator> /usr/bin/qemu-system-sparc </emulator> </guest_architecture>
<guest_architecture> <model> i686 </model> <machine> pc </machine> <fullvirt/> <domain_type> qemu </domain_type> <machine_type> pc </machine_type> <emulator> /usr/bin/qemu </emulator> </guest_architecture>
<guest_architecture> <model> x86_64 </model> <machine> pc </machine> <fullvirt/> <domain_type> kqemu </domain_type> <machine_type> pc </machine_type> <emulator> /usr/bin/qemu </emulator> <qemu_uses_kqemu /> </guest_architecture>
<guest_architecture> <model> x86_64 </model> <machine> pc </machine> <fullvirt/> <domain_type> kvm </domain_type> <machine_type> pc </machine_type> <emulator> /usr/bin/qemu-kvm </emulator> <qemu_uses_kvm /> </guest_architecture> </guest_architecture> </capabilities>
<capabilities> <host> <cpu> <arch>x86_64</arch> <features> <vmx/> <pae/> </features> </cpu> </host> <guest> <os_type>hvm</os_type> <arch name="x86_64"> <wordsize>64</wordsize> <machine >pc</machine> <machine>isapc</machine> <emulator>/usr/bin/qemu-system-x86_64</emulator> <domain type="qemu"/> <domain type="kqemu"/> <domain type="kvm"> <emulator>/usr/bin/qemu-kvm</emulator> </domain> </arch> <features> <pae/> <nonpae/> </features> </guest> <guest> <os_type>hvm</os_type> <arch name="i686"> <wordsize>32</wordsize> <machine >pc</machine> <machine>isapc</machine> <emulator>/usr/bin/qemu</emulator> <domain type="qemu"/> </arch> <features> <nonpae/> </features> </guest> <guest> <os_type>hvm</os_type> <arch name="sparc"> <wordsize>32</wordsize> <machine >sun4m</machine> <emulator>/usr/bin/qemu-system-sparc</emulator> <domain type="qemu"/> </arch> <features> <pae/> <nonpae/> </features> </guest> <guest> <os_type>hvm</os_type> <arch name="ppc"> <wordsize>32</wordsize> <machine>prep</machine> <machine>g3bw</machine> <machine>mac99</machine> <emulator>/usr/bin/qemu-system-ppc</emulator> <domain type="qemu"/> </arch> <features> <pae/> <nonpae/> </features> </guest> </capabilities> Notice in this example, that the <domain type='kvm'> block inside the the <arch> can override / specialize arch data. eg we provide an alternate <emulator> block for KVM. Als notice mutliple <machine> elements - the first is taken to be the implicit default machine. Alternatively we could add an explicit default="true" attribute. So in summary, with Xen this results in N * <guest> blocks where N equals the number of entries in /sys/hypervisor/properties/capabilities, and with QEMU N == number of QEMU architectures (ie 7). Regards, Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|