mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
Hook up more test driver methods. Allow HV config to be loaded from extenral XML definition
This commit is contained in:
parent
64d25e8de5
commit
5c2831b30b
@ -1,3 +1,11 @@
|
||||
Wed Aug 16 11:38:02 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
||||
|
||||
* src/test.c, src/test.h: Allow a hypervisor config to be
|
||||
loaded from an external XML file. Implement drivers for
|
||||
setMemory, setMaxMemory, createLinux, dumpXML, setVcpus.
|
||||
* docs/testnode.xml, docs/testfc4.xml, docs/testfv0.xml:
|
||||
Example config for using with test driver
|
||||
|
||||
Wed Aug 16 11:36:21 EDT 2006 Daniel Berrange <berrange@redhat.com>
|
||||
|
||||
* src/xend_internal.c, src/xml.c, src/xml.h: Refactored the
|
||||
|
25
docs/testdomfc4.xml
Normal file
25
docs/testdomfc4.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<domain type='test'>
|
||||
<name>fc4</name>
|
||||
<uuid>EF86180145B911CB88E3AFBFE5370493</uuid>
|
||||
<os>
|
||||
<type>linux</type>
|
||||
<kernel>/boot/vmlinuz-2.6.15-1.43_FC5guest</kernel>
|
||||
<initrd>/boot/initrd-2.6.15-1.43_FC5guest.img</initrd>
|
||||
<root>/dev/sda1</root>
|
||||
<cmdline> ro selinux=0 3</cmdline>
|
||||
</os>
|
||||
<memory>131072</memory>
|
||||
<vcpu>1</vcpu>
|
||||
<devices>
|
||||
<disk type='file'>
|
||||
<source file='/u/fc4.img'/>
|
||||
<target dev='sda1'/>
|
||||
</disk>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='aa:00:00:00:00:11'/>
|
||||
<script path='/etc/xen/scripts/vif-bridge'/>
|
||||
</interface>
|
||||
<console tty='/dev/pts/5'/>
|
||||
</devices>
|
||||
</domain>
|
42
docs/testdomfv0.xml
Normal file
42
docs/testdomfv0.xml
Normal file
@ -0,0 +1,42 @@
|
||||
<domain type='test'>
|
||||
<name>fv0</name>
|
||||
<uuid>4dea22b31d52d8f32516782e98ab3fa0</uuid>
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<boot dev='hd'/>
|
||||
</os>
|
||||
<memory>524288</memory>
|
||||
<maxMemory>1524288</maxMemory>
|
||||
<vcpu>4</vcpu>
|
||||
<on_poweroff>destroy</on_poweroff>
|
||||
<on_reboot>restart</on_reboot>
|
||||
<on_crash>restart</on_crash>
|
||||
<features>
|
||||
<pae/>
|
||||
<acpi/>
|
||||
<apic/>
|
||||
</features>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='00:16:3e:5d:c7:9e'/>
|
||||
<script path='vif-bridge'/>
|
||||
</interface>
|
||||
<disk type='file'>
|
||||
<source file='/root/fv0'/>
|
||||
<target dev='hda'/>
|
||||
</disk>
|
||||
<disk type='file' device='cdrom'>
|
||||
<source file='/root/fc5-x86_64-boot.iso'/>
|
||||
<target dev='hdc'/>
|
||||
<readonly/>
|
||||
</disk>
|
||||
<disk type='file' device='floppy'>
|
||||
<source file='/root/fd.img'/>
|
||||
<target dev='fda'/>
|
||||
</disk>
|
||||
<graphics type='vnc' port='5904'/>
|
||||
</devices>
|
||||
</domain>
|
23
docs/testnode.xml
Normal file
23
docs/testnode.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<node>
|
||||
<!-- This file gives an example config for the mock 'test' backend
|
||||
driver to libvirt. This is intended to allow relible unit testing
|
||||
of applications using libvirt. To use this with virsh, run something
|
||||
like:
|
||||
|
||||
virsh -connect test:////path/to/this/dir/testnode.xml nodeinfo
|
||||
|
||||
-->
|
||||
<domain file="testdomfv0.xml"/>
|
||||
<domain file="testdomfc4.xml"/>
|
||||
|
||||
<cpu>
|
||||
<mhz>6000</mhz>
|
||||
<model>i986</model>
|
||||
<active>50</active>
|
||||
<nodes>4</nodes>
|
||||
<sockets>4</sockets>
|
||||
<cores>4</cores>
|
||||
<threads>2</threads>
|
||||
</cpu>
|
||||
<memory>137438953472</memory>
|
||||
</node>
|
814
src/test.c
814
src/test.c
@ -11,10 +11,16 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/uri.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "internal.h"
|
||||
#include "test.h"
|
||||
#include "xml.h"
|
||||
|
||||
static virDriver testDriver = {
|
||||
VIR_DRV_TEST,
|
||||
@ -28,7 +34,7 @@ static virDriver testDriver = {
|
||||
testNodeGetInfo, /* nodeGetInfo */
|
||||
testListDomains, /* listDomains */
|
||||
testNumOfDomains, /* numOfDomains */
|
||||
NULL, /* domainCreateLinux */
|
||||
testDomainCreateLinux, /* domainCreateLinux */
|
||||
testLookupDomainByID, /* domainLookupByID */
|
||||
testLookupDomainByUUID, /* domainLookupByUUID */
|
||||
testLookupDomainByName, /* domainLookupByName */
|
||||
@ -42,16 +48,16 @@ static virDriver testDriver = {
|
||||
NULL, /* domainGetID */
|
||||
NULL, /* domainGetUUID */
|
||||
NULL, /* domainGetOSType */
|
||||
NULL, /* domainGetMaxMemory */
|
||||
testGetMaxMemory, /* domainGetMaxMemory */
|
||||
testSetMaxMemory, /* domainSetMaxMemory */
|
||||
NULL, /* domainSetMemory */
|
||||
testSetMemory, /* domainSetMemory */
|
||||
testGetDomainInfo, /* domainGetInfo */
|
||||
NULL, /* domainSave */
|
||||
NULL, /* domainRestore */
|
||||
NULL, /* domainSetVcpus */
|
||||
testSetVcpus, /* domainSetVcpus */
|
||||
NULL, /* domainPinVcpu */
|
||||
NULL, /* domainGetVcpus */
|
||||
NULL, /* domainDumpXML */
|
||||
testDomainDumpXML, /* domainDumpXML */
|
||||
};
|
||||
|
||||
/* Amount of time it takes to shutdown */
|
||||
@ -71,7 +77,10 @@ typedef struct _testDom {
|
||||
virDomainKernel kernel;
|
||||
virDomainInfo info;
|
||||
time_t shutdownStartedAt;
|
||||
virDomainRestart onRestart;
|
||||
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,6 +89,7 @@ typedef struct _testDom {
|
||||
|
||||
typedef struct _testCon {
|
||||
int active;
|
||||
virNodeInfo nodeInfo;
|
||||
int numDomains;
|
||||
testDom domains[MAX_DOMAINS];
|
||||
} testCon;
|
||||
@ -98,8 +108,8 @@ typedef struct _testNode {
|
||||
too probably */
|
||||
static testNode *node = NULL;
|
||||
|
||||
static virNodeInfo nodeInfo = {
|
||||
"i86",
|
||||
static const virNodeInfo defaultNodeInfo = {
|
||||
"i686",
|
||||
1024*1024*3, /* 3 GB */
|
||||
16,
|
||||
1400,
|
||||
@ -125,6 +135,33 @@ testError(virConnectPtr con,
|
||||
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,13 +173,452 @@ void testRegister(void)
|
||||
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 <node->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 i, j;
|
||||
int ret, connid;
|
||||
|
||||
if (!name) {
|
||||
return -1;
|
||||
@ -157,53 +633,29 @@ int testOpen(virConnectPtr conn,
|
||||
|
||||
if (!uri->scheme ||
|
||||
strcmp(uri->scheme, "test") ||
|
||||
!uri->path ||
|
||||
strcmp(uri->path, "/default")) {
|
||||
!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);
|
||||
|
||||
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;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int testClose(virConnectPtr conn)
|
||||
@ -218,14 +670,15 @@ int testClose(virConnectPtr conn)
|
||||
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
unsigned long *hvVer)
|
||||
{
|
||||
*hvVer = 1;
|
||||
*hvVer = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testNodeGetInfo(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
int testNodeGetInfo(virConnectPtr conn,
|
||||
virNodeInfoPtr info)
|
||||
{
|
||||
memcpy(info, &nodeInfo, sizeof(nodeInfo));
|
||||
testCon *con = &node->connections[conn->handle];
|
||||
memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -235,14 +688,58 @@ int testNumOfDomains(virConnectPtr conn)
|
||||
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,23 +814,56 @@ int testListDomains (virConnectPtr conn,
|
||||
|
||||
int testDestroyDomain (virDomainPtr domain)
|
||||
{
|
||||
testCon *con = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int testResumeDomain (virDomainPtr domain)
|
||||
{
|
||||
testCon *con = &node->connections[domain->conn->handle];
|
||||
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 = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* We don't do an immediate shutdown. We basically pretend that
|
||||
@ -342,27 +872,51 @@ int testPauseDomain (virDomainPtr domain)
|
||||
will check to see if shutdown ought to be marked complete. */
|
||||
int testShutdownDomain (virDomainPtr domain)
|
||||
{
|
||||
testCon *con = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
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;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Similar behaviour as shutdown */
|
||||
int testRebootDomain (virDomainPtr domain, virDomainRestart action)
|
||||
{
|
||||
testCon *con = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!action)
|
||||
@ -371,17 +925,25 @@ int testRebootDomain (virDomainPtr domain, virDomainRestart action)
|
||||
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)
|
||||
{
|
||||
testCon *con = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Check to see if there is an in-progresss shutdown/reboot that
|
||||
@ -419,13 +981,129 @@ int testGetDomainInfo (virDomainPtr domain,
|
||||
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;
|
||||
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 = &node->connections[domain->conn->handle];
|
||||
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;
|
||||
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, "<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;
|
||||
}
|
||||
|
11
src/test.h
11
src/test.h
@ -30,6 +30,9 @@ int testNumOfDomains(virConnectPtr conn);
|
||||
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,10 +47,14 @@ int testRebootDomain (virDomainPtr domain,
|
||||
virDomainRestart action);
|
||||
int testGetDomainInfo(virDomainPtr domain,
|
||||
virDomainInfoPtr info);
|
||||
int testGetDomainID(virDomainPtr domain);
|
||||
const char*testGetDomainName(virDomainPtr domain);
|
||||
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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user