libvirt architecture

This is in a large part Xen specific since this is the only hypervisor supported at the moment

When running in a Xen environment, programs using libvirt have to execute in "Domain 0", which is the primary Linux OS loaded on the machine. That OS kernel provides most if not all of the actual drivers used by the set of domains. It also runs the Xen Store, a database of informations shared by the hypervisor, the kernels, the drivers and the xen daemon. Xend. The xen daemon supervise the control and execution of the sets of domains. The hypervisor, drivers, kernels and daemons communicate though a shared system bus implemented in the hypervisor. The figure below tries to provide a view of this environment:

The Xen architecture

The library can be initialized in 2 ways depending on the level of priviledge of the embedding program. If it runs with root access, virConnectOpen() can be used, it will use three different ways to connect to the Xen infrastructure:

  • a connection to the Xen Daemon though an HTTP RPC layer
  • a read/write connection to the Xen Store
  • use Xen Hypervisor calls

The library will usually interract with the Xen daemon for any operation changing the state of the system, but for performance and accuracy reasons may talk directly to the hypervisor when gathering state informations at least when possible (i.e. when the running program using libvirt has root priviledge access).

If it runs without root access virConnectOpenReadOnly() should be used to connect to initialize the library. It will try to open the read-only socket /var/run/xenstored/socket_ro to connect to the Xen Store and also try to use the RPC to the Xen daemon. In this case use of hypervisor calls and write to the Xen Store will not be possible, restraining the amount of APIs available and slowing down information gathering about domains.

Internal architecture

As the previous section explains, libvirt can communicate using different channels with the current hypervisor, and should also be able to use different kind of hypervisor. To simplify the internal design, code, ease maintainance and simplify the support of other virtualization engine the internals have been structured as one core component, the libvirt.c module acting as a front-end for the library API and a set of hypvisor drivers defining a common set of routines. That way the Xen Daemon accces, the Xen Store one, the Hypervisor hypercall are all isolated in separate C modules implementing at least a subset of the common operations defined by the drivers present in driver.h:

  • xend_internal: implements the driver functions though the Xen Daemon
  • xs_internal: implements the subset of the driver availble though the Xen Store
  • xen_internal: provide the implementation of the functions possible via direct hypervisor access

Note that a given driver may only implement a subset of those functions, for example saving a domain state to disk and restoring it is only possible though the Xen Daemon, on the other hand all interfaces allow to query the runtime state of a given domain.