[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



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)

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]