您的位置:首页 > 编程语言 > C语言/C++

用C++编程调用libvirt的API来创建KVM虚拟机

2013-08-22 21:51 531 查看
1. 如果已经写好了创建kvm的配置文件(stand.xml)格式,那么创建kvm虚拟机只要使用命令即可:

virsh define ./conf/stand.xml
virsh start rheltest3


2. 如果直接编程调用libvirt创建kvm虚拟机,则可用以下程序

/***************************************************************************
* create_vm.cpp
*  create kvm machine(domain) based on conf.xml
*  the first parameter is the conf xml files' name
*  Note: the .xml must has two boot types (cdrom/hd) by any order
*  compile command: 'g++ create_vm.cpp -o createvm -lvirt'
*  running command: './createvm  /path/to/xml/example.xml'
*  author  : Aborn Jiang
*  date    : Aug.17, 2013
*  version : v0.1
***************************************************************************/

#include <iostream>
#include <cstdio>
#include <string>
#include <fstream>
#include <sstream>
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
#include <memory.h>

using namespace std;
int main(int argc, char* argv[])
{
if ( 1 == argc ) {
cout << "must and only need an argument, this is, configure .xml file name." << endl;
return -1;
}
if ( 3 <= argc ) {
cout << "too many arguments. must and only need one, that is, .xml file name." << endl;
return -1;
}
string xmlfile=argv[1];
cout << "*************************" << endl;
cout << "begin to build vm ..." << endl;
cout << "xmlfile path:" << xmlfile <<endl;

ifstream file(xmlfile.c_str());
if (!file) {
cout << "Cannot open file, permission denied." << xmlfile << endl;
return -1;
}
stringstream buffer;
buffer << file.rdbuf();
string xmlcontents = buffer.str();
file.close();

/*************************************************************************************
* deal with the original xml configuration file
* initxmlconts for transient guest domain(install os) configure (boot from cdrom)
* xmlcontents  for persistent guest domain configure (boot from hd)
************************************************************************************/
int pos_boot  = xmlcontents.find("boot");
int pos_hd    = xmlcontents.find("hd", pos_boot);
int pos_cdrom = xmlcontents.find("cdrom", pos_boot);
cout << "pos_hd=" << pos_hd << "  pos_cdrom=" << pos_cdrom << endl;
string initxmlconts(xmlcontents);
if ( pos_hd > pos_cdrom ) {    // cdrom apears in first order
cout << "cdrom apears in first order" << endl;
xmlcontents.replace(pos_cdrom, 5 ,"hd");
pos_hd=xmlcontents.find("hd", pos_cdrom + 2);
xmlcontents.replace(pos_hd, 2, "cdrom");
} else {                     // hd apears in first order
cout << "hd apears in first order" << endl;
initxmlconts.replace(pos_hd, 2, "cdrom");
pos_cdrom=initxmlconts.find("cdrom", pos_hd + 5);
initxmlconts.replace(pos_cdrom, 5, "hd");
}

// create and boot a transient initial domain, for vm os installation
virConnectPtr conn = virConnectOpen("qemu:///system");
if (NULL == conn ) {
virErrorPtr error = virGetLastError();
cout << error->message << endl;
return -1;
}
virDomainPtr vmpi = virDomainCreateXML(conn, initxmlconts.c_str(), VIR_DOMAIN_START_AUTODESTROY);
if (NULL == vmpi) {
virErrorPtr error = virGetLastError();
cout << error->message << endl;
return -1;
}
cout << "os installation ongoing, it will spend some time..." << endl;
while ( 1 == virDomainIsActive(vmpi) );                // waiting until installation finish.
cout << "os installation finished..." << endl;
if (NULL == conn)
virConnectPtr conn = virConnectOpen("qemu:///system");
cout << "start boot the vm machine..." << endl;

// store xmlcontents configuration for a persistent guest domain and boot it.
virDomainPtr vmp = virDomainDefineXML(conn, xmlcontents.c_str());
if (NULL == vmp) {
virErrorPtr error = virGetLastError();
cout << error->message << endl;
return -1;
} else {
cout << "define persistent domain success." << endl;
if (virDomainCreate(vmp) < 0) {                   // boot the vm.
cout << "Unable to boot guest configuration." << endl;
} else {
cout << "Boot the persistent defined guest ..." << endl;
}
cout << "build vm finished." << endl;
cout << "*************************" << endl;
return 0;
}
}


3. 附stand.xml文件内容

<domain type='kvm'>
<name>rheltest3</name>
<uuid>32b95fab-6d78-4e28-beca-2d3988ff8c8f</uuid>
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-1.2'>hvm</type>
<boot dev='hd'/>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/home/lisp/code/auto-rhel/virt/rheltest3.img'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' buss='0' target='0' unit='0'/>
</disk>
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<source file='/home/lisp/code/auto-rhel/rhelcustom.iso'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<controller type='ide' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
</controller>
<interface type='bridge'>
<mac address='52:54:00:78:f9:98'/>
<source bridge='virbr0'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoprot='yes'/>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</memballoon>
</devices>
</domain>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: