提交 5fbd4b15 编写于 作者: D Daniel P. Berrange

Added inactive domain management support to the test driver

上级 ec329ce9
Thu Jan 18 16:05:13 EST 2007 Daniel Berrange <berrange@redhat.com>
* src/test.h, src/test.c: Implement full inactive domain management
support in mock hypervisor to allow testing of apps wanting inactive
domains.
Thu Jan 18 13:37:02 EST 2007 Daniel Berrange <berrange@redhat.com>
* src/xend_internal.c: Tweak some of the new inactive domain methods
......@@ -14,7 +20,7 @@ Wed Jan 10 11:06:36 CET 2007 Daniel Veillard <veillard@redhat.com>
fixed or added a number constructs
Tue Jan 9 17:28:18 CET 2007 Daniel Veillard <veillard@redhat.com>
* docs/libvirt.rng: first version of the Relax-NG schemas to validate
XML instances
......
/*
* test.c: A "mock" hypervisor for use by application unit tests
*
* Copyright (C) 2006 Red Hat, Inc.
* Copyright (C) 2006-2007 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* See COPYING.LIB for the License of this software
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Daniel Berrange <berrange@redhat.com>
*/
......@@ -22,91 +35,140 @@
#include "test.h"
#include "xml.h"
int testOpen(virConnectPtr conn,
const char *name,
int flags);
int testClose (virConnectPtr conn);
int testGetVersion(virConnectPtr conn,
unsigned long *hvVer);
int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info);
int testNumOfDomains(virConnectPtr conn);
int testListDomains(virConnectPtr conn,
int *ids,
int maxids);
char *testGetOSType(virDomainPtr dom);
virDomainPtr
testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
unsigned int flags ATTRIBUTE_UNUSED);
virDomainPtr testLookupDomainByID(virConnectPtr conn,
int id);
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
const unsigned char *uuid);
virDomainPtr testLookupDomainByName(virConnectPtr conn,
const char *name);
int testDestroyDomain(virDomainPtr domain);
int testResumeDomain(virDomainPtr domain);
int testPauseDomain(virDomainPtr domain);
int testShutdownDomain (virDomainPtr domain);
int testRebootDomain (virDomainPtr domain,
virDomainRestart action);
int testGetDomainInfo(virDomainPtr domain,
virDomainInfoPtr info);
unsigned long testGetMaxMemory(virDomainPtr domain);
int testSetMaxMemory(virDomainPtr domain,
unsigned long memory);
int testSetMemory(virDomainPtr domain,
unsigned long memory);
int testSetVcpus(virDomainPtr domain,
unsigned int nrCpus);
char * testDomainDumpXML(virDomainPtr domain, int flags);
int testNumOfDefinedDomains(virConnectPtr conn);
int testListDefinedDomains(virConnectPtr conn,
const char **names,
int maxnames);
virDomainPtr testDomainDefineXML(virConnectPtr conn,
const char *xml);
int testDomainCreate(virDomainPtr dom);
int testDomainUndefine(virDomainPtr dom);
static virDriver testDriver = {
VIR_DRV_TEST,
"Test",
LIBVIR_VERSION_NUMBER,
NULL, /* init */
testOpen, /* open */
testClose, /* close */
NULL, /* type */
testGetVersion, /* version */
testNodeGetInfo, /* nodeGetInfo */
testListDomains, /* listDomains */
testNumOfDomains, /* numOfDomains */
testDomainCreateLinux, /* domainCreateLinux */
testLookupDomainByID, /* domainLookupByID */
testLookupDomainByUUID, /* domainLookupByUUID */
testLookupDomainByName, /* domainLookupByName */
testPauseDomain, /* domainSuspend */
testResumeDomain, /* domainResume */
testShutdownDomain, /* domainShutdown */
testRebootDomain, /* domainReboot */
testDestroyDomain, /* domainDestroy */
NULL, /* domainFree */
NULL, /* domainGetName */
NULL, /* domainGetID */
NULL, /* domainGetUUID */
testGetOSType, /* domainGetOSType */
testGetMaxMemory, /* domainGetMaxMemory */
testSetMaxMemory, /* domainSetMaxMemory */
testSetMemory, /* domainSetMemory */
testGetDomainInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
testSetVcpus, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
testDomainDumpXML, /* domainDumpXML */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
NULL, /* domainDefineXML */
NULL, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
VIR_DRV_TEST,
"Test",
LIBVIR_VERSION_NUMBER,
NULL, /* init */
testOpen, /* open */
testClose, /* close */
NULL, /* type */
testGetVersion, /* version */
testNodeGetInfo, /* nodeGetInfo */
testListDomains, /* listDomains */
testNumOfDomains, /* numOfDomains */
testDomainCreateLinux, /* domainCreateLinux */
testLookupDomainByID, /* domainLookupByID */
testLookupDomainByUUID, /* domainLookupByUUID */
testLookupDomainByName, /* domainLookupByName */
testPauseDomain, /* domainSuspend */
testResumeDomain, /* domainResume */
testShutdownDomain, /* domainShutdown */
testRebootDomain, /* domainReboot */
testDestroyDomain, /* domainDestroy */
NULL, /* domainFree */
NULL, /* domainGetName */
NULL, /* domainGetID */
NULL, /* domainGetUUID */
testGetOSType, /* domainGetOSType */
testGetMaxMemory, /* domainGetMaxMemory */
testSetMaxMemory, /* domainSetMaxMemory */
testSetMemory, /* domainSetMemory */
testGetDomainInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
testSetVcpus, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
testDomainDumpXML, /* domainDumpXML */
testListDefinedDomains, /* listDefinedDomains */
testNumOfDefinedDomains, /* numOfDefinedDomains */
testDomainCreate, /* domainCreate */
testDomainDefineXML, /* domainDefineXML */
testDomainUndefine, /* domainUndefine */
NULL, /* domainAttachDevice */
NULL, /* domainDetachDevice */
};
/* Amount of time it takes to shutdown */
#define SHUTDOWN_DURATION 15
typedef struct _testDev {
char name[20];
virDeviceMode mode;
char name[20];
virDeviceMode mode;
} testDev;
#define MAX_DEVICES 10
typedef struct _testDom {
int active;
char name[20];
unsigned char uuid[16];
virDomainKernel kernel;
virDomainInfo info;
time_t shutdownStartedAt;
virDomainRestart onRestart; /* What to do at end of current shutdown procedure */
virDomainRestart onReboot;
virDomainRestart onPoweroff;
virDomainRestart onCrash;
int numDevices;
testDev devices[MAX_DEVICES];
int active;
int handle;
char name[20];
unsigned char uuid[16];
virDomainKernel kernel;
virDomainInfo info;
unsigned int maxVCPUs;
virDomainRestart onRestart; /* What to do at end of current shutdown procedure */
virDomainRestart onReboot;
virDomainRestart onPoweroff;
virDomainRestart onCrash;
int numDevices;
testDev devices[MAX_DEVICES];
} testDom;
#define MAX_DOMAINS 20
typedef struct _testCon {
int active;
virNodeInfo nodeInfo;
int numDomains;
testDom domains[MAX_DOMAINS];
int active;
virNodeInfo nodeInfo;
int numDomains;
testDom domains[MAX_DOMAINS];
} testCon;
#define MAX_CONNECTIONS 5
typedef struct _testNode {
int numConnections;
testCon connections[MAX_CONNECTIONS];
int numConnections;
testCon connections[MAX_CONNECTIONS];
} testNode;
/* XXX, how about we stuff this in a SHM
......@@ -115,60 +177,61 @@ typedef struct _testNode {
Would need a pthread process shared mutex
too probably */
static testNode *node = NULL;
static int nextDomID = 1;
static const virNodeInfo defaultNodeInfo = {
"i686",
1024*1024*3, /* 3 GB */
16,
1400,
2,
2,
2,
2,
"i686",
1024*1024*3, /* 3 GB */
16,
1400,
2,
2,
2,
2,
};
static void
testError(virConnectPtr con,
virDomainPtr dom,
virErrorNumber error,
const char *info)
virDomainPtr dom,
virErrorNumber error,
const char *info)
{
const char *errmsg;
const char *errmsg;
if (error == VIR_ERR_OK)
return;
if (error == VIR_ERR_OK)
return;
errmsg = __virErrorMsg(error, info);
__virRaiseError(con, dom, VIR_FROM_XEN, error, VIR_ERR_ERROR,
errmsg, info, NULL, 0, 0, errmsg, info, 0);
errmsg = __virErrorMsg(error, info);
__virRaiseError(con, dom, VIR_FROM_XEN, error, VIR_ERR_ERROR,
errmsg, info, NULL, 0, 0, errmsg, info, 0);
}
static int testRestartStringToFlag(const char *str) {
if (!strcmp(str, "restart")) {
return VIR_DOMAIN_RESTART;
} else if (!strcmp(str, "destroy")) {
return VIR_DOMAIN_DESTROY;
} else if (!strcmp(str, "preserve")) {
return VIR_DOMAIN_PRESERVE;
} else if (!strcmp(str, "rename-restart")) {
return VIR_DOMAIN_RENAME_RESTART;
} else {
return 0;
}
if (!strcmp(str, "restart")) {
return VIR_DOMAIN_RESTART;
} else if (!strcmp(str, "destroy")) {
return VIR_DOMAIN_DESTROY;
} else if (!strcmp(str, "preserve")) {
return VIR_DOMAIN_PRESERVE;
} else if (!strcmp(str, "rename-restart")) {
return VIR_DOMAIN_RENAME_RESTART;
} else {
return (0);
}
}
static const char *testRestartFlagToString(int flag) {
switch (flag) {
case VIR_DOMAIN_RESTART:
return "restart";
case VIR_DOMAIN_DESTROY:
return "destroy";
case VIR_DOMAIN_PRESERVE:
return "preserve";
case VIR_DOMAIN_RENAME_RESTART:
return "rename-restart";
}
return NULL;
switch (flag) {
case VIR_DOMAIN_RESTART:
return "restart";
case VIR_DOMAIN_DESTROY:
return "destroy";
case VIR_DOMAIN_PRESERVE:
return "preserve";
case VIR_DOMAIN_RENAME_RESTART:
return "rename-restart";
}
return (NULL);
}
/**
......@@ -178,700 +241,784 @@ static const char *testRestartFlagToString(int flag) {
*/
void testRegister(void)
{
virRegisterDriver(&testDriver);
virRegisterDriver(&testDriver);
}
static int testLoadDomain(virConnectPtr conn,
int domid,
xmlDocPtr xml) {
xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL;
char *name = NULL;
unsigned char rawuuid[16];
char *dst_uuid;
testCon *con;
struct timeval tv;
unsigned long memory;
int nrVirtCpu;
char *conv;
virDomainRestart onReboot = VIR_DOMAIN_RESTART;
virDomainRestart onPoweroff = VIR_DOMAIN_DESTROY;
virDomainRestart onCrash = VIR_DOMAIN_RENAME_RESTART;
if (gettimeofday(&tv, NULL) < 0) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return -1;
}
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain"));
goto error;
}
ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
goto error;
}
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("domain name"));
goto error;
}
name = strdup((const char *)obj->stringval);
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
goto error;
}
dst_uuid = (char *) &rawuuid[0];
if (!(virParseUUID((char **)&dst_uuid, (const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
goto error;
}
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/memory[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
goto error;
}
memory = strtoll((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
goto error;
}
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
nrVirtCpu = 1;
} else {
nrVirtCpu = strtoll((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain vcpus"));
goto error;
int domid,
xmlDocPtr xml) {
xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL;
char *name = NULL;
unsigned char rawuuid[16];
char *dst_uuid;
testCon *con;
struct timeval tv;
unsigned long memory = 0;
unsigned long maxMem = 0;
int nrVirtCpu;
char *conv;
int handle = -1, i;
virDomainRestart onReboot = VIR_DOMAIN_RESTART;
virDomainRestart onPoweroff = VIR_DOMAIN_DESTROY;
virDomainRestart onCrash = VIR_DOMAIN_RENAME_RESTART;
if (gettimeofday(&tv, NULL) < 0) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
}
if (obj)
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_reboot[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain reboot behaviour"));
goto error;
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain"));
goto error;
}
}
if (obj)
ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
goto error;
}
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("domain name"));
goto error;
}
name = strdup((const char *)obj->stringval);
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_poweroff[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain poweroff behaviour"));
goto error;
obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
goto error;
}
dst_uuid = (char *) &rawuuid[0];
if (!(virParseUUID((char **)&dst_uuid, (const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_crash[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain crash behaviour"));
goto error;
obj = xmlXPathEval(BAD_CAST "string(/domain/memory[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
goto error;
}
maxMem = strtoll((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
con = &node->connections[conn->handle];
con->domains[domid].active = 1;
strncpy(con->domains[domid].name, name, sizeof(con->domains[domid].name));
free(name);
name = NULL;
obj = xmlXPathEval(BAD_CAST "string(/domain/currentMemory[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
memory = maxMem;
} else {
memory = strtoll((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain current memory"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
memmove(con->domains[domid].uuid, rawuuid, 16);
con->domains[domid].info.maxMem = memory;
con->domains[domid].info.memory = memory;
con->domains[domid].info.state = VIR_DOMAIN_RUNNING;
con->domains[domid].info.nrVirtCpu = nrVirtCpu;
con->domains[domid].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
con->domains[domid].onReboot = onReboot;
con->domains[domid].onPoweroff = onPoweroff;
con->domains[domid].onCrash = onCrash;
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
nrVirtCpu = 1;
} else {
nrVirtCpu = strtoll((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain vcpus"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_reboot[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain reboot behaviour"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_poweroff[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain poweroff behaviour"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
obj = xmlXPathEval(BAD_CAST "string(/domain/on_crash[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain crash behaviour"));
goto error;
}
}
if (obj)
xmlXPathFreeObject(obj);
return 0;
con = &node->connections[conn->handle];
error:
if (obj)
xmlXPathFreeObject(obj);
if (name)
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (!con->domains[i].active) {
handle = i;
break;
}
}
if (handle < 0)
return (-1);
con->domains[handle].active = 1;
con->domains[handle].handle = domid;
strncpy(con->domains[handle].name, name, sizeof(con->domains[handle].name));
free(name);
return -1;
name = NULL;
if (memory > maxMem)
memory = maxMem;
memmove(con->domains[handle].uuid, rawuuid, 16);
con->domains[handle].info.maxMem = maxMem;
con->domains[handle].info.memory = memory;
con->domains[handle].info.state = domid < 0 ? VIR_DOMAIN_SHUTOFF : VIR_DOMAIN_RUNNING;
con->domains[handle].info.nrVirtCpu = nrVirtCpu;
con->domains[handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
con->domains[handle].maxVCPUs = nrVirtCpu;
con->domains[handle].onReboot = onReboot;
con->domains[handle].onPoweroff = onPoweroff;
con->domains[handle].onCrash = onCrash;
return (0);
error:
if (obj)
xmlXPathFreeObject(obj);
if (name)
free(name);
return (-1);
}
static int testLoadDomainFromDoc(virConnectPtr conn,
int domid,
const char *doc) {
int ret;
xmlDocPtr xml;
if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
return -1;
}
ret = testLoadDomain(conn, domid, xml);
xmlFreeDoc(xml);
return ret;
int domid,
const char *doc) {
int ret;
xmlDocPtr xml;
if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
return (-1);
}
ret = testLoadDomain(conn, domid, xml);
xmlFreeDoc(xml);
return (ret);
}
static int testLoadDomainFromFile(virConnectPtr conn,
int domid,
const char *file) {
int ret, fd;
xmlDocPtr xml;
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file"));
return -1;
}
if (!(xml = xmlReadFd(fd, file, NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
int domid,
const char *file) {
int ret, fd;
xmlDocPtr xml;
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file"));
return (-1);
}
if (!(xml = xmlReadFd(fd, file, NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
close(fd);
return (-1);
}
close(fd);
return -1;
}
close(fd);
ret = testLoadDomain(conn, domid, xml);
ret = testLoadDomain(conn, domid, xml);
xmlFreeDoc(xml);
xmlFreeDoc(xml);
return ret;
return (ret);
}
static int testOpenDefault(virConnectPtr conn,
int connid) {
int u;
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return -1;
}
conn->handle = connid;
node->connections[connid].active = 1;
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
node->connections[connid].numDomains = 1;
node->connections[connid].domains[0].active = 1;
strcpy(node->connections[connid].domains[0].name, "Domain-0");
for (u = 0 ; u < 16 ; u++) {
node->connections[connid].domains[0].uuid[u] = (u * 75)%255;
}
node->connections[connid].domains[0].info.maxMem = 8192 * 1024;
node->connections[connid].domains[0].info.memory = 2048 * 1024;
node->connections[connid].domains[0].info.state = VIR_DOMAIN_RUNNING;
node->connections[connid].domains[0].info.nrVirtCpu = 2;
node->connections[connid].domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
return 0;
int connid) {
int u;
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
conn->handle = connid;
node->connections[connid].active = 1;
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
node->connections[connid].numDomains = 1;
node->connections[connid].domains[0].active = 1;
node->connections[connid].domains[0].handle = nextDomID++;
node->connections[connid].domains[0].onReboot = VIR_DOMAIN_RESTART;
node->connections[connid].domains[0].onCrash = VIR_DOMAIN_RESTART;
node->connections[connid].domains[0].onPoweroff = VIR_DOMAIN_DESTROY;
strcpy(node->connections[connid].domains[0].name, "test");
for (u = 0 ; u < 16 ; u++) {
node->connections[connid].domains[0].uuid[u] = (u * 75)%255;
}
node->connections[connid].domains[0].info.maxMem = 8192 * 1024;
node->connections[connid].domains[0].info.memory = 2048 * 1024;
node->connections[connid].domains[0].info.state = VIR_DOMAIN_RUNNING;
node->connections[connid].domains[0].info.nrVirtCpu = 2;
node->connections[connid].domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
return (0);
}
static char *testBuildFilename(const char *relativeTo,
const char *filename) {
char *offset;
int baseLen;
if (!filename || filename[0] == '\0')
return NULL;
if (filename[0] == '/')
return strdup(filename);
offset = rindex(relativeTo, '/');
if ((baseLen = (offset-relativeTo+1))) {
char *absFile = malloc(baseLen + strlen(filename) + 1);
strncpy(absFile, relativeTo, baseLen);
absFile[baseLen] = '\0';
strcat(absFile, filename);
return absFile;
} else {
return strdup(filename);
}
const char *filename) {
char *offset;
int baseLen;
if (!filename || filename[0] == '\0')
return (NULL);
if (filename[0] == '/')
return strdup(filename);
offset = rindex(relativeTo, '/');
if ((baseLen = (offset-relativeTo+1))) {
char *absFile = malloc(baseLen + strlen(filename) + 1);
strncpy(absFile, relativeTo, baseLen);
absFile[baseLen] = '\0';
strcat(absFile, filename);
return absFile;
} else {
return strdup(filename);
}
}
static int testOpenFromFile(virConnectPtr conn,
int connid,
const char *file) {
int fd, i;
xmlDocPtr xml;
xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL;
virNodeInfoPtr nodeInfo;
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
return -1;
}
if (!(xml = xmlReadFd(fd, file, NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("host"));
goto error;
}
close(fd);
fd = -1;
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node"));
goto error;
}
ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
goto error;
}
conn->handle = connid;
node->connections[connid].active = 1;
node->connections[connid].numDomains = 0;
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
nodeInfo = &node->connections[connid].nodeInfo;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/nodes[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->nodes = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu numa nodes"));
goto error;
int connid,
const char *file) {
int fd, i;
xmlDocPtr xml;
xmlNodePtr root = NULL;
xmlXPathContextPtr ctxt = NULL;
xmlXPathObjectPtr obj = NULL;
virNodeInfoPtr nodeInfo;
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
return (-1);
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/sockets[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->sockets = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu sockets"));
goto error;
if (!(xml = xmlReadFd(fd, file, NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("host"));
goto error;
}
xmlXPathFreeObject(obj);
}
close(fd);
fd = -1;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/cores[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->cores = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu cores"));
goto error;
root = xmlDocGetRootElement(xml);
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node"));
goto error;
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/threads[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->threads = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu threads"));
goto error;
ctxt = xmlXPathNewContext(xml);
if (ctxt == NULL) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
goto error;
}
xmlXPathFreeObject(obj);
}
nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/active[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
unsigned int active = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node active cpu"));
goto error;
conn->handle = connid;
node->connections[connid].active = 1;
node->connections[connid].numDomains = 0;
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
nodeInfo = &node->connections[connid].nodeInfo;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/nodes[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->nodes = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu numa nodes"));
goto error;
}
xmlXPathFreeObject(obj);
}
if (active < nodeInfo->cpus) {
nodeInfo->cpus = active;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/sockets[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->sockets = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu sockets"));
goto error;
}
xmlXPathFreeObject(obj);
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/mhz[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->mhz = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu mhz"));
goto error;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/cores[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->cores = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu cores"));
goto error;
}
xmlXPathFreeObject(obj);
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/model[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
strncpy(nodeInfo->model, (const char *)obj->stringval, sizeof(nodeInfo->model)-1);
nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/memory[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->memory = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node memory"));
goto error;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/threads[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->threads = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu threads"));
goto error;
}
xmlXPathFreeObject(obj);
}
nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/active[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
unsigned int active = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node active cpu"));
goto error;
}
if (active < nodeInfo->cpus) {
nodeInfo->cpus = active;
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/mhz[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->mhz = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu mhz"));
goto error;
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/model[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
strncpy(nodeInfo->model, (const char *)obj->stringval, sizeof(nodeInfo->model)-1);
nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
xmlXPathFreeObject(obj);
}
xmlXPathFreeObject(obj);
}
obj = xmlXPathEval(BAD_CAST "/node/domain", ctxt);
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL)) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list"));
goto error;
}
obj = xmlXPathEval(BAD_CAST "string(/node/memory[1])", ctxt);
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
char *conv = NULL;
nodeInfo->memory = strtol((const char*)obj->stringval, &conv, 10);
if (conv == (const char*)obj->stringval) {
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node memory"));
goto error;
}
xmlXPathFreeObject(obj);
}
for (i = 0 ; i < obj->nodesetval->nodeNr ; i++) {
xmlChar *domFile = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "file");
char *absFile = testBuildFilename(file, (const char *)domFile);
free(domFile);
if (!absFile) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename"));
goto error;
obj = xmlXPathEval(BAD_CAST "/node/domain", ctxt);
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
(obj->nodesetval == NULL)) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list"));
goto error;
}
if (testLoadDomainFromFile(conn, i, absFile) != 0) {
free(absFile);
goto error;
for (i = 0 ; i < obj->nodesetval->nodeNr ; i++) {
xmlChar *domFile = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "file");
char *absFile = testBuildFilename(file, (const char *)domFile);
int domid = nextDomID++;
free(domFile);
if (!absFile) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename"));
goto error;
}
if (testLoadDomainFromFile(conn, domid, absFile) != 0) {
free(absFile);
goto error;
}
free(absFile);
node->connections[connid].numDomains++;
}
free(absFile);
node->connections[connid].numDomains++;
}
xmlXPathFreeObject(obj);
xmlFreeDoc(xml);
xmlXPathFreeObject(obj);
xmlFreeDoc(xml);
return 0;
return (0);
error:
if (node->connections[connid].active) {
for (i = 0 ; i <node->connections[connid].numDomains ; i++) {
node->connections[connid].domains[i].active = 0;
if (node->connections[connid].active) {
for (i = 0 ; i <node->connections[connid].numDomains ; i++) {
node->connections[connid].domains[i].active = 0;
}
node->connections[connid].numDomains = 0;
node->connections[connid].active = 0;
}
node->connections[connid].numDomains = 0;
node->connections[connid].active = 0;
}
if (obj)
xmlXPathFreeObject(obj);
if (xml)
xmlFreeDoc(xml);
if (fd != -1)
close(fd);
return -1;
if (obj)
xmlXPathFreeObject(obj);
if (xml)
xmlFreeDoc(xml);
if (fd != -1)
close(fd);
return (-1);
}
static int getNextConnection(void) {
int i;
if (node == NULL) {
node = calloc(1, sizeof(testNode));
if (!node) {
testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating node"));
return -1;
int i;
if (node == NULL) {
node = calloc(1, sizeof(testNode));
nextDomID = 1;
if (!node) {
testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating node"));
return (-1);
}
}
for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
if (!node->connections[i].active) {
return (i);
}
}
}
return (-1);
}
for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
if (!node->connections[i].active) {
return i;
static int getDomainIndex(virDomainPtr domain) {
int i;
testCon *con;
con = &node->connections[domain->conn->handle];
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (domain->handle >= 0) {
if (domain->handle == con->domains[i].handle)
return (i);
} else {
if (!strcmp(domain->name, con->domains[i].name))
return (i);
}
}
}
return -1;
return (-1);
}
int testOpen(virConnectPtr conn,
const char *name,
int flags)
{
xmlURIPtr uri;
int ret, connid;
if (!name) {
return -1;
}
uri = xmlParseURI(name);
if (uri == NULL) {
if (!(flags & VIR_DRV_OPEN_QUIET))
testError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
return(-1);
}
if (!uri->scheme ||
strcmp(uri->scheme, "test") ||
!uri->path) {
xmlFreeURI(uri);
return -1;
}
xmlURIPtr uri;
int ret, connid;
if (!name) {
return (-1);
}
if ((connid = getNextConnection()) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many connections"));
return -1;
}
uri = xmlParseURI(name);
if (uri == NULL) {
if (!(flags & VIR_DRV_OPEN_QUIET))
testError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
return(-1);
}
if (!strcmp(uri->path, "/default")) {
ret = testOpenDefault(conn,
connid);
} else {
ret = testOpenFromFile(conn,
connid,
uri->path);
}
if (!uri->scheme ||
strcmp(uri->scheme, "test") ||
!uri->path) {
xmlFreeURI(uri);
return (-1);
}
xmlFreeURI(uri);
return (ret);
if ((connid = getNextConnection()) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many connections"));
return (-1);
}
if (!strcmp(uri->path, "/default")) {
ret = testOpenDefault(conn,
connid);
} else {
ret = testOpenFromFile(conn,
connid,
uri->path);
}
xmlFreeURI(uri);
return (ret);
}
int testClose(virConnectPtr conn)
{
testCon *con = &node->connections[conn->handle];
con->active = 0;
conn->handle = -1;
memset(con, 0, sizeof(testCon));
return 0;
testCon *con = &node->connections[conn->handle];
con->active = 0;
conn->handle = -1;
memset(con, 0, sizeof(testCon));
return (0);
}
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
unsigned long *hvVer)
{
*hvVer = 2;
return 0;
*hvVer = 2;
return (0);
}
int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info)
{
testCon *con = &node->connections[conn->handle];
memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
return 0;
testCon *con = &node->connections[conn->handle];
memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
return (0);
}
int testNumOfDomains(virConnectPtr conn)
{
testCon *con = &node->connections[conn->handle];
return con->numDomains;
int numActive = 0, i;
testCon *con = &node->connections[conn->handle];
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (!con->domains[i].active ||
con->domains[i].info.state == VIR_DOMAIN_SHUTOFF)
continue;
numActive++;
}
return (numActive);
}
virDomainPtr
testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
unsigned int flags ATTRIBUTE_UNUSED)
unsigned int flags ATTRIBUTE_UNUSED)
{
testCon *con;
int i;
virDomainPtr dom;
testCon *con;
int domid, handle = -1, i;
virDomainPtr dom;
if (!VIR_IS_CONNECT(conn)) {
testError(conn, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xmlDesc == NULL) {
testError(conn, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO) {
testError(conn, NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (NULL);
}
con = &node->connections[conn->handle];
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (!con->domains[i].active) {
if (testLoadDomainFromDoc(conn, i, xmlDesc) < 0)
return NULL;
dom = virGetDomain(conn, con->domains[i].name, con->domains[i].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return NULL;
}
con->numDomains++;
return dom;
}
}
if (!VIR_IS_CONNECT(conn)) {
testError(conn, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xmlDesc == NULL) {
testError(conn, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO) {
testError(conn, NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (NULL);
}
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains"));
return (NULL);
con = &node->connections[conn->handle];
if (con->numDomains == MAX_DOMAINS) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains"));
return (NULL);
}
domid = nextDomID++;
if (testLoadDomainFromDoc(conn, domid, xmlDesc) < 0)
return (NULL);
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].handle == domid) {
handle = i;
break;
}
}
dom = virGetDomain(conn, con->domains[handle].name, con->domains[handle].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return (NULL);
}
con->numDomains++;
return (dom);
}
virDomainPtr testLookupDomainByID(virConnectPtr conn,
int id)
{
testCon *con = &node->connections[conn->handle];
virDomainPtr dom;
if (!con->domains[id].active) {
return NULL;
}
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
}
dom->handle = id;
return dom;
testCon *con = &node->connections[conn->handle];
virDomainPtr dom;
int i, idx = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
con->domains[i].handle == id) {
idx = i;
break;
}
}
if (idx < 0) {
return(NULL);
}
dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
}
dom->handle = id;
return (dom);
}
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
const unsigned char *uuid)
{
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, id = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
memcmp(uuid, con->domains[i].uuid, 16) == 0) {
id = i;
break;
}
}
if (id >= 0) {
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, idx = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
memcmp(uuid, con->domains[i].uuid, 16) == 0) {
idx = i;
break;
}
}
dom->handle = id;
}
return dom;
if (idx >= 0) {
dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
}
dom->handle = con->domains[idx].handle;
}
return (dom);
}
virDomainPtr testLookupDomainByName(virConnectPtr conn,
const char *name)
{
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, id = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
strcmp(name, con->domains[i].name) == 0) {
id = i;
break;
}
}
if (id >= 0) {
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, idx = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
strcmp(name, con->domains[i].name) == 0) {
idx = i;
break;
}
}
dom->handle = id;
}
return dom;
if (idx >= 0) {
dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid);
if (dom == NULL) {
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
return(NULL);
}
dom->handle = con->domains[idx].handle;
}
return (dom);
}
int testListDomains (virConnectPtr conn,
int *ids,
int maxids)
{
testCon *con = &node->connections[conn->handle];
int n, i;
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
if (con->domains[i].active) {
ids[n++] = i;
testCon *con = &node->connections[conn->handle];
int n, i;
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
if (con->domains[i].active &&
con->domains[i].info.state != VIR_DOMAIN_SHUTOFF) {
ids[n++] = con->domains[i].handle;
}
}
}
return n;
return (n);
}
int testDestroyDomain (virDomainPtr domain)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].active = 0;
return (0);
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con->domains[domidx].active = 0;
return (0);
}
int testResumeDomain (virDomainPtr domain)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
return 0;
con = &node->connections[domain->conn->handle];
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
return (0);
}
int testPauseDomain (virDomainPtr domain)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;\
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_PAUSED;
return (0);
con = &node->connections[domain->conn->handle];
con->domains[domidx].info.state = VIR_DOMAIN_PAUSED;
return (0);
}
/* We don't do an immediate shutdown. We basically pretend that
......@@ -880,242 +1027,361 @@ int testPauseDomain (virDomainPtr domain)
will check to see if shutdown ought to be marked complete. */
int testShutdownDomain (virDomainPtr domain)
{
testCon *con;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;
int domidx;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con = &node->connections[domain->conn->handle];
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTDOWN;
con->domains[domain->handle].onRestart = VIR_DOMAIN_DESTROY;
con->domains[domain->handle].shutdownStartedAt = tv.tv_sec;
return (0);
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
domain->handle = -1;
con->domains[domidx].handle = -1;
return (0);
}
/* Similar behaviour as shutdown */
int testRebootDomain (virDomainPtr domain, virDomainRestart action)
{
testCon *con;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;
int domidx;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con = &node->connections[domain->conn->handle];
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
if (!action)
action = VIR_DOMAIN_RESTART;
con->domains[domidx].info.state = VIR_DOMAIN_SHUTDOWN;
switch (action) {
case VIR_DOMAIN_DESTROY:
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
break;
case VIR_DOMAIN_RESTART:
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
break;
case VIR_DOMAIN_PRESERVE:
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
break;
case VIR_DOMAIN_RENAME_RESTART:
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
break;
if (!action)
action = VIR_DOMAIN_RESTART;
default:
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
break;
}
domain->handle = -1;
con->domains[domidx].handle = -1;
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTDOWN;
con->domains[domain->handle].onRestart = action;
con->domains[domain->handle].shutdownStartedAt = tv.tv_sec;
return (0);
return (0);
}
int testGetDomainInfo (virDomainPtr domain,
virDomainInfoPtr info)
{
struct timeval tv;
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
con = &node->connections[domain->conn->handle];
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
/* Check to see if there is an in-progresss shutdown/reboot that
needs to be marked completed now */
if (con->domains[domain->handle].info.state == VIR_DOMAIN_SHUTDOWN &&
(tv.tv_sec - con->domains[domain->handle].shutdownStartedAt) > SHUTDOWN_DURATION) {
switch (con->domains[domain->handle].onRestart) {
case VIR_DOMAIN_DESTROY:
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF;
break;
case VIR_DOMAIN_RESTART:
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
break;
case VIR_DOMAIN_PRESERVE:
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF;
break;
case VIR_DOMAIN_RENAME_RESTART:
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
break;
default:
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTOFF;
break;
}
}
if (con->domains[domain->handle].info.state == VIR_DOMAIN_SHUTOFF) {
con->domains[domain->handle].info.cpuTime = 0;
con->domains[domain->handle].info.memory = 0;
} else {
con->domains[domain->handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
}
memcpy(info, &con->domains[domain->handle].info, sizeof(virDomainInfo));
return (0);
struct timeval tv;
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return (-1);
}
if (con->domains[domidx].info.state == VIR_DOMAIN_SHUTOFF) {
con->domains[domidx].info.cpuTime = 0;
con->domains[domidx].info.memory = 0;
} else {
con->domains[domidx].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
}
memcpy(info, &con->domains[domidx].info, sizeof(virDomainInfo));
return (0);
}
char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
return strdup("linux");
return strdup("linux");
}
unsigned long testGetMaxMemory(virDomainPtr domain) {
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
con = &node->connections[domain->conn->handle];
return con->domains[domain->handle].info.maxMem;
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
return con->domains[domidx].info.maxMem;
}
int testSetMaxMemory (virDomainPtr domain,
unsigned long memory)
int testSetMaxMemory(virDomainPtr domain,
unsigned long memory)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
/* XXX validate not over host memory wrt to other domains */
con->domains[domain->handle].info.maxMem = memory;
return (0);
con = &node->connections[domain->conn->handle];
/* XXX validate not over host memory wrt to other domains */
con->domains[domidx].info.maxMem = memory;
return (0);
}
int testSetMemory (virDomainPtr domain,
unsigned long memory)
int testSetMemory(virDomainPtr domain,
unsigned long memory)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con = &node->connections[domain->conn->handle];
if (memory > con->domains[domain->handle].info.maxMem) {
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (-1);
}
if (memory > con->domains[domidx].info.maxMem) {
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (-1);
}
con->domains[domain->handle].info.memory = memory;
return (0);
con->domains[domidx].info.memory = memory;
return (0);
}
int testSetVcpus(virDomainPtr domain,
unsigned int nrCpus) {
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
unsigned int nrCpus) {
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
con = &node->connections[domain->conn->handle];
/* We allow more cpus in guest than host */
if (nrCpus > 32) {
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (-1);
}
/* We allow more cpus in guest than host */
if (nrCpus > 32) {
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (-1);
}
con->domains[domain->handle].info.nrVirtCpu = nrCpus;
return (0);
con->domains[domidx].info.nrVirtCpu = nrCpus;
return (0);
}
char * testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
{
virBufferPtr buf;
char *xml;
unsigned char *uuid;
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return(NULL);
}
con = &node->connections[domain->conn->handle];
if (!(buf = virBufferNew(4000))) {
return (NULL);
}
virBufferVSprintf(buf, "<domain type='test' id='%d'>\n", domain->handle);
virBufferVSprintf(buf, " <name>%s</name>\n", domain->name);
uuid = domain->uuid;
virBufferVSprintf(buf,
" <uuid>%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x</uuid>\n",
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]);
virBufferVSprintf(buf, " <memory>%d</memory>\n", con->domains[domain->handle].info.maxMem);
virBufferVSprintf(buf, " <vcpu>%d</vcpu>\n", con->domains[domain->handle].info.nrVirtCpu);
virBufferVSprintf(buf, " <on_reboot>%s</on_reboot>\n", testRestartFlagToString(con->domains[domain->handle].onReboot));
virBufferVSprintf(buf, " <on_poweroff>%s</on_poweroff>\n", testRestartFlagToString(con->domains[domain->handle].onPoweroff));
virBufferVSprintf(buf, " <on_crash>%s</on_crash>\n", testRestartFlagToString(con->domains[domain->handle].onCrash));
virBufferAdd(buf, "</domain>\n", -1);
xml = buf->content;
free(buf);
return xml;
virBufferPtr buf;
char *xml;
unsigned char *uuid;
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (NULL);
}
con = &node->connections[domain->conn->handle];
if (!(buf = virBufferNew(4000))) {
return (NULL);
}
virBufferVSprintf(buf, "<domain type='test' id='%d'>\n", domain->handle);
virBufferVSprintf(buf, " <name>%s</name>\n", domain->name);
uuid = domain->uuid;
virBufferVSprintf(buf,
" <uuid>%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x</uuid>\n",
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]);
virBufferVSprintf(buf, " <memory>%d</memory>\n", con->domains[domidx].info.maxMem);
virBufferVSprintf(buf, " <vcpu>%d</vcpu>\n", con->domains[domidx].info.nrVirtCpu);
virBufferVSprintf(buf, " <on_reboot>%s</on_reboot>\n", testRestartFlagToString(con->domains[domidx].onReboot));
virBufferVSprintf(buf, " <on_poweroff>%s</on_poweroff>\n", testRestartFlagToString(con->domains[domidx].onPoweroff));
virBufferVSprintf(buf, " <on_crash>%s</on_crash>\n", testRestartFlagToString(con->domains[domidx].onCrash));
virBufferAdd(buf, "</domain>\n", -1);
xml = buf->content;
free(buf);
return (xml);
}
int testNumOfDefinedDomains(virConnectPtr conn) {
int numInactive = 0, i;
testCon *con = &node->connections[conn->handle];
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (!con->domains[i].active ||
con->domains[i].info.state != VIR_DOMAIN_SHUTOFF)
continue;
numInactive++;
}
return (numInactive);
}
int testListDefinedDomains(virConnectPtr conn,
const char **names,
int maxnames) {
testCon *con = &node->connections[conn->handle];
int n = 0, i;
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxnames ; i++) {
if (con->domains[i].active &&
con->domains[i].info.state == VIR_DOMAIN_SHUTOFF) {
names[n++] = strdup(con->domains[i].name);
}
}
return (n);
}
virDomainPtr testDomainDefineXML(virConnectPtr conn,
const char *doc) {
int ret;
xmlDocPtr xml;
int domid;
if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
return (NULL);
}
domid = nextDomID++;
ret = testLoadDomain(conn, domid, xml);
xmlFreeDoc(xml);
if (ret < 0)
return (NULL);
return testLookupDomainByID(conn, domid);
}
int testDomainCreate(virDomainPtr domain) {
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) {
testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR,
_("Domain is already running"));
return (-1);
}
domain->handle = con->domains[domidx].handle = nextDomID++;
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
return (0);
}
int testDomainUndefine(virDomainPtr domain) {
testCon *con;
int domidx;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
((domidx = getDomainIndex(domain)) < 0)) {
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
__FUNCTION__);
return (-1);
}
con = &node->connections[domain->conn->handle];
if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) {
testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR,
_("Domain is still running"));
return (-1);
}
con->domains[domidx].active = 0;
return (0);
}
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
/*
* test.h: A "mock" hypervisor for use by application unit tests
*
* Copyright (C) 2006 Red Hat, Inc.
* Copyright (C) 2006-2006 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* See COPYING.LIB for the License of this software
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Daniel Berrange <berrange@redhat.com>
*/
#ifndef __VIR_TEST_SIMPLE_INTERNAL_H__
#define __VIR_TEST_SIMPLE_INTERNAL_H__
#ifndef __VIR_TEST_INTERNAL_H__
#define __VIR_TEST_INTERNAL_H__
#include <libvirt/virterror.h>
......@@ -17,47 +30,18 @@
extern "C" {
#endif
void testRegister(void);
int testOpen(virConnectPtr conn,
const char *name,
int flags);
int testClose (virConnectPtr conn);
int testGetVersion(virConnectPtr conn,
unsigned long *hvVer);
int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info);
int testNumOfDomains(virConnectPtr conn);
int testListDomains(virConnectPtr conn,
int *ids,
int maxids);
char *testGetOSType(virDomainPtr dom);
virDomainPtr
testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
unsigned int flags ATTRIBUTE_UNUSED);
virDomainPtr testLookupDomainByID(virConnectPtr conn,
int id);
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
const unsigned char *uuid);
virDomainPtr testLookupDomainByName(virConnectPtr conn,
const char *name);
int testDestroyDomain(virDomainPtr domain);
int testResumeDomain(virDomainPtr domain);
int testPauseDomain(virDomainPtr domain);
int testShutdownDomain (virDomainPtr domain);
int testRebootDomain (virDomainPtr domain,
virDomainRestart action);
int testGetDomainInfo(virDomainPtr domain,
virDomainInfoPtr info);
unsigned long testGetMaxMemory(virDomainPtr domain);
int testSetMaxMemory(virDomainPtr domain,
unsigned long memory);
int testSetMemory(virDomainPtr domain,
unsigned long memory);
int testSetVcpus(virDomainPtr domain,
unsigned int nrCpus);
char * testDomainDumpXML(virDomainPtr domain, int flags);
void testRegister(void);
#ifdef __cplusplus
}
#endif
#endif /* __VIR_TEST_INTERNAL_H__ */
#endif /* __VIR_TEST_INTERNAL_H__ */
/*
* Local variables:
* indent-tabs-mode: nil
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
* End:
*/
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册