From: http://wz.csdn.net/item/2416458/
Test xen monitoring based on libvirt API
Favorites
The computer architecture course provides a large assignment. By using the xen API or a function library that encapsulates its API, such as libvirt, programming, the following functions are implemented:
- Displays the name of the running client (Guest OS) on the host machine (host OS) as a command line;
- The command line interface is used to display the working status of the specified client (Guest OS) (displaying its CPU utilization and memory usage );
This job project is similar to the built-in XM Management Program in Linux systems such as fedora. Here, the XM top function is simply implemented. I chose Fedora Core 8 as the host OS. Install another Fedora Core 8 as the guest OS through xen. Use the APIS provided by libvirt to display the guest OS name, CPU usage, and memory usage. Compare with the running results of XM and virt-manager to verify the correctness.
Install the required software package:
- Xen-3.1.2-2.fc8
- Libvirt-o.4.2-1.fc8
- Libvirt-devl-0.4.2-1.fc8
Specifically, xen is a virtual machine, libvirt is the Runtime Library, and libvirt-devl is the code Runtime Library for development and compilation. The specific version depends on the dependency between the installation source and other components of the system.
A small problem occurred when I installed Guest OS using xen: the default SELinux service in Fedora Core 8 has an impact on xen, it is estimated that the transmission of some semaphores may be blocked. By modifying/etc/sysconfig/SELinux, SELinux = disabled will disable SELinux.
Install Guest OS through virt-manager or virt-install. Set to MB memory, 4 GB hard disk space, and semi-virtualization mode.
Use of the libvirt API:
Virconnectptr virconnectopenreadonly (const char * name) |
Call this function to obtain the connection of the hypervisor. |
Name |
Uri of hypervisor. If it is null, it indicates a local link. |
Returns |
Returns the hypervisor pointer. |
Int virconnectlistdomains (virconnectptr Conn, int * IDs, int maxids) |
Obtain the IDs of all hypervisor domains. |
Conn |
Hypervisor connection pointer |
IDS |
Array that stores each domain ID |
Maxids |
Maximum number of domains |
Returns |
Number of Domains |
Virdomainptr virdomainlookupbyid (virconnectptr Conn, int ID) |
Returns the pointer of the domain by the domain ID. |
Conn |
Hypervisor connection pointer |
ID |
Domain ID |
Returns |
Returns the pointer to the domain. |
Int virdomaingetinfo (virdomainptr domain, virdomaininfoptr info) |
Obtain Domain Information |
Domain |
Domain pointer |
Info |
Pointer to the data structure that stores Domain Information |
Returns |
0 is returned for successful retrieval; otherwise-1 is returned. |
Const char * virdomaingetname (virdomainptr domain) |
Obtain the domain name. |
Domain |
Domain pointer |
Returns |
Domain Name |
Int virconnectclose (virconnectptr conn) |
Releases the connection of hyperbisor. If the program goes offline, the function should be called to terminate the connection. |
Conn |
Hypervisor pointer |
Returns |
0 is returned for successful release; otherwise-1 is returned. |
Int virdomainfree (virdomainptr domain) |
Release the domain pointer. If you connect to the domain, you need to call this function to release the domain link, and then release the hyperbisor connection. |
Domain |
Domain pointer |
Returns |
0 is returned for successful release; otherwise-1 is returned. |
A major data structure:
Struct virdomaininfo |
Unsigned char |
State |
Running status of the current domain |
Unsigned long |
Maxmem |
Maximum memory supported |
Unsigned long |
Memory |
Memory Used |
Unsigned short |
Nrw.cpu |
Number of virtual CPUs |
Unsigned long |
Cputime |
Virtual CPU running time |
My design idea is to use virconnectopenreadonly () to get the link and use virconnectlistdomains () to get the ID of the currently active domain. Use virdomainlookupbyid () for each ID to obtain the pointer to its domain. Call virdomaingetinfo () to obtain the memory and CPU running time of the current domain. The name of the current domain is obtained by virdomaingetname.
The CPU usage calculation method is as follows: In myxm, virdomaingetinfo () is called twice to obtain the virtual CPU running time before and after the start of the time period. The difference between the two shows the virtual CPU running time. Use sleep () to implement the interval. Use gettimeofday () to get the real time difference before and after sleep. The ratio of the CPU running time to the actual time in this period is the CPU usage during this period.
Added the-lvirt parameter to GCC during compilation to include the libvirt-devl library.
- <PRE class = CSHARP name = "code"> /**
- * Project: myxm
- * Version: 0.2
- * Abstract: A simple xen Monitor
- * Author: Gu Xiangnan
- * Date: 2008-05-25
- */
-
- # Include <stdlib. h> </stdlib. h>
- # Include <stdio. h> </stdio. h>
- # Include <libvirt. H = ""> </libvirt>
-
- # Define maxid 50
- /* The data structure of time */
Typedef struct timeinfo
{
Long long cpu_time;
Struct timeval real_time;
} Timeinfonode;
/* The hypervisor connection */
Static virconnectptr conn = NULL;
/* Release the connect of hypervisor */
Void closeconn ()
{
If (Conn! = NULL)
Virconnectclose (conn );
}
/* Release the domain pointer */
Void freedom (virdomainptr DOM)
{
If (Dom! = NULL)
Virdomainfree (DOM );
}
/* Get the start time of each domain */
Void gettimeinfo (int id, timeinfonode * Infos)
{
Virdomainptr dom = NULL;
Virdomaininfo Info;
Int ret;
/* Find the domain of the given ID */
DOM = virdomainlookupbyid (Conn, ID );
If (DOM = NULL)
{
Fprintf (stderr, "failed to find domain % d", ID );
Freedom (DOM );
Closeconn ();
}
/* Get the information of the domain */
Ret = virdomaingetinfo (DOM, & info );
If (Ret <0)
{
Fprintf (stderr, "failed to get information for domain % d", ID );
Freedom (DOM );
Closeconn ();
}
/* Get the start of realtime */
If (gettimeofday (& (Infos-> real_time), null) =-1)
{
Fprintf (stderr, "failed to get start time ");
Return;
}
/* Get the start of cputime */
Infos-> cpu_time = info. cputime;/* nanosecond */
Freedom (DOM );
}
Void getdomaininfo (int id, timeinfonode Infos)
{
Virdomainptr dom = NULL;
Virdomaininfo Info;
Int ret;
Struct timeval realtime;
Int cpu_diff, real_diff;
Float usage;
/* Find the domain of the given ID */
DOM = virdomainlookupbyid (Conn, ID );
If (DOM = NULL)
{
Fprintf (stderr, "failed to find domain % d", ID );
Freedom (DOM );
Closeconn ();
}
/* Get the information of the domain */
Ret = virdomaingetinfo (DOM, & info );
If (Ret <0)
{
Fprintf (stderr, "failed to get information for domain % d", ID );
Freedom (DOM );
Closeconn ();
}
/* Get the end of realtime */
If (gettimeofday (& realtime, null) =-1)
{
Fprintf (stderr, "failed to get start time ");
Return;
}
/* Calculate the usage of CPU */
Cpu_diff = (info. cputime-Infos. cpu_time)/10000;
Real_diff = 1000 * (realtime. TV _sec-Infos. real_time. TV _sec) +
(Realtime. TV _usec-Infos. real_time. TV _usec );
Usage = cpu_diff/(float) (real_diff );
/* Print the results */
Printf ("% d %. 3f % lu % Hu % 0x % s", ID, usage, info. Memory/1024,
Info. maxmem/1024, info. nr1_cpu, info. State, virdomaingetname (DOM ));
Freedom (DOM );
}
Int main ()
{
Int idcount;
Int I;
Int ID;
Int IDs [maxid];
Timeinfonode timeinfos [maxid];
Printf ("--------------------------------------------------------");
Printf ("xen domain monitor version 0.2 ");
Printf ("build by Gu Xiangnan 35060514 ");
Printf ("--------------------------------------------------------");
/* Null means connect to local xen hypervisor */
Conn = virconnectopenreadonly (null );
If (conn = NULL)
{
Fprintf (stderr, "failed to connect to hypervisor ");
Closeconn ();
Return 0;
}
/* Get the Count of IDs and save these id into IDs [] */
Idcount = virconnectlistdomains (Conn, & IDs [0], maxid );
If (idcount <0)
{
Fprintf (stderr, "failed to list the domains ");
Closeconn ();
Return 0;
}
Printf ("Domain totals: % d", idcount );
Printf ("id cpu mem maxmem vcpus state name ");
/* Loop get the cputime info by IDS */
For (I = 0; I <idcount; I ++)
{
Id = IDs [I];
Gettimeinfo (ID, & (timeinfos [I]);
}
Sleep (1 );
/* Loop print the domain info and calculate the usage of CPUs */
For (I = 0; I <idcount; I ++)
{
Id = IDs [I];
Getdomaininfo (ID, timeinfos [I]);
}
Printf ("--------------------------------------------------------");
Closeconn ();
Return 0;
}
</PRE>