[Libvir] Proposed XML format for capabilities, with examples [long]

Richard W.M. Jones rjones at redhat.com
Wed Mar 14 11:59:57 UTC 2007


Lots of people had various things to say about the first capabilities 
patches (see thread starting here: 
https://www.redhat.com/archives/libvir-list/2007-March/msg00153.html). 
So I thought I'd try to pull together ideas into a single thread, and 
post some information about what this is trying to achieve and some 
example proposed XML.


Motivation
----------

At the moment there is a considerable amount of conditional code in 
libvirt clients.  For example the following code from virt-manager 
(src/virtManager/create.py):

   if self.connection.get_type() == "QEMU":    <------- 1
       self.window.get_widget("virt-method-pv").set_sensitive(False)
       self.window.get_widget("virt-method-fv").set_active(True)
       self.window.get_widget("virt-method-fv-unsupported").hide()
       self.window.get_widget("virt-method-fv-disabled").hide()
   else:
       self.window.get_widget("virt-method-pv").set_sensitive(True)
       self.window.get_widget("virt-method-pv").set_active(True)
       if virtinst.util.is_hvm_capable():      <--------- 2
           self.window.get_widget("virt-method-fv").set_sensitive(True)
           self.window.get_widget("virt-method-fv-unsupported").hide()
           self.window.get_widget("virt-method-fv-disabled").hide()

This hopefully demonstrates two points which I'd like to fix: Firstly 
having code which requires knowledge of what a driver is capable of 
(line 1 above) is not scalable as we add more and more types of 
virtualisation (OpenVZ, VMWare, ...).  Secondly the virtinst.util module 
does some probing to find out what the local hardware is capable of 
(line 2 above), and that won't work over remote connections.

Thirdly, although you can only really connect to one driver at a time 
(except in the Xen case, but that's just weird), the <domain> 
description required by virDomainCreateLinux is to some extent 
driver-specific.  So you need additional logic when creating domains, 
and for some of those (eg. qemu/kqemu/kvm) it's non-trivial and depends 
on information that you "just know" about the driver.

The proposed new API ("virConnectGetCapabilities") would return an XML 
description of the capabilities of the driver / hypervisor.  In the 
remote case, probing would be done on the remote machine.  In either 
case the idea would be to remove conditional code from virt-manager, 
remove local hardware probing from virtinst, and provide some 
description of what optional features the <domain> XML supports.

In the next two sections I'll analyse the problem areas in the current 
virtinst and virt-manager.  You may want to skip the next two sections 
and go straight to the example XML.


Analysis of virtinst
--------------------

The main issue is with virtinst/util.py which contains the following 
functions which do local probing:

(1) is_pae_capable: host supports PAE? Uses Linux-specific /proc/cpuinfo

(2) is_hvm_capable: host supports HVM & enabled in Xen? Uses 
Xen-specific /sys/hypervisor/properties/capabilities

(3) is_kqemu_capable: [Linux] kernel supports kqemu?  Uses 
Linux-specific /dev/kqemu

(4) is_kvm_capable: [Linux] kernel supports kvm?  Uses Linux-specific 
/dev/kvm

In virtinst/FullVirtGuest.py:

(5) "emulator" and "loader" must be specified for Xen/QEMU and Xen 
guests respectively.  They have architecture- and distro-specific paths 
which refer to files on the remote machine.

In virtinst/ParaVirtGuest.py:

(6) Uses "xm console" to connect to the console in the Xen case (but 
then this sort of paravirtualisation implies Xen).

In virtinst/DistroManager.py:

(7) We download the kernel and boot.iso files, and download and modify 
the initrd file. [Comment: I'm not sure that capabilities can solve 
this, but it does need to be fixed properly for the remote case to work].


Analysis of virt-manager
------------------------

In src/virtManager/create.py:

(8) Tries to detect if VT-x/AMD-V is present in the hardware but 
disabled in the BIOS by doing some Xen-specific heuristics.

(9) Paravirt and fullvirt dialogs are enabled based on the type of the 
connection (eg. if self.connection.get_type() == "QEMU" it disables 
paravirt).

(10) CPU architecture combo box is enabled only for type == "QEMU".

(11) Similarly, the "accelerate" checkbox is enabled only for type == 
"QEMU".  [Comment: Dan tells me that this requirement comes about 
because kqemu is sometimes unreliable, so users need a way to disable it].

(12) Local media are required for FV installs.  Also we use HAL to 
detect media inserted and removed. [Comment: Can be solved separately by 
abstracting storage].

In the *.glade files:

(13) The list of CPU architectures for qemu is hard-coded in the 
interface description file.

Other areas which are beyond the role of capabilities:
  * Remote console
  * Serial console
  * Saving images


Proposed XML format
-------------------

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).


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>


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>


Guest architectures: Cartesian product or UI builder?
-----------------------------------------------------

Currently the list of guest architectures is a flat list, worst case 5 
entries long for Xen and 14 entries long for qemu.  Presenting this in 
user interfaces could be challenging.

One suggestion is that the user interface looks like:

   [*] Show only fullvirt
   [*] Show only PC architectures
   [ ] Show 32 bit architectures
   [*] Show 64 bit architectures

   | Shorter list of architectures which match
   | the criteria checked above.
   | ...
   |

Another is that we change the XML description so that it matches the UI. 
  For instance:
   <guest_architecture>
     <models> <model> sparc </model> <model> ppc </model> ...

Or:
   <pae> <can_enable/> <can_disable/> </pae>

This is relatively easy to do with qemu, but the format of Xen's 
/sys/hypervisor/properties/capabilities makes it quite hard.


i18n
----

Some proposed features may make translation challenging.  For example 
qemu supports a whole list of machine types ("pc", "sun4m", etc.) and it 
would be nice for libvirt clients to be able to provide some sort of 
description for the user.  It would not be wise to carry this 
description in the XML because it would not be possible to localise it.

To avoid all libvirt clients duplicating and maintaining lists of 
machine types and descriptions, it may be worth adding a call to the API 
along the lines of:

   virConnectGetMachineDescription (const char *machine_name,
                                    const char *lang);
(where lang == NULL would mean to use the current language).

[EOF]



-- 
Emerging Technologies, Red Hat  http://et.redhat.com/~rjones/
64 Baker Street, London, W1U 7DF     Mobile: +44 7866 314 421
  "[Negative numbers] darken the very whole doctrines of the equations
  and make dark of the things which are in their nature excessively
  obvious and simple" (Francis Maseres FRS, mathematician, 1759)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3237 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20070314/91e3a97e/attachment-0001.bin>


More information about the libvir-list mailing list