提交 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
......
/*
* 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,6 +35,57 @@
#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",
......@@ -59,18 +123,15 @@ static virDriver testDriver = {
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
testDomainDumpXML, /* domainDumpXML */
NULL, /* listDefinedDomains */
NULL, /* numOfDefinedDomains */
NULL, /* domainCreate */
NULL, /* domainDefineXML */
NULL, /* domainUndefine */
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;
......@@ -80,11 +141,12 @@ typedef struct _testDev {
typedef struct _testDom {
int active;
int handle;
char name[20];
unsigned char uuid[16];
virDomainKernel kernel;
virDomainInfo info;
time_t shutdownStartedAt;
unsigned int maxVCPUs;
virDomainRestart onRestart; /* What to do at end of current shutdown procedure */
virDomainRestart onReboot;
virDomainRestart onPoweroff;
......@@ -115,6 +177,7 @@ 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",
......@@ -153,7 +216,7 @@ static int testRestartStringToFlag(const char *str) {
} else if (!strcmp(str, "rename-restart")) {
return VIR_DOMAIN_RENAME_RESTART;
} else {
return 0;
return (0);
}
}
......@@ -168,7 +231,7 @@ static const char *testRestartFlagToString(int flag) {
case VIR_DOMAIN_RENAME_RESTART:
return "rename-restart";
}
return NULL;
return (NULL);
}
/**
......@@ -192,16 +255,18 @@ static int testLoadDomain(virConnectPtr conn,
char *dst_uuid;
testCon *con;
struct timeval tv;
unsigned long memory;
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;
return (-1);
}
root = xmlDocGetRootElement(xml);
......@@ -244,13 +309,31 @@ static int testLoadDomain(virConnectPtr conn,
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
goto error;
}
memory = strtoll((const char*)obj->stringval, &conv, 10);
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;
}
xmlXPathFreeObject(obj);
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);
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
......@@ -300,30 +383,44 @@ static int testLoadDomain(virConnectPtr conn,
con = &node->connections[conn->handle];
con->domains[domid].active = 1;
strncpy(con->domains[domid].name, name, sizeof(con->domains[domid].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);
name = NULL;
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));
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[domid].onReboot = onReboot;
con->domains[domid].onPoweroff = onPoweroff;
con->domains[domid].onCrash = onCrash;
con->domains[handle].onReboot = onReboot;
con->domains[handle].onPoweroff = onPoweroff;
con->domains[handle].onCrash = onCrash;
return 0;
return (0);
error:
if (obj)
xmlXPathFreeObject(obj);
if (name)
free(name);
return -1;
return (-1);
}
static int testLoadDomainFromDoc(virConnectPtr conn,
......@@ -335,14 +432,14 @@ static int testLoadDomainFromDoc(virConnectPtr conn,
XML_PARSE_NOENT | XML_PARSE_NONET |
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
return -1;
return (-1);
}
ret = testLoadDomain(conn, domid, xml);
xmlFreeDoc(xml);
return ret;
return (ret);
}
static int testLoadDomainFromFile(virConnectPtr conn,
......@@ -353,7 +450,7 @@ static int testLoadDomainFromFile(virConnectPtr conn,
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file"));
return -1;
return (-1);
}
if (!(xml = xmlReadFd(fd, file, NULL,
......@@ -361,7 +458,7 @@ static int testLoadDomainFromFile(virConnectPtr conn,
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
close(fd);
return -1;
return (-1);
}
close(fd);
......@@ -369,7 +466,7 @@ static int testLoadDomainFromFile(virConnectPtr conn,
xmlFreeDoc(xml);
return ret;
return (ret);
}
......@@ -380,7 +477,7 @@ static int testOpenDefault(virConnectPtr conn,
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
return -1;
return (-1);
}
conn->handle = connid;
......@@ -389,7 +486,11 @@ static int testOpenDefault(virConnectPtr conn,
node->connections[connid].numDomains = 1;
node->connections[connid].domains[0].active = 1;
strcpy(node->connections[connid].domains[0].name, "Domain-0");
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;
}
......@@ -398,7 +499,7 @@ static int testOpenDefault(virConnectPtr conn,
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;
return (0);
}
......@@ -407,7 +508,7 @@ static char *testBuildFilename(const char *relativeTo,
char *offset;
int baseLen;
if (!filename || filename[0] == '\0')
return NULL;
return (NULL);
if (filename[0] == '/')
return strdup(filename);
......@@ -435,7 +536,7 @@ static int testOpenFromFile(virConnectPtr conn,
if ((fd = open(file, O_RDONLY)) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
return -1;
return (-1);
}
if (!(xml = xmlReadFd(fd, file, NULL,
......@@ -568,12 +669,13 @@ static int testOpenFromFile(virConnectPtr conn,
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, i, absFile) != 0) {
if (testLoadDomainFromFile(conn, domid, absFile) != 0) {
free(absFile);
goto error;
}
......@@ -584,7 +686,7 @@ static int testOpenFromFile(virConnectPtr conn,
xmlXPathFreeObject(obj);
xmlFreeDoc(xml);
return 0;
return (0);
error:
if (node->connections[connid].active) {
......@@ -600,25 +702,42 @@ static int testOpenFromFile(virConnectPtr conn,
xmlFreeDoc(xml);
if (fd != -1)
close(fd);
return -1;
return (-1);
}
static int getNextConnection(void) {
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;
return (-1);
}
}
for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
if (!node->connections[i].active) {
return i;
return (i);
}
}
return -1;
return (-1);
}
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);
}
int testOpen(virConnectPtr conn,
......@@ -629,7 +748,7 @@ int testOpen(virConnectPtr conn,
int ret, connid;
if (!name) {
return -1;
return (-1);
}
uri = xmlParseURI(name);
......@@ -643,13 +762,13 @@ int testOpen(virConnectPtr conn,
strcmp(uri->scheme, "test") ||
!uri->path) {
xmlFreeURI(uri);
return -1;
return (-1);
}
if ((connid = getNextConnection()) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many connections"));
return -1;
return (-1);
}
if (!strcmp(uri->path, "/default")) {
......@@ -672,14 +791,14 @@ int testClose(virConnectPtr conn)
con->active = 0;
conn->handle = -1;
memset(con, 0, sizeof(testCon));
return 0;
return (0);
}
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
unsigned long *hvVer)
{
*hvVer = 2;
return 0;
return (0);
}
int testNodeGetInfo(virConnectPtr conn,
......@@ -687,13 +806,20 @@ int testNodeGetInfo(virConnectPtr conn,
{
testCon *con = &node->connections[conn->handle];
memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
return 0;
return (0);
}
int testNumOfDomains(virConnectPtr conn)
{
int numActive = 0, i;
testCon *con = &node->connections[conn->handle];
return con->numDomains;
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
......@@ -701,7 +827,7 @@ testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
unsigned int flags ATTRIBUTE_UNUSED)
{
testCon *con;
int i;
int domid, handle = -1, i;
virDomainPtr dom;
if (!VIR_IS_CONNECT(conn)) {
......@@ -719,22 +845,27 @@ testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
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].active) {
if (testLoadDomainFromDoc(conn, i, xmlDesc) < 0)
return NULL;
dom = virGetDomain(conn, con->domains[i].name, con->domains[i].uuid);
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;
return (NULL);
}
con->numDomains++;
return dom;
}
}
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains"));
return (NULL);
return (dom);
}
......@@ -743,18 +874,27 @@ virDomainPtr testLookupDomainByID(virConnectPtr conn,
{
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 (!con->domains[id].active) {
return NULL;
if (idx < 0) {
return(NULL);
}
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
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;
return (dom);
}
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
......@@ -762,23 +902,23 @@ virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
{
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, id = -1;
int i, idx = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
memcmp(uuid, con->domains[i].uuid, 16) == 0) {
id = i;
idx = i;
break;
}
}
if (id >= 0) {
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
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 = id;
dom->handle = con->domains[idx].handle;
}
return dom;
return (dom);
}
virDomainPtr testLookupDomainByName(virConnectPtr conn,
......@@ -786,23 +926,23 @@ virDomainPtr testLookupDomainByName(virConnectPtr conn,
{
testCon *con = &node->connections[conn->handle];
virDomainPtr dom = NULL;
int i, id = -1;
int i, idx = -1;
for (i = 0 ; i < MAX_DOMAINS ; i++) {
if (con->domains[i].active &&
strcmp(name, con->domains[i].name) == 0) {
id = i;
idx = i;
break;
}
}
if (id >= 0) {
dom = virGetDomain(conn, con->domains[id].name, con->domains[id].uuid);
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 = id;
dom->handle = con->domains[idx].handle;
}
return dom;
return (dom);
}
int testListDomains (virConnectPtr conn,
......@@ -813,20 +953,23 @@ int testListDomains (virConnectPtr conn,
int n, i;
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
if (con->domains[i].active) {
ids[n++] = 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)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -834,17 +977,19 @@ int testDestroyDomain (virDomainPtr domain)
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].active = 0;
con->domains[domidx].active = 0;
return (0);
}
int testResumeDomain (virDomainPtr domain)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -852,17 +997,19 @@ int testResumeDomain (virDomainPtr domain)
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
return 0;
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)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -870,7 +1017,7 @@ int testPauseDomain (virDomainPtr domain)
}
con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_PAUSED;
con->domains[domidx].info.state = VIR_DOMAIN_PAUSED;
return (0);
}
......@@ -881,8 +1028,10 @@ int testPauseDomain (virDomainPtr domain)
int testShutdownDomain (virDomainPtr domain)
{
testCon *con;
int domidx;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
......@@ -899,9 +1048,10 @@ int testShutdownDomain (virDomainPtr domain)
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;
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
domain->handle = -1;
con->domains[domidx].handle = -1;
return (0);
}
......@@ -909,11 +1059,13 @@ int testShutdownDomain (virDomainPtr domain)
int testRebootDomain (virDomainPtr domain, virDomainRestart action)
{
testCon *con;
int domidx;
struct timeval tv;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -930,9 +1082,31 @@ int testRebootDomain (virDomainPtr domain, virDomainRestart action)
if (!action)
action = VIR_DOMAIN_RESTART;
con->domains[domain->handle].info.state = VIR_DOMAIN_SHUTDOWN;
con->domains[domain->handle].onRestart = action;
con->domains[domain->handle].shutdownStartedAt = tv.tv_sec;
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;
default:
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
break;
}
domain->handle = -1;
con->domains[domidx].handle = -1;
return (0);
}
......@@ -941,10 +1115,12 @@ int testGetDomainInfo (virDomainPtr domain,
{
struct timeval tv;
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
con = &node->connections[domain->conn->handle];
......@@ -954,41 +1130,13 @@ int testGetDomainInfo (virDomainPtr domain,
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;
if (con->domains[domidx].info.state == VIR_DOMAIN_SHUTOFF) {
con->domains[domidx].info.cpuTime = 0;
con->domains[domidx].info.memory = 0;
} else {
con->domains[domain->handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
con->domains[domidx].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
}
memcpy(info, &con->domains[domain->handle].info, sizeof(virDomainInfo));
memcpy(info, &con->domains[domidx].info, sizeof(virDomainInfo));
return (0);
}
......@@ -998,24 +1146,28 @@ char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
unsigned long testGetMaxMemory(virDomainPtr domain) {
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
con = &node->connections[domain->conn->handle];
return con->domains[domain->handle].info.maxMem;
return con->domains[domidx].info.maxMem;
}
int testSetMaxMemory (virDomainPtr domain,
int testSetMaxMemory(virDomainPtr domain,
unsigned long memory)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -1024,18 +1176,20 @@ int testSetMaxMemory (virDomainPtr domain,
con = &node->connections[domain->conn->handle];
/* XXX validate not over host memory wrt to other domains */
con->domains[domain->handle].info.maxMem = memory;
con->domains[domidx].info.maxMem = memory;
return (0);
}
int testSetMemory (virDomainPtr domain,
int testSetMemory(virDomainPtr domain,
unsigned long memory)
{
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -1044,23 +1198,24 @@ int testSetMemory (virDomainPtr domain,
con = &node->connections[domain->conn->handle];
if (memory > con->domains[domain->handle].info.maxMem) {
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;
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)) {
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);
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO) {
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
......@@ -1075,7 +1230,7 @@ int testSetVcpus(virDomainPtr domain,
return (-1);
}
con->domains[domain->handle].info.nrVirtCpu = nrCpus;
con->domains[domidx].info.nrVirtCpu = nrCpus;
return (0);
}
......@@ -1085,10 +1240,12 @@ char * testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
char *xml;
unsigned char *uuid;
testCon *con;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
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);
return (NULL);
}
con = &node->connections[domain->conn->handle];
......@@ -1107,15 +1264,124 @@ char * testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
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));
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;
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__ */
/*
* 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.
先完成此消息的编辑!
想要评论请 注册