Libvirt is a virtualized library on Linux, a long-term stable C language API that supports Mainstream virtualization scenarios such as Kvm/qemu, Xen, LXC, and more. Links:http://libvirt.org/
Talking about scaling out computing, such as cloud computing, Libvirt is probably one of the most important libraries you've never heard of. Libvirt provides a hypervisor-agnostic API to securely manage the guest operating system running on the host. Libvirt is not a tool in itself , it is an API that can build tools to manage guest operating systems. Libvirt itself is built on an abstract concept. It provides a common API for commonly used functions implemented by supported Hypervisors. Libvirt was initially designed as a management API specifically for Xen, and was later extended to support multiple hypervisor applications.
Basic architecture
Let's start with the libvirt discussion from the use case model perspective, and then delve deeper into its architecture and purpose. Libvirt exists in the form of a set of APIs designed for use by management applications (see Figure 1). Libvirt communicates with each of the active hypervisor through a hypervisor-specific mechanism to complete API requests. I'll explore how to do this with QEMU later in the article.
Figure 1. Libvirt comparison and use case models
The figure also shows the terminology control used by Libvirt. These terms are important because they are used when naming the API. The two fundamental difference is that libvirt refers to a physical host as a node and a guest operating system as a domain . It is important to note that Libvirt (and its applications) run in the host Linux operating system (domain 0).
Control mode
Using Libvirt, we have two different ways of controlling it. The first is shown in Figure 1, where the management application and domain reside on the same node. In this example, the management application works through Libvirt to control the local domain. When management applications and domains reside on different nodes, another control is created. In this case, remote communication is required (see Figure 2). This mode uses a special daemon called Libvirtd , which runs on a remote node. The program automatically starts when Libvirt is installed on a new node and automatically determines and installs drivers for the local hypervisor (discussed later). The management application connects from the local libvirt to the remote LIBVIRTD through a common protocol. For QEMU, the protocol ends at the QEMU Monitor. QEMU includes a monitoring console that allows you to check the running guest operating system and control the parts of the virtual machine (VM).
Figure 2. Using LIBVIRTD to control remote virtual machine monitoring programs
Virtual Machine Monitoring Program support
To support the scalability of a variety of hypervisors, Libvirt implements a driver-based architecture that allows a common API to service a large number of potential hypervisor programs in a common way. This means that some of the specialized features of the hypervisor are not visible in the API. In addition, some hypervisors may not implement all of the API features and are therefore defined as unsupported within a specific driver. Figure 3 shows the hierarchical structure of the Libvirt API and related drivers. It is also important to note that LIBVIRTD provides a way to access the local domain from a remote application.
Figure 3. Driver-based Libvirt architecture
When writing this article, Libvirt implements the driver for the hypervisor listed in table 1. As new hypervisors appear in the open source community, other drivers will undoubtedly be available.
Table 1. Libvirt supported virtual machine monitoring programs
Virtual Machine Monitoring Program |
Description |
Xen |
Virtual machine monitor for ia-32,ia-64 and PowerPC 970 architectures |
Qemu |
Platform emulator for a variety of architectures |
kernel-based Virtual Machine (KVM) |
Linux Platform Emulator |
Linux Containers (LXC) |
Linux (lightweight) Containers for operating system virtualization |
Openvz |
Operating system-level virtualization based on the Linux kernel |
VirtualBox |
x86 Virtual Machine Monitoring Program |
User Mode Linux |
Linux platform Emulator for a variety of architectures |
Test |
Test drive for pseudo-Virtual machine monitoring Program |
Storage |
Storage pool drives (local disks, network disks, ISCSI volumes) |
Back to top of page
Libvirt and virtual shells
Some of the architecture of Libvirt has been described above, and then look at some examples of how to use the Libvirt virtualization API. First, introduce an application called Virsh(virtual shell), which is built on Libvirt. The shell allows multiple libvirt functions to be used in an interactive (shell-based) manner. In this section, I use Virsh to demonstrate some VM operations.
The first step is to define the domain configuration file (as shown in Listing 1 below). This code specifies all the options required to define the domain-from the hypervisor (emulator) to the resources used by the domain and the perimeter configuration (such as the network). Note that this is just a simple configuration, and the properties that Libvirt really support are more diverse. For example, you can specify the BIOS and host bootstrapper, the resources to be used by the domain, and the devices to be used-from floppy disks and CD-ROMs to USB and PCI devices.
The domain profile defines some of the basic metadata that the QEMU domain will use, including the domain name, maximum memory, the initial available memory (current), and the number of virtual processors available for that domain. Instead of assigning your own universally Unique Idenifier (UUID), you have libvirt assigned. You need to define the machine type to emulate for the platform-in this case, the 686 processor that is fully virtualized (HVM). You need to define the location of the emulator for your domain (for use when you need to support multiple emulators of the same type) and virtual disks. Note here to indicate the VM, which is a ReactOS operating system that exists in Virtual machine Disk (VMDK) format. Finally, you specify the default network settings and use the graphics-oriented Virtual network Computing (VNC).
Listing 1. Domain Configuration file
<xml version= "1.0"? ><domain type= ' Qemu ' > <name>ReactOS-on-QEMU<name> <uuid <uuid> <memory>131072<memory> <currentMemory>131072<currentMemory> <vcpu>1<vcpu> <os> <type arch= ' i686 ' machine= ' pc ' >hvm<type> <os> <devices> <emulator>usr/bin/qemu<emulator> <disk type= ' file ' device= ' disk ' > <source file= '/home/mtj/libvtest/reactos.vmdk '/> <target dev= ' hda '/> <disk > <interface type= ' network ' > <source network= ' default '/> <interface> <graphics type= ' vnc ' port= '-1 '/> <devices><domain>
Now that the domain profile is complete, start the domain using the Virsh tool. The Virsh tool takes command parameters for the specific action to be performed. When starting a new domain, use the create
command and domain configuration files:
Listing 2. Start a new domain
Virsh Create React-qemu.xml Connecting to Uri:qemu:///systemdomain Reactos-on-qemu created from React-qemu.xml[email protected]:~/libvtest$
Note here qemu:///system
the Universal Resource Indicator (URI) used to connect to the domain (). The local URI is connected to the local QEMU driver on the system-mode daemon. To connect to a remote QEMU hypervisor through the Secure Shell (SSH) protocol on host Shinchan, you can use the URL qemu+ssh://shinchan/.
Next, you can use the commands within Virsh to list
list the active domains on a given host. Doing so can list the active domain, the domain ID, and their status as follows:
Listing 3. List Active domains
Virsh List Connecting to Uri:qemu:///system Id Name ---------------------------------- 1 Reactos-on-qemu Running[email protected]:~/libvtest$
Note that the name defined here is the name defined in the metadata for the domain configuration file. As you can see, the domain's domain name is 1 and is running.
You can also abort the domain with a suspend
command. This command stops the domain in the schedule, but the domain still exists in memory and can be quickly resumed. The following example shows how to abort a domain, perform a list view status, and then restart the domain:
Listing 4. Abort the domain, check the status, and restart
Virsh suspend 1 Virsh List Connecting to Uri:qemu:///system Id Name ---------------------------------- 1 reactos-on-qemu Virsh Resume 1connecting to Uri:qemu:///systemdomain 1 resumed[email protected]:~/libvtest$
The Virsh tool also supports many other commands, such as saving a domain's command (), restoring a saved-domain command (), save
restore
restarting the domain's command ( reboot
), and other commands. You can also create a domain configuration file from a running domain ( dumpxml
).
So far, we've started and manipulated the domain, but how do we connect to the domain to see the current active domain? This can be done via VNC. To create a window that represents a specific domain graphical desktop, you can use VNC:
Listing 5. Connect to a domain
Xvnc4viewer 127.0.0.1 0
Back to top of page
Libvirt and Python
The previous example shows how to use the command-line tool Virsh to implement control of the domain. Now let's look at an example of using Python to control the domain. Python is a scripting language supported by Libvirt, which provides a fully object-oriented interface to the Libvirt API.
In this example, I studied some basic operations similar to those previously shown with the Virsh tool (,, and list
suspend
so on resume
). The Python sample script is shown in Listing 6. In this example, we start by importing the Libvirt module. Then connect to the local QEMU hypervisor. From here, repeat the available domain IDs, create a domain object for each ID, then abort, continue, and finally delete the domain.
Listing 6. Sample Python script for controlling the domain (libvtest.py)
Import libvirtconn = Libvirt.open (' Qemu:///system ') for ID in conn.listdomainsid ():d om = Conn.lookupbyid (ID) print "Dom%s State %s "% (Dom.name (), Dom.info () [0]) dom.suspend () print" Dom%s State%s (after suspend) "% (Dom.name (), Dom.info () [0]) Dom.resume () print ' Dom%s state%s ' after Resume '% (dom.na Me (), Dom.info () [0]) Dom.destroy ()
While this is a simple example, we can still see the powerful features that Libvirt provides through Python. With a simple script, you can repeat all local QEMU domains, issue information about the domain, and then control the domain. The result of the script is shown in listing 7 .
Listing 7. The result of the Python script output in Listing 6
python libvtest.py Dom Reactos-on-qemu State 1Dom Reactos-on-qemu State 3 (after suspend) Dom Reactos-on-qemu State 1 (after Resume) [Email protected]:~/libvtest$
Back to top of page
API Overview
The Advanced Libvirt API can be divided into 5 API parts: Hypervisor connection API, domain API, network API, storage volume API, and storage pool API.
Creating a connection for a given hypervisor generates all LIBVIRT traffic (for example, the call shown in Listing 6 open
). This connection provides the path for all other APIs to be used. In the C
API, this behavior is virConnectOpen
provided by invocation (and other authentication calls). The return value of these functions is an virConnectPtr
object that represents a connection to the hypervisor. This object serves as the basis for all other administrative functions and is necessary for a given hypervisor to make concurrent API calls. Important concurrent calls are virConnectGetCapabilities
and virNodeGetInfo
, in return, the functionality of the hypervisor and the driver, which gets information about the node. This information is returned as an XML document, so that you can understand the behavior that might occur by parsing.
After you enter the hypervisor, you can reuse the various resources on the hypervisor using a set of API call functions. The virConnectListDomains
API call function returns a list of domain identifiers that represent the active domain on the hypervisor.
The API implements a large number of domain-specific functions. To explore or manage a domain, you first need an virDomainPtr
object. There are several ways you can get the handle (using ID, UUID, or domain name). To continue with the example of a repeating field, you can use the index table returned by the function and call virDomainLookupByID
to get the domain handle. With this domain handle, you can do a lot of things, from exploring domains (,,, virDomainGetUUID
virDomainGetInfo
virDomainGetXMLDesc
virDomainMemoryPeek
) to control domains (,,, virDomainCreate
virDomainSuspend
virDomainResume
virDomainDestroy
and virDomainMigrate
).
You can also use the API to manage and examine virtual networks and storage resources. Once the API model is established, an virNetworkPtr
object is required to manage and examine the virtual network, and a virStoragePoolPtr
(storage pool) or virStorageVolPtr
(volume) object is required to manage these resources.
The API also supports an event mechanism that you can use to register to be notified when a particular event occurs, such as when a domain is started, aborted, resumed, or stopped.
Back to top of page
Language binding
The Libvirt Library is C
implemented with (support C++
) and includes direct support for Python. However, it also supports a large number of language bindings. Bindings have been implemented for Ruby, Java™ language, Perl, and OCaml. C#
we have done a lot of work in terms of calling Libvirt. Libvirt supports the most popular system programming languages ( C
and C++
), multiple scripting languages, and even a unified functional language (Objective CAML). So, no matter what language you focus on, Libvirt provides a path to help you control your domain.
Back to top of page
Applications that use Libvirt
The powerful features provided by Libvirt can be seen only from a small subset of the features shown in this article. And as you wish, there are a number of applications that are successfully built on Libvirt. One of the interesting applications is Virsh (shown here), which is a virtual shell. There is also an application called Virt-install, which can be used to supply a new domain from multiple operating system distributions. Virt-clone can be used to replicate VMS from another VM, including both OS replication and disk replication. Some advanced applications include the Multipurpose Desktop management tool Virt-manager and the lightweight tool virt-viewer that securely connects to the VM graphics console.
One of the most important tools built on Libvirt is named oVirt. The OVirt VM Management application is designed to manage a large number of VMS on a single VM or on multiple hosts on a single node. In addition to simplifying the management of a large number of hosts and VMS, it can also be used to automate clusters across platforms and architectures, load balancing, and work.
Back to top of page
Deep Dive
As you can see from this short article, Libvirt is a powerful library for building applications that can manage domains in different hypervisor environments across large networks of systems. Given the growing popularity of cloud computing, Libvirt will undoubtedly evolve, gaining access to new applications and users. At the time of writing, Libvirt also had a history of only four years, so it was relatively new in the field of large scale scalable computing. Libvirt will certainly have a great development in the future.
Anatomy of a Libvirt virtual library