基于Libvirt实现轻量级的虚拟机管理工具
程序说明
程序实现了虚拟机的所有基本操作。包括虚拟机的启动、暂停、关闭、重启、强制关机、强制重启、保存等功能。 程序源码地址:Github 程序编译:支持g++和clang(Apple LLVM 8.0)编译。
编译命令:
clang libvirtctl.cpp -o libvirtctl -lvirt
程序执行方法:
./libvirtctl DomainName Operation
DomainName : 虚拟主机域名 Operation : 虚拟机执行操作 操作示例:开机:
./libvirtctl CentOS6.4 start
示例:
./libvirtctl CentOS6.4 shutdown
错误解决方案
在程序编译过程中,若clang提示错误:
#include <libvirt/libvirt.h> ^ clang error: libvirt.h not found
解决方案:
sudo apt-get install libvirt-dev
程序源码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
typedef int DOMAIN_INFO_STATUS;
typedef int DOMAIN_INFO_LOOKUPID;
static virConnectPtr connection = NULL;
static virDomainPtr domainInfoPtr = NULL;
static DOMAIN_INFO_STATUS domainStart(const char *guestname);
static DOMAIN_INFO_STATUS domainShutdown(const char *guestname);
static DOMAIN_INFO_STATUS domainForcedShutdown(const char *guestname);
//static DOMAIN_INFO_STATUS GetDomainInformation(DOMAIN_INFO_LOOKUPID id);
static DOMAIN_INFO_STATUS domainReboot(const char *guestname);
static DOMAIN_INFO_STATUS domainReset(const char *guestname);
static DOMAIN_INFO_STATUS domainResume(const char *guestname);
static DOMAIN_INFO_STATUS GetDomainInformation(const char *guestname);
int main(int argc, const char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: ./libvirtctl guestName(domainName) start(START)/shutdown(SHUTDOWN)/forcedShutdown(FORCEDSHUTDOWN)/reboot(REBOOT)/reset(RESET)/resume(RESUME)/status(STATUS).\n");
return -1;
}
connection = virConnectOpen("qemu:///system");
if (connection == NULL)
{
fprintf(stderr, "Failed to open connectionn to qemu:///system.\n");
return -1;
}
domainInfoPtr = virDomainLookupByName(connection, argv[1]);
if (domainInfoPtr == NULL)
{
fprintf(stderr, "virDomainLookupByName failed.\n");
virConnectClose(connection);
return -1;
}
if (strcmp(argv[2], "start") == 0 || strcmp(argv[2], "START") == 0)
{
if (domainStart(argv[1]) != 0)
{
fprintf(stderr, "Start Failed.\n");
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "shutdown") == 0 || strcmp(argv[2], "SHUTDOWN") == 0)
{
if (domainShutdown(argv[1]) != 0)
{
fprintf(stderr, "Shutdown Failed.\n");
virConnectClose(connection);
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "forcedShutdown") == 0 || strcmp(argv[2], "FORCEDSHUTDOWN") == 0)
{
if (domainForcedShutdown(argv[1]) != 0)
{
fprintf(stderr, "Forced Shutdown Failed.\n");
virConnectClose(connection);
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "reboot") == 0 || strcmp(argv[2], "REBOOT") == 0)
{
if (domainReboot(argv[1]) != 0)
{
fprintf(stderr, "Reboot Failed.\n");
virConnectClose(connection);
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "reset") == 0 || strcmp(argv[2], "RESET") == 0)
{
if (domainReset(argv[1]) != 0)
{
fprintf(stderr, "Reset Failed.\n");
virConnectClose(connection);
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "resume") == 0 || strcmp(argv[2], "RESUME") == 0)
{
if (domainResume(argv[1]) != 0)
{
fprintf(stderr, "Resume Failed.\n");
virConnectClose(connection);
virDomainFree(domainInfoPtr);
return -1;
}
}
if (strcmp(argv[2], "status") == 0 || strcmp(argv[2], "STATUS") == 0)
{
if (GetDomainInformation(argv[1]) != 0)
{
fprintf(stderr, "Get Status Failed.\n");
virDomainFree(domainInfoPtr);
virConnectClose(connection);
return -1;
}
}
/* if(strcmp(argv[2], "start") != 0 || strcmp(argv[2], "shutdown") !=0 || strcmp(argv[2], "status") !=0 || strcmp(argv[2], "START") != 0 || strcmp(argv[2], "SHUTDOWN") != 0 || strcmp(argv[2], "STATUS") != 0)
{
fprintf(stderr, "Usage: ./libvirtctl guestName(domainName) start(START)/shutdown(SHUTDOWN)/status(STATUS).\n");
return -1;
}*/
if (domainInfoPtr != NULL)
{
virDomainFree(domainInfoPtr);
}
if (connection != NULL)
{
virConnectClose(connection);
}
return EXIT_SUCCESS;
}
inline DOMAIN_INFO_STATUS domainStart(const char *guestname)
{
int flag = -1;
flag = virDomainCreate(domainInfoPtr);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainCreate failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain starting was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS domainShutdown(const char *guestname)
{
int flag = -1;
flag = virDomainShutdown(domainInfoPtr);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainShutdown failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain shutdown was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS domainForcedShutdown(const char *guestname)
{
int flag = -1;
domainShutdown(guestname);
flag = virDomainDestroy(domainInfoPtr);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainForcedShutdown failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain forced shutdown was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS domainReboot(const char *guestname)
{
int flag = -1;
flag = virDomainReboot(domainInfoPtr, VIR_DOMAIN_REBOOT_ACPI_POWER_BTN);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainReboot failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain reboot was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS domainReset(const char *guestname)
{
int flag = -1;
flag = virDomainReset(domainInfoPtr, 0);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainReset failed: %s.\n", guestname);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain reset was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS domainResume(const char *guestname)
{
int flag = -1;
flag = virDomainResume(domainInfoPtr);
if (flag != 0)
{
virErrorPtr error = virGetLastError();
fprintf(stderr, "virDomainResume failed: %s.\n", guestname);
virFreeError(error);
return -1;
}
else
{
fprintf(stdout, "libvirtctl: %s domain resume was succeed.\n", guestname);
}
return 0;
}
inline DOMAIN_INFO_STATUS GetDomainInformation(const char *guestname)
{
char *status = NULL;
virErrorPtr error = NULL;
int vcpus = 0;
unsigned long long node_free_memory = 0;
int id = 0;
const char *name = NULL;
virNodeInfo nodeInfo;
virDomainInfo domainInfo;
fprintf(stdout, "****************************************************\n");
status = virConnectGetCapabilities(connection);
if (status == NULL)
{
error = virGetLastError();
fprintf(stderr, "virConnectGetCapabilities failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
free(status);
status = NULL;
status = virConnectGetHostname(connection);
if (status == NULL)
{
error = virGetLastError();
fprintf(stderr, "virConnectGetHostname failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
fprintf(stdout, "Connection Hostname:\t%s\n", status);
free(status);
status = NULL;
vcpus = virConnectGetMaxVcpus(connection, NULL);
if (vcpus < 0)
{
error = virGetLastError();
fprintf(stderr, "virConnectGetMaxVcpus faild: %s.\n", error->message);
virFreeError(error);
return -1;
}
fprintf(stdout, "Maximum number of cpus supported on connection:\t%d\n", vcpus);
node_free_memory = virNodeGetFreeMemory(connection);
if (node_free_memory == 0)
{
error = virGetLastError();
fprintf(stderr, "virNodeGetFreeMemory failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
fprintf(stdout, "Node Free Memory:\t%llu\n", node_free_memory);
if (virNodeGetInfo(connection, &nodeInfo) < 0)
{
error = virGetLastError();
fprintf(stderr, "virNodeGetInfo failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
fprintf(stdout, "------------------------------------------\n");
fprintf(stdout, "Node Information From Connection : \n");
fprintf(stdout, "Model:\t%s\n", nodeInfo.model);
fprintf(stdout, "Memory Size:\t%luKiB\n", nodeInfo.memory);
fprintf(stdout, "Number of CPUs:\t%u\n", nodeInfo.cpus);
fprintf(stdout, "MHz of CPUs:\t%u\n", nodeInfo.mhz);
fprintf(stdout, "Number of NUMA Nodes:\t%u\n", nodeInfo.nodes);
fprintf(stdout, "Number of CPU Sockets:\t%u\n", nodeInfo.sockets);
fprintf(stdout, "Number of CPU Cores Per Socket:\t%u\n", nodeInfo.cores);
fprintf(stdout, "Number of CPU Threads Per Core:\t%u\n", nodeInfo.threads);
fprintf(stdout, "****************************************************\n");
fprintf(stdout, "ID\t名称\t\t状态\n");
fprintf(stdout, "------------------------------------------\n");
id = virDomainGetID(domainInfoPtr);
name = virDomainGetName(domainInfoPtr);
if (virDomainGetInfo(domainInfoPtr, &domainInfo) < 0)
{
error = virGetLastError();
fprintf(stderr, "virDomainGetInfo failed: %s.\n", error->message);
virFreeError(error);
return -1;
}
fprintf(stdout, "%d\t%s\t\t%d\n", id, name, domainInfo.state);
fprintf(stdout, "****************************************************\n");
return 0;
}