使用libvirt管理kvm(API篇)

本文详细介绍如何通过Libvirt API创建、读取信息、关闭及销毁KVM虚拟机。涵盖Libvirt安装配置、XML配置文件编写及核心API使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创作品,允许转载,转载时请务必以超链接形式标明文章  原始出处 、作者信息和本声明。否则将追究法律责任。 http://speakingbaicai.blog.51cto.com/5667326/1162005

一、简介

libvirtLinux上的虚拟化库,是长期稳定的C语言API,支持KVM/QEMUXenLXC等主流虚拟化方案。链接:http://libvirt.org/

API开发手册:http://libvirt.org/html/libvirt-libvirt.html

virshlibvirt对应的shell命令。

之前写了一篇使用virsh管理kvm虚拟机的博客《使用libvirt管理kvmvirsh篇)》(传送门:http://speakingbaicai.blog.51cto.com/5667326/1161964),这里再从编程接口API的角度介绍如何使用libvirt管理kvm虚拟机。

二、环境介绍

OSUbuntu 12.04.1 LTS

内核:Linux 3.2.0-33-generic-pae #52-Ubuntu SMP Thu Oct 18 16:39:21 UTC 2012 i686 i686 i386 GNU/Linux

libvirt0.9.8

三、准备工作

ubuntu安装,直接apt-get install

1、安装kvm/qemu

sudo apt-get install kvm qemu

2、安装libvirt

sudo apt-get install libvirt-bin libvirt-dev

3、网桥管理工具

sudo apt-get install bridge-utils

4、统一建模语言

sudo apt-get install uml-utilities

5vnc 虚拟机查看工具

sudo apt-get install vncviewer vnc4server

四、创建镜像

在指定目录下

执行 qemu-img create -f raw template.img 3G

这样就创建了一个大小为3G的镜像(img

有人可能问镜像是什么东西。简单的说,我们在镜像上启动一个虚拟机,这个3G的镜像就相当于这个虚拟机对应的磁盘空间。

也有人执行 qemu-img create -f qcow2 template.img 3G,(备注:qcow2支持动态扩张)来获得一个动态扩张的镜像。我个人还需要对磁盘资源进行简单的统计、管理,因此没有用这个。不同情景下可能这种模式更好,有兴趣的朋友自己试一下。

五、libvirt xml配置文件

libvirt(包括virsh)使用xml文件对虚拟机进行配置,其中包括虚拟机名称、分配内存、vcpu等多种信息。定义、创建虚拟机等操作都需要xml配置文件的参与,因此这里先介绍xml配置文件。我编辑了一个名为template.xmlxml文件,其中定义了一个名为demokvm 虚拟机。

  
  
  1. <domain type = 'kvm'>          //虚拟机类型,kvm 
  2.     <name>demo</name>          //虚拟机名称 
  3.     <memory>1048576</memory>   //分配内存,单位kb 
  4.     <vcpu>1</vcpu>             //分配vcpu,单位个数 
  5.     <os> 
  6.         <type arch = 'x86_64' machine = 'pc'>hvm</type> 
  7.         <boot dev = 'cdrom'/>  //cd 启动 
  8.         <boot dev = 'hd'/>     //硬盘启动 
  9.     </os> 
  10.     <features> 
  11.         <acpi/> 
  12.         <apic/> 
  13.         <pae/> 
  14.     </features> 
  15.     <clock offset = 'localtime'/> 
  16.     <on_poweroff>destroy</on_poweroff> 
  17.     <on_reboot>restart</on_reboot> 
  18.     <on_crash>destroy</on_crash> 
  19.     <devices> 
  20.         <emulator>/usr/bin/kvm</emulator> 
  21.         <disk type = 'file' device = 'disk'>  //对应的镜像,就是之前使用qemu-img命令新建的img文件,注意路径要正确 
  22.             <driver name = 'qemu' type = 'raw'/> 
  23.             <source file = '/var/lib/lynn/img/template.img'/> 
  24.             <target dev = 'hda' bus = 'ide'/> 
  25.         </disk> 
  26.         <disk type = 'file' device = 'cdrom'> //可选项,iso通常是操作系统的安装光盘 
  27.             <source file = '/var/lib/lynn/img/template.iso'/> 
  28.             <target dev = 'hdb' bus = 'ide'/> 
  29.         </disk> 
  30.         <interface type = 'bridge'>           //libvirt默认虚拟机的网络配置是NAT模式,就是虚拟机与宿主机的网络拓扑是NAT形式。实际中,许多开发者更希望使用网桥模式。 
  31.             <source bridge = 'br0'/> 
  32.         </interface> 
  33.         <input type ='tablet' bus='usb'/> 
  34.         <input type = 'mouse' bus = 'ps2'/> 
  35.         <graphics type = 'vnc' port = '-1' listen = '0.0.0.0' autoport = 'yes' keymap = 'en-us'/>  //vnc端口系统自动配置 
  36.     </devices> 
  37. </domain> 

六、libvirt的使用——头文件与编译

#include "libvirt/libvirt.h" //libvirt主要API

#include <libvirt/virterror.h> //libvirt 错误提示

编译时加入连接库 -lvirt,例如我要编译名为createvm.cpp的源文件,可以运行如下命令g++ createvm.cpp -o createvm -lvirt

七、主要使用的API

这里只列举一些常用的API,具体可参见libvirt API开发手册

主要功能

函数原型

创建连接

virConnectPtr virConnectOpen(const char * name)                 

根据xml文档创建虚拟机

virDomainPtr virDomainCreateXML(virConnectPtr conn, const char * xmlDesc, unsigned int flags)

根据虚拟机名字获得虚拟域

virDomainPtr virDomainLookupByName(virConnectPtr conn, const char * name)

获取虚拟域相关信息

int virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)

关闭虚拟域

int virDomainShutdown (virDomainPtr domain)

销毁虚拟域

int virDomainDestroy (virDomainPtr domain)

八、新建虚拟机

备注:这里只是写一个简单的例子,除print.cpp以外的代码没有写成带参数、可配置的,请见谅。

  
  
  1. /*  createvm.cpp  */ 
  2. /* compile with: g++ createvm.cpp -o createvm -lvirt */ 
  3.  
  4. /* Wang Min @ iie           */ 
  5. /* autumn_sky_is@163.com    */ 
  6. /* date: 2013-02-27         */ 
  7.  
  8. #include <iostream> 
  9. #include <cstdio> 
  10. #include <string> 
  11. #include <fstream> 
  12. #include <sstream>  // for stringstream 
  13. #include "libvirt/libvirt.h" 
  14. #include <libvirt/virterror.h> 
  15.  
  16. using namespace std; 
  17. string vm_xml_location = "../xml/template.xml"
  18.  
  19. int main() 
  20.     ifstream file(vm_xml_location.c_str()); 
  21.     if(!file) { 
  22.         cout<<"Cannot open file "<<vm_xml_location<<endl
  23.         return -1; 
  24.     } 
  25.     // read xml file 
  26.     stringstream buffer; 
  27.     buffer << file.rdbuf(); 
  28.     string vm_xml_template = buffer.str(); 
  29.     file.close(); 
  30.      
  31.     virConnectPtr conn = virConnectOpen("qemu:///system"); 
  32.     if(NULL==conn) { 
  33.         fprintf(stderr, "Failed to build connection to qemu:///system.\n"); 
  34.         return -1; 
  35.     } 
  36.  
  37.     virDomainPtr vm_ptr = virDomainCreateXML(conn, vm_xml_template.c_str(), 0); 
  38.     if(!vm_ptr) { 
  39.         virErrorPtr error = virGetLastError(); 
  40.         cout<<error->message<<endl
  41.         return -1; 
  42.     } 
  43.     return 0; 

编译后,直接运行./createvm,就创建了一个名为demo的kvm 虚拟机。需要预先在相应目录下新建好一个名为“template.xml”的配置文件

九、读取虚拟机信息

  
  
  1. /* print.cpp  */ 
  2. /* compile with: g++ print.cpp -o print -lvirt */ 
  3.  
  4. /* Wang Min @ iie           */ 
  5. /* autumn_sky_is@163.com    */ 
  6. /* date: 2013-02-27         */ 
  7.  
  8. #include <iostream> 
  9. #include <cstdio> 
  10. #include <string> 
  11. #include <fstream> 
  12. #include <sstream>  // for stringstream 
  13. #include "libvirt/libvirt.h" 
  14. #include <libvirt/virterror.h> 
  15.  
  16. using namespace std; 
  17. //using namespace rapidxml; 
  18.  
  19. int main(int argc, char * argv[]) 
  20.     if(2!=argc){ 
  21.     cout<<"Error: print need 1 parametre"<<endl
  22.     cout<<"usage: ./print vm_name"<<endl
  23.     return -1;   
  24.     } 
  25.     virConnectPtr conn = virConnectOpen("lxc:///"); 
  26.     if(NULL==conn) { 
  27.         fprintf(stderr, "Failed to build connection to lxc:///.\n"); 
  28.         return -1; 
  29.     } 
  30.  
  31.     virDomainPtr domain = virDomainLookupByName(conn, argv[1]); 
  32.     if(domain == NULL){ 
  33.         cout<<"can not find "<<argv[1]<<", regard it as success."<<endl
  34.         return -1; 
  35.     }    
  36.      
  37.     // get lxc Info 
  38.     virDomainInfo info; 
  39.     if(-1==virDomainGetInfo(domain, &info)){ 
  40.        cout<<"can not get domain info"<<endl
  41.        return -1; 
  42.     } 
  43.    
  44.     printf("state:%d|maxmem:%d|memused:%d|cpunum:%d|cputime:%ld\n",info.state,info.maxMem,info.memory,info.nrVirtCpu,info.cpuTime); 
  45.     cout<<"Helloworld"<<endl
  46.     return 0; 

编译后运行./print virt_name,例如./print demo

十、关闭虚拟机

  
  
  1. /* shutdownvm.cpp  */ 
  2. /* compile with: g++ shutdownvm.cpp -o shutdownvm -lvirt */ 
  3.  
  4. /* Wang Min @ iie           */ 
  5. /* autumn_sky_is@163.com    */ 
  6. /* date: 2013-02-27         */ 
  7.  
  8. #include <iostream> 
  9. #include <cstdio> 
  10. #include <string> 
  11. #include <fstream> 
  12. #include <sstream>  // for stringstream 
  13. #include "libvirt/libvirt.h" 
  14. #include <libvirt/virterror.h> 
  15.  
  16. using namespace std; 
  17. string domname = "demo"
  18. int main() 
  19.     virConnectPtr conn = virConnectOpen("qemu:///system"); 
  20.     if(NULL==conn) { 
  21.         fprintf(stderr, "Failed to build connection to qemu:///system.\n"); 
  22.         return -1; 
  23.     } 
  24.  
  25.     virDomainPtr domain = virDomainLookupByName(conn, domname.c_str()); 
  26.     if(domain == NULL){ 
  27.         cout<<"can not find "<<domname <<", regard it as success."<<endl
  28.         return 0; 
  29.     } 
  30.     if(virDomainShutdown(domain)!=0){ 
  31.         virErrorPtr error = virGetLastError(); 
  32.         cout<<error->message<<endl
  33.         return -1; 
  34.     } 
  35.     return 0; 

编译后运行./shutdownvm

十一、销毁虚拟机

  
  
  1. /* destroyvm.cpp  */ 
  2. /* compile with: g++ destroyvm.cpp -o destroyvm -lvirt */ 
  3.  
  4. /* Wang Min @ iie           */ 
  5. /* autumn_sky_is@163.com    */ 
  6. /* date: 2013-02-27         */ 
  7.  
  8. #include <iostream> 
  9. #include <cstdio> 
  10. #include <string> 
  11. #include <fstream> 
  12. #include <sstream>  // for stringstream 
  13.  
  14. #include "libvirt/libvirt.h" 
  15. #include <libvirt/virterror.h> 
  16.  
  17. using namespace std; 
  18. string domname = "demo"
  19. int main() 
  20.     virConnectPtr conn = virConnectOpen("qemu:///system"); 
  21.     if(NULL==conn) { 
  22.         fprintf(stderr, "Failed to build connection to qemu:///system.\n"); 
  23.         return -1; 
  24.     } 
  25.  
  26.     virDomainPtr domain = virDomainLookupByName(conn, domname.c_str()); 
  27.     if(domain == NULL){ 
  28.         cout<<"can not find "<<domname <<", regard it as success."<<endl
  29.         return 0; 
  30.     } 
  31.     if(virDomainDestroy(domain)!=0){ 
  32.         virErrorPtr error = virGetLastError(); 
  33.         cout<<error->message<<endl
  34.         return -1; 
  35.     } 
  36.     return 0; 

编译后运行./destroyvm

本文出自 “说话的白菜” 博客,请务必保留此出处http://speakingbaicai.blog.51cto.com/5667326/1162005

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值