Index: docs/testdomfc4.xml
===================================================================
RCS file: docs/testdomfc4.xml
diff -N docs/testdomfc4.xml
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- docs/testdomfc4.xml 16 Aug 2006 15:55:17 -0000
***************
*** 0 ****
--- 1,25 ----
+
+ fc4
+ EF86180145B911CB88E3AFBFE5370493
+
+ linux
+ /boot/vmlinuz-2.6.15-1.43_FC5guest
+ /boot/initrd-2.6.15-1.43_FC5guest.img
+ /dev/sda1
+ ro selinux=0 3
+
+ 131072
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: docs/testdomfv0.xml
===================================================================
RCS file: docs/testdomfv0.xml
diff -N docs/testdomfv0.xml
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- docs/testdomfv0.xml 16 Aug 2006 15:55:17 -0000
***************
*** 0 ****
--- 1,42 ----
+
+ fv0
+ 4dea22b31d52d8f32516782e98ab3fa0
+
+ hvm
+ /usr/lib/xen/boot/hvmloader
+
+
+ 524288
+ 1524288
+ 4
+ destroy
+ restart
+ restart
+
+
+
+
+
+
+ /usr/lib/xen/bin/qemu-dm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: docs/testnode.xml
===================================================================
RCS file: docs/testnode.xml
diff -N docs/testnode.xml
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- docs/testnode.xml 16 Aug 2006 15:55:17 -0000
***************
*** 0 ****
--- 1,23 ----
+
+
+
+
+
+
+ 6000
+ i986
+ 50
+ 4
+ 4
+ 4
+ 2
+
+ 137438953472
+
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.6
diff -c -r1.6 test.c
*** src/test.c 9 Aug 2006 15:21:16 -0000 1.6
--- src/test.c 16 Aug 2006 15:55:17 -0000
***************
*** 11,20 ****
--- 11,26 ----
#include
#include
#include
+ #include
+ #include
+ #include
#include
+ #include
+ #include
#include "internal.h"
#include "test.h"
+ #include "xml.h"
static virDriver testDriver = {
VIR_DRV_TEST,
***************
*** 28,34 ****
testNodeGetInfo, /* nodeGetInfo */
testListDomains, /* listDomains */
testNumOfDomains, /* numOfDomains */
! NULL, /* domainCreateLinux */
testLookupDomainByID, /* domainLookupByID */
testLookupDomainByUUID, /* domainLookupByUUID */
testLookupDomainByName, /* domainLookupByName */
--- 34,40 ----
testNodeGetInfo, /* nodeGetInfo */
testListDomains, /* listDomains */
testNumOfDomains, /* numOfDomains */
! testDomainCreateLinux, /* domainCreateLinux */
testLookupDomainByID, /* domainLookupByID */
testLookupDomainByUUID, /* domainLookupByUUID */
testLookupDomainByName, /* domainLookupByName */
***************
*** 42,57 ****
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
! NULL, /* domainGetMaxMemory */
testSetMaxMemory, /* domainSetMaxMemory */
! NULL, /* domainSetMemory */
testGetDomainInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
! NULL, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
! NULL, /* domainDumpXML */
};
/* Amount of time it takes to shutdown */
--- 48,63 ----
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
! testGetMaxMemory, /* domainGetMaxMemory */
testSetMaxMemory, /* domainSetMaxMemory */
! testSetMemory, /* domainSetMemory */
testGetDomainInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
! testSetVcpus, /* domainSetVcpus */
NULL, /* domainPinVcpu */
NULL, /* domainGetVcpus */
! testDomainDumpXML, /* domainDumpXML */
};
/* Amount of time it takes to shutdown */
***************
*** 71,77 ****
virDomainKernel kernel;
virDomainInfo info;
time_t shutdownStartedAt;
! virDomainRestart onRestart;
int numDevices;
testDev devices[MAX_DEVICES];
} testDom;
--- 77,86 ----
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];
} testDom;
***************
*** 80,85 ****
--- 89,95 ----
typedef struct _testCon {
int active;
+ virNodeInfo nodeInfo;
int numDomains;
testDom domains[MAX_DOMAINS];
} testCon;
***************
*** 98,105 ****
too probably */
static testNode *node = NULL;
! static virNodeInfo nodeInfo = {
! "i86",
1024*1024*3, /* 3 GB */
16,
1400,
--- 108,115 ----
too probably */
static testNode *node = NULL;
! static const virNodeInfo defaultNodeInfo = {
! "i686",
1024*1024*3, /* 3 GB */
16,
1400,
***************
*** 125,130 ****
--- 135,167 ----
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;
+ }
+ }
+
+ 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;
+ }
/**
* testRegister:
***************
*** 136,148 ****
virRegisterDriver(&testDriver);
}
int testOpen(virConnectPtr conn,
const char *name,
int flags)
{
xmlURIPtr uri;
! int i, j;
if (!name) {
return -1;
--- 173,624 ----
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, "cannot get timeofday");
+ return -1;
+ }
+
+ root = xmlDocGetRootElement(xml);
+ if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
+ testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, "malformed root element");
+ goto error;
+ }
+
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, "cannot create 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, "missing name element on domain");
+ 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_INTERNAL_ERROR, "missing uuid element on domain");
+ goto error;
+ }
+ dst_uuid = (char *) &rawuuid[0];
+ if (!(virParseUUID((char **)&dst_uuid, (const char *)obj->stringval))) {
+ testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, "malformed uuid data in domain");
+ 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_INTERNAL_ERROR, "missing memory element on domain");
+ goto error;
+ }
+ memory = strtoll((const char*)obj->stringval, &conv, 10);
+ if (conv == (const char*)obj->stringval) {
+ testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, "malformed memory value for domain");
+ 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_INTERNAL_ERROR, "malformed vcpus value for domain");
+ 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_INTERNAL_ERROR, "malformed on_reboot value for domain");
+ 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_INTERNAL_ERROR, "malformed on_poweroff value for domain");
+ 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_INTERNAL_ERROR, "malformed on_crash value for domain");
+ 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;
+
+ 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;
+
+ 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_INTERNAL_ERROR, "cannot parse domain definition");
+ 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, "cannot load domain definition");
+ 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, "cannot parse domain definition");
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ ret = testLoadDomain(conn, domid, xml);
+
+ xmlFreeDoc(xml);
+
+ 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, "cannot get timeofday");
+ 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;
+ }
+
+
+ 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);
+ }
+ }
+
+ 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, "cannot load host definition");
+ 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, "cannot parse host definition");
+ goto error;
+ }
+ close(fd);
+ fd = -1;
+
+ root = xmlDocGetRootElement(xml);
+ if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "malformed root element");
+ goto error;
+ }
+
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot create 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_INTERNAL_ERROR, "malformed nodes value for node cpu");
+ goto error;
+ }
+ 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_INTERNAL_ERROR, "malformed sockets value for node cpu");
+ goto error;
+ }
+ xmlXPathFreeObject(obj);
+ }
+
+ 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_INTERNAL_ERROR, "malformed cores value for node cpu");
+ 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_INTERNAL_ERROR, "malformed threads value for node cpu");
+ 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_INTERNAL_ERROR, "malformed active value for node 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_INTERNAL_ERROR, "malformed threads value for node cpu");
+ 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);
+ }
+
+ 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_INTERNAL_ERROR, "malformed memory value for node");
+ goto error;
+ }
+ xmlXPathFreeObject(obj);
+ }
+
+ obj = xmlXPathEval(BAD_CAST "/node/domain", ctxt);
+ if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
+ (obj->nodesetval == NULL)) {
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot extract domain list");
+ 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);
+ free(domFile);
+ if (!absFile) {
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot resolve filename");
+ goto error;
+ }
+ if (testLoadDomainFromFile(conn, i, absFile) != 0) {
+ free(absFile);
+ goto error;
+ }
+ free(absFile);
+ node->connections[connid].numDomains++;
+ }
+
+ xmlXPathFreeObject(obj);
+ xmlFreeDoc(xml);
+
+ return 0;
+
+ error:
+ if (node->connections[connid].active) {
+ for (i = 0 ; i connections[connid].numDomains ; i++) {
+ node->connections[connid].domains[i].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;
+ }
+
+ static int getNextConnection(void) {
+ int i;
+ if (node == NULL) {
+ node = calloc(1, sizeof(testNode));
+ if (!node) {
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot allocate memory");
+ return -1;
+ }
+ }
+
+ for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
+ if (!node->connections[i].active) {
+ return i;
+ }
+ }
+ return -1;
+ }
int testOpen(virConnectPtr conn,
const char *name,
int flags)
{
xmlURIPtr uri;
! int ret, connid;
if (!name) {
return -1;
***************
*** 157,209 ****
if (!uri->scheme ||
strcmp(uri->scheme, "test") ||
! !uri->path ||
! strcmp(uri->path, "/default")) {
xmlFreeURI(uri);
return -1;
}
! xmlFreeURI(uri);
!
! if (node == NULL) {
! node = calloc(1, sizeof(testNode));
! if (!node) {
! testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot allocate memory");
! return -1;
! }
}
! for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
! if (!node->connections[i].active) {
! struct timeval tv;
!
! if (gettimeofday(&tv, NULL) < 0) {
! testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! return -1;
! }
!
! conn->handle = i;
! node->connections[i].active = 1;
!
! node->connections[i].numDomains = 1;
! node->connections[i].domains[0].active = 1;
! strcpy(node->connections[i].domains[0].name, "Domain-0");
! for (j = 0 ; j < 16 ; j++) {
! node->connections[i].domains[0].uuid[j] = (j * 75)%255;
! }
! node->connections[i].domains[0].info.maxMem = 8192 * 1024;
! node->connections[i].domains[0].info.memory = 2048 * 1024;
! node->connections[i].domains[0].info.state = VIR_DOMAIN_RUNNING;
! node->connections[i].domains[0].info.nrVirtCpu = 2;
! node->connections[i].domains[0].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
! return 0;
! }
}
! testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "too make connections");
! return -1;
}
int testClose(virConnectPtr conn)
--- 633,661 ----
if (!uri->scheme ||
strcmp(uri->scheme, "test") ||
! !uri->path) {
xmlFreeURI(uri);
return -1;
}
! 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)
***************
*** 218,231 ****
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
unsigned long *hvVer)
{
! *hvVer = 1;
return 0;
}
! int testNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
virNodeInfoPtr info)
{
! memcpy(info, &nodeInfo, sizeof(nodeInfo));
return 0;
}
--- 670,684 ----
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
unsigned long *hvVer)
{
! *hvVer = 2;
return 0;
}
! int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info)
{
! testCon *con = &node->connections[conn->handle];
! memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
return 0;
}
***************
*** 235,248 ****
--- 688,745 ----
return con->numDomains;
}
+ virDomainPtr
+ testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags ATTRIBUTE_UNUSED)
+ {
+ testCon *con;
+ int 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_READ_ONLY, __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;
+ }
+ }
+
+ testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "too many domains");
+ return (NULL);
+ }
+
+
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");
***************
*** 317,339 ****
int testDestroyDomain (virDomainPtr domain)
{
! testCon *con = &node->connections[domain->conn->handle];
con->domains[domain->handle].active = 0;
! return 0;
}
int testResumeDomain (virDomainPtr domain)
{
! testCon *con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_RUNNING;
return 0;
}
int testPauseDomain (virDomainPtr domain)
{
! testCon *con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_PAUSED;
! return 0;
}
/* We don't do an immediate shutdown. We basically pretend that
--- 814,869 ----
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_READ_ONLY, __FUNCTION__);
! return (-1);
! }
!
! con = &node->connections[domain->conn->handle];
con->domains[domain->handle].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_READ_ONLY, __FUNCTION__);
! return (-1);
! }
!
! con = &node->connections[domain->conn->handle];
con->domains[domain->handle].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_READ_ONLY, __FUNCTION__);
! return (-1);
! }
!
! con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.state = VIR_DOMAIN_PAUSED;
! return (0);
}
/* We don't do an immediate shutdown. We basically pretend that
***************
*** 342,368 ****
will check to see if shutdown ought to be marked complete. */
int testShutdownDomain (virDomainPtr domain)
{
! testCon *con = &node->connections[domain->conn->handle];
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! 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;
}
/* Similar behaviour as shutdown */
int testRebootDomain (virDomainPtr domain, virDomainRestart action)
{
! testCon *con = &node->connections[domain->conn->handle];
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! return -1;
}
if (!action)
--- 872,922 ----
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_READ_ONLY, __FUNCTION__);
+ return (-1);
+ }
+
+ con = &node->connections[domain->conn->handle];
+
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! 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);
}
/* 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_READ_ONLY, __FUNCTION__);
+ return (-1);
+ }
+
+ con = &node->connections[domain->conn->handle];
+
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! return (-1);
}
if (!action)
***************
*** 371,387 ****
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;
}
int testGetDomainInfo (virDomainPtr domain,
virDomainInfoPtr info)
{
- testCon *con = &node->connections[domain->conn->handle];
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, "cannot get timeofday");
! return -1;
}
/* Check to see if there is an in-progresss shutdown/reboot that
--- 925,949 ----
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);
}
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, "cannot get timeofday");
! return (-1);
}
/* Check to see if there is an in-progresss shutdown/reboot that
***************
*** 419,431 ****
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;
}
int testSetMaxMemory (virDomainPtr domain,
unsigned long memory)
{
! testCon *con = &node->connections[domain->conn->handle];
con->domains[domain->handle].info.maxMem = memory;
! return 0;
}
--- 981,1109 ----
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);
! }
!
! 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;
}
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_READ_ONLY, __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);
! }
!
! 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_READ_ONLY, __FUNCTION__);
! return (-1);
! }
!
! con = &node->connections[domain->conn->handle];
!
! if (memory > con->domains[domain->handle].info.maxMem) {
! testError(domain->conn, domain, VIR_ERR_INVALID_ARG, "memory over maximum limit");
! return (-1);
! }
!
! con->domains[domain->handle].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_READ_ONLY, __FUNCTION__);
! return (-1);
! }
!
! 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, "too many virtual cpus");
! return (-1);
! }
!
! con->domains[domain->handle].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, "\n", domain->handle);
! virBufferVSprintf(buf, " %s\n", domain->name);
! uuid = domain->uuid;
! virBufferVSprintf(buf,
! " %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\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, " %d\n", con->domains[domain->handle].info.maxMem);
! virBufferVSprintf(buf, " %d\n", con->domains[domain->handle].info.nrVirtCpu);
! virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domain->handle].onReboot));
! virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domain->handle].onPoweroff));
! virBufferVSprintf(buf, " %s\n", testRestartFlagToString(con->domains[domain->handle].onCrash));
!
! virBufferAdd(buf, "\n", -1);
!
! xml = buf->content;
! free(buf);
! return xml;
}
Index: src/test.h
===================================================================
RCS file: /data/cvs/libvirt/src/test.h,v
retrieving revision 1.3
diff -c -r1.3 test.h
*** src/test.h 26 Jun 2006 15:02:18 -0000 1.3
--- src/test.h 16 Aug 2006 15:55:17 -0000
***************
*** 30,35 ****
--- 30,38 ----
int testListDomains(virConnectPtr conn,
int *ids,
int maxids);
+ virDomainPtr
+ testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags ATTRIBUTE_UNUSED);
virDomainPtr testLookupDomainByID(virConnectPtr conn,
int id);
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
***************
*** 44,53 ****
virDomainRestart action);
int testGetDomainInfo(virDomainPtr domain,
virDomainInfoPtr info);
! int testGetDomainID(virDomainPtr domain);
! const char*testGetDomainName(virDomainPtr domain);
int testSetMaxMemory(virDomainPtr domain,
unsigned long memory);
#ifdef __cplusplus
}
--- 47,60 ----
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);
#ifdef __cplusplus
}