天天看點

基于libvirt API監測xen初探 (轉)

通過使用Xen的API或封裝了其API的函數庫,如libvirt進行程式設計,實作以下功能:

1.以指令行形式顯示主控端(Host OS)上正在運作的客戶機(Guest OS)名稱; 

2.通過指令行形式顯示指定客戶機(Guest OS)的工作狀态(顯示其 CPU 使用率,和記憶體使用情況即可); 

這個作業工程類似于Fedora等Linux系統中内置的xm管理程式,在這裡僅簡單的實作xm top的功能。我選用了Fedora Core 8作為Host OS。在其上,通過Xen安裝另一Fedora Core 8作為Guest OS。利用libvirt提供的API實作顯示Guest OS名稱、顯示其 CPU 使用率,和記憶體使用情況的功能。并與xm、virt-manager的運作結果做對比,驗證正确性。

安裝所需的軟體包:

•xen-3.1.2-2.fc8 

•libvirt-o.4.2-1.fc8 

•libvirt-devl-0.4.2-1.fc8 

其中,xen為虛拟機,libvirt為運作庫,libvirt-devl為代碼運作庫,供開發編譯使用。具體版本視安裝源與系統其他元件的依賴關系。

在我使用Xen安裝Guest OS的過程中出現的一點小問題:在Fedora Core 8中發現預設提供的SELinux服務會對xen産生影響,估計可能是阻礙了某些信号量的傳遞,通過修改/etc/sysconfig/selinux, 設定其中SELINUX=disabled将SElinux禁用。

通過virt-manager或virt-install安裝Guest OS。設定為256m記憶體,4G硬碟空間,半虛拟化方式。

有關libvirt API的使用:

virConnectPtr virConnectOpenReadOnly (const char * name)  

在使用時首先應調用這個函數,獲得hypervisor的連結  

name URI of hypervisor,為NULL則代表本地連結 

Returns 傳回hypervisor的指針

int virConnectListDomains (virConnectPtr conn, int * ids, int maxids)  

獲得hypervisor下所有域的ID  

conn hypervisor連結指針 

ids 存儲每個域ID的數組 

maxids 域數量的上限 

Returns 域的數量

virDomainPtr virDomainLookupByID (virConnectPtr conn, int id) 

由域的ID傳回域的指針  

conn hypervisor連結指針 

id 域的ID 

Returns 傳回域的指針

int virDomainGetInfo (virDomainPtr domain, virDomainInfoPtr info) 

獲得域的資訊 

domain 域的指針 

info 指向存儲域的資訊的資料結構的指針 

Returns 成功擷取傳回0,否則傳回-1

const char * virDomainGetName (virDomainPtr domain) 

得到域的名字 

domain 域的指針 

Returns 域的名字

int virConnectClose (virConnectPtr conn) 

釋放hyperbisor的連接配接,如果程式出線異常或錯誤應調用本函數終止連接配接 

conn hypervisor的指針 

Returns 成功釋放傳回0,否則傳回-1

int virDomainFree (virDomainPtr domain) 

釋放域的指針,如果連接配接到域就要先調用這個函數釋放域的連結,之後再釋放hyperbisor的連接配接 

domain 域的指針 

Returns 成功釋放傳回0,否則傳回-1

一個主要的資料結構:

struct virDomainInfo 

unsigned char state 目前域的運作狀态 

unsigned long maxMem 支援的最大記憶體 

unsigned long memory 使用的記憶體 

unsigned short nrVirtCpu 虛拟CPU數量 

unsigned long long cpuTime 虛拟CPU運作時間

我的設計思路是,利用virConnectOpenReadOnly()擷取連結,通過virConnectListDomains()得到目前活躍的域 的ID。對于每一個ID利用virDomainLookupByID()得到指向其域的指針。調用virDomainGetInfo()獲得目前域的内 存、CPU運作時間等資訊。目前域的名稱由virDomainGetName()獲得。

CPU占用率的計算方法為:在myxm中兩次調用virDomainGetInfo()擷取時間段開始前和結束後的虛拟CPU運作時間,二者內插補點可知虛拟 CPU的運作時間。間隔時間段用sleep()實作。在sleep()前後用gettimeofday()取得真實的時間差。該時間段内CPU運作時間與 真實時間的比值即為這段時間内的CPU占用率。

編譯時gcc增加-lvirt參數,用于包含libvirt-devl庫。

