Home > Articles > Operating Systems, Server

  • Print
  • + Share This
Like this article? We recommend libvirt: A Virtualization API

libvirt: A Virtualization API

libvirt provides an API that allows software access to VM facilities. Some of the key items to note in the libvirt lexicon are the following:

  • Node - A single physical machine.
  • Hypervisor - A layer of software that allows the virtualization of a node in a set of VMs.
  • Domain - An instance of an operating system running on a VM provided by the hypervisor.

Let's try to make this all a bit more concrete by actually running some code. Listing 1 illustrates the program output from a simple libvirt client when no VMs are running on the host Ubuntu system.

Listing 1—Enumerating QEMU Domains with libvirt

Hello World!

 Hypervisor version 8003

 Type QEMU

 NumOfDefinedDomains 2

 URI qemu:///system

Domain:MyKVMVirtualMachine id -1 running OS hvm host name stephen-Latitude-E5400 hypervisor version 8003

Domain state: VIR_DOMAIN_SHUTOFF

Listing 1 illustrates what is essentially an empty virtual environment—i.e., no VMs are running. Notice however, that libvirt has identified that two domains have been created but that the domain state is VIR_DOMAIN_SHUTOFF—i.e., no VMs are running.

How do I acquire the information in Listing 1? It's not too difficult; in Listing 2, you see the Java code that produces the output in Listing 1.

Listing 2—The libvirt API in Action

   Connect conn = new Connect("qemu:///system", true);                                            

   System.out.println(" Hypervisor version "

                    + conn.getHypervisorVersion(null));

   System.out.println(" Type " + conn.getType());

   System.out.println(" NumOfDefinedDomains "

            + conn.numOfDefinedDomains());

   System.out.println(" URI "

            + conn.getURI());

   Domain testDomain = conn.domainLookupByName("MyKVMVirtualMachine");

   System.out.println("Domain:" + testDomain.getName() + " id "

             + testDomain.getID() + " running OS "

             + testDomain.getOSType() + " host name "

             + conn.getHostName() + " hypervisor version "

             + conn.getHypervisorVersion(null));

   System.out.println("Domain state: " + testDomain.getInfo().state.name());

The first action in Listing 2 is to instantiate a Connect instance. This object is then used to communicate with the hypervisor; in this case, the hypervisor is QEMU/KVM. I enumerate the version of the hypervisor before reading the number of domains associated with that hypervisor. I then do a domain lookup of one of the VMs by name. Finally, the details of the underlying VM are enumerated.

Let's now build on the output from Listing 1 by interacting with the QEMU/KVM hypervisor and by running one of its defined VMs. On Ubuntu, I do this by running the abovementioned program Virtual Machine Manager from the Applications > System Tools menu. This results in the display illustrated in Figure 1.

Comparing Figure 1 with Listing 1, you can see that there are indeed two QEMU/KVM VMs defined and that both of them are in the “not running” or “shutoff” state. Let's now run one of the VMs. You do this by selecting one of the VMs in Figure 1 and clicking the green start button, which results in the contents displayed in Figure 2.

Figure 2 Running one of the virtual machines on the Ubuntu host

In passing, notice in Figure 2 the CPU usage graphic starts to indicate activity in the VM. This is a nice way of showing you that the VM is beginning to consume resources in the underlying platform. Also, note that the state of the VM changes to “Running”.

I've always felt that graphical tools are invaluable for giving rapid insight into the operation of even the most complex software systems!

So, what effect does this newly running VM in Figure 2 have on the Listing 2 libvirt Java code? Let's run it again to see, with the result displayed in Listing 3.

Listing 3—One VM Running

Hello World!

 Hypervisor version 8003

 Type QEMU

 NumOfDefinedDomains 1

 URI qemu:///system

Domain:MyKVMVirtualMachine id 2 running OS hvm host name stephen-Latitude-E5400 hypervisor version 8003

Domain state: VIR_DOMAIN_RUNNING

In Listing 3, you can see the domain state is now VIR_DOMAIN_RUNNING. The Java code in Listing 2 is now mirroring the (now running) VM state. Notice also that the domain name 'stephen-Latitude-E5400' has been displayed in Listing 3.

Clearly, if we're using virtualization in a commercial or corporate context, we'll need to run many VMs. Indeed, in large corporate data centers, it's commonplace to have many thousands of VMs running constantly. How do we modify the Listing 2 Java code to see more than one VM?

Well, because we're now going to address two VMs, a small modification to the code is required, as illustrated in Listing 4. The change I made is to extract (or refactor) the displaying of the domain details into a separate method called displayDomainDetails(). This method is then called for each of the two domains.

Listing 4—Minor libvirt Code Change

    private static void displayDomainDetails(Connect conn, Domain testDomain)

            throws LibvirtException {

        System.out.println("Domain:" + testDomain.getName() + " id "

         + testDomain.getID() + " running OS "

         + testDomain.getOSType() + " host name "

         + conn.getHostName() + " hypervisor version "

         + conn.getHypervisorVersion(null));

        

        System.out.println("Domain state: " + testDomain.getInfo().state.name());

    }

    

    public static void main(String[] args) {

        System.out.println("Hello World!");

        Connect conn = null;

        try {

            conn = new Connect("qemu:///system", true);

            System.out.println(" Hypervisor version "

                    + conn.getHypervisorVersion(null));

            System.out.println(" Type " + conn.getType());

            System.out.println(" NumOfDefinedDomains "

                    + conn.numOfDefinedDomains());

            System.out.println(" URI "

                    + conn.getURI());

            Domain testDomain1 = conn.domainLookupByName("MyKVMVirtualMachine");

            Domain testDomain2 = conn.domainLookupByName("MyKVMVirtualMachine-clone");

            displayDomainDetails(conn, testDomain1);

            displayDomainDetails(conn, testDomain2);

With the Java code changed, let's now run the second VM, and again review the program output as illustrated in Listing 5.

Listing 5—Two VMs Running

Hello World!

 Hypervisor version 8003

 Type QEMU

 NumOfDefinedDomains 0

 URI qemu:///system

Domain:MyKVMVirtualMachine id 2 running OS hvm host name stephen-Latitude-E5400 hypervisor version 8003

Domain state: VIR_DOMAIN_RUNNING

Domain:MyKVMVirtualMachine-clone id 3 running OS hvm host name stephen-Latitude-E5400 hypervisor version 8003

Domain state: VIR_DOMAIN_RUNNING

So, from Listing 5, you can see the way libvirt allows us to programmatically view the contents of the host VMs running inside the QEMU/KVM hypervisor. What else can we do with the Virtual Machine Manager program?

  • + Share This
  • 🔖 Save To Your Account