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 -=|