# view plaincopy to clipboardprint?  # 01.<PRE class=csharp name="code">  # 08.  # 09.#include <STDLIB.H></STDLIB.H>  # 10.#include <STDIO.H></STDIO.H>  # 11.#include <LIBVIRT libvirt.h=""></LIBVIRT>  # 12.  # 13.#define MAXID 50  # 14.  # 15.  # 16.typedef struct timeInfo  # 17.{  # 18. long long cpu_time;  # 19. struct timeval real_time;  # 20.} timeInfoNode;  # 21.  # 22.  # 23.static virConnectPtr conn = NULL;  # 24.  # 25.  # 26.void closeConn()  # 27.{  # 28. if (conn != NULL)  # 29. virConnectClose(conn);  # 30.}  # 31.  # 32.  # 33.void freeDom(virDomainPtr dom)  # 34.{  # 35. if (dom != NULL)  # 36. virDomainFree(dom);  # 37.}  # 38.  # 39.  # 40.void getTimeInfo(int id, timeInfoNode * infos)  # 41.{  # 42. virDomainPtr dom = NULL;  # 43. virDomainInfo info;  # 44. int ret;  # 45.  # 46.   # 47. dom = virDomainLookupByID(conn, id);  # 48. if (dom == NULL)  # 49. {  # 50. fprintf(stderr, "Failed to find Domain %d/n", id);  # 51. freeDom(dom);  # 52. closeConn();  # 53. }  # 54.  # 55.   # 56. ret = virDomainGetInfo(dom, &info);  # 57. if (ret < 0)  # 58. {  # 59. fprintf(stderr, "Failed to get information for Domain %d/n", id);  # 60. freeDom(dom);  # 61. closeConn();  # 62. }  # 63.  # 64.   # 65. if (gettimeofday(&(infos->real_time), NULL) == - 1)  # 66. {  # 67. fprintf(stderr, "Failed to get start time/n");  # 68. return;  # 69. }  # 70.  # 71.   # 72. infos->cpu_time = info.cpuTime;   # 73.  # 74. freeDom(dom);  # 75.}  # 76.  # 77.void getDomainInfo(int id, timeInfoNode infos)  # 78.{  # 79. virDomainPtr dom = NULL;  # 80. virDomainInfo info;  # 81. int ret;  # 82. struct timeval realTime;  # 83. int cpu_diff, real_diff;  # 84. float usage;  # 85.  # 86.   # 87. dom = virDomainLookupByID(conn, id);  # 88. if (dom == NULL)  # 89. {  # 90. fprintf(stderr, "Failed to find Domain %d/n", id);  # 91. freeDom(dom);  # 92. closeConn();  # 93. }  # 94.  # 95.   # 96. ret = virDomainGetInfo(dom, &info);  # 97. if (ret < 0)  # 98. {  # 99. fprintf(stderr, "Failed to get information for Domain %d/n", id);  # 100. freeDom(dom);  # 101. closeConn();  # 102. }  # 103.  # 104.   # 105. if (gettimeofday(&realTime, NULL) == - 1)  # 106. {  # 107. fprintf(stderr, "Failed to get start time/n");  # 108. return;  # 109. }  # 110.  # 111.   # 112. cpu_diff = (info.cpuTime - infos.cpu_time) / 10000;  # 113. real_diff = 1000 *(realTime.tv_sec - infos.real_time.tv_sec) +  # 114. (realTime.tv_usec - infos.real_time.tv_usec);  # 115. usage = cpu_diff / (float)(real_diff);  # 116.  # 117.   # 118. printf("%d/t%.3f%/t%lu/t%lu/t%hu/t%0X/t%s/n", id, usage, info.memory / 1024,  # 119. info.maxMem / 1024, info.nrVirtCpu, info.state, virDomainGetName(dom));  # 120.  # 121. freeDom(dom);  # 122.}  # 123.  # 124.int main()  # 125.{  # 126. int idCount;  # 127. int i;  # 128. int id;  # 129. int ids[MAXID];  # 130. timeInfoNode timeInfos[MAXID];  # 131.  # 132. printf("--------------------------------------------------------/n");  # 133. printf(" XEN Domain Monitor Version 0.2/n");  # 134. printf(" Build by Gu Xiangnan 35060514/n");  # 135. printf("--------------------------------------------------------/n");  # 136.  # 137.   # 138. conn = virConnectOpenReadOnly(NULL);  # 139. if (conn == NULL)  # 140. {  # 141. fprintf(stderr, "Failed to connect to hypervisor/n");  # 142. closeConn();  # 143. return 0;  # 144. }  # 145.  # 146.   # 147. idCount = virConnectListDomains(conn, &ids[0], MAXID);  # 148. if (idCount < 0)  # 149. {  # 150. fprintf(stderr, "Failed to list the domains/n");  # 151. closeConn();  # 152. return 0;  # 153. }  # 154.  # 155. printf("Domain Totals: %d/n", idCount);  # 156. printf("ID/tCPU/tMEM/tMaxMEM/tVCPUs/tState/tNAME/n");  # 157.  # 158.   # 159. for (i = 0; i < idCount; i++)  # 160. {  # 161. id = ids[i];  # 162. getTimeInfo(id, &(timeInfos[i]));  # 163. }  # 164.  # 165. sleep(1);  # 166.  # 167.   # 168. for (i = 0; i < idCount; i++)  # 169. {  # 170. id = ids[i];  # 171. getDomainInfo(id, timeInfos[i]);  # 172. }  # 173.  # 174. printf("--------------------------------------------------------/n");  # 175. closeConn();  # 176. return 0;  # 177.}  # 178.</PRE>

運作結果:
基于libvirt API監測xen初探 (轉)
可以對比一下vmm與xm top,驗證實作的正确性:
基于libvirt API監測xen初探 (轉)
基于libvirt API監測xen初探 (轉)

  原文位址 http://qinlong.blog.51cto.com/1130504/405018

繼續閱讀