2006-06-06 03:32:51 +00:00
|
|
|
/*
|
|
|
|
* test.c: A "mock" hypervisor for use by application unit tests
|
|
|
|
*
|
2007-01-18 21:08:21 +00:00
|
|
|
* Copyright (C) 2006-2007 Red Hat, Inc.
|
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
2006-06-06 03:32:51 +00:00
|
|
|
*
|
2007-01-18 21:08:21 +00:00
|
|
|
* 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
|
2006-06-06 03:32:51 +00:00
|
|
|
*
|
|
|
|
* Daniel Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2007-03-15 07:43:16 +00:00
|
|
|
#ifdef WITH_TEST
|
2006-06-06 03:32:51 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/time.h>
|
2006-08-16 16:36:39 +00:00
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <libxml/tree.h>
|
|
|
|
#include <libxml/xpath.h>
|
2006-06-06 03:32:51 +00:00
|
|
|
#include <libxml/uri.h>
|
2006-08-16 16:36:39 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
#include <unistd.h>
|
2006-06-06 03:32:51 +00:00
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include "test.h"
|
2006-08-16 16:36:39 +00:00
|
|
|
#include "xml.h"
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
2007-03-15 17:24:56 +00:00
|
|
|
char *testGetCapabilities (virConnectPtr conn);
|
2007-01-18 21:08:21 +00:00
|
|
|
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,
|
2007-03-06 21:55:44 +00:00
|
|
|
char **const names,
|
2007-01-18 21:08:21 +00:00
|
|
|
int maxnames);
|
|
|
|
|
|
|
|
virDomainPtr testDomainDefineXML(virConnectPtr conn,
|
|
|
|
const char *xml);
|
|
|
|
|
|
|
|
int testDomainCreate(virDomainPtr dom);
|
|
|
|
|
|
|
|
int testDomainUndefine(virDomainPtr dom);
|
|
|
|
|
2006-06-06 03:32:51 +00:00
|
|
|
static virDriver testDriver = {
|
2007-01-18 21:08:21 +00:00
|
|
|
VIR_DRV_TEST,
|
|
|
|
"Test",
|
|
|
|
LIBVIR_VERSION_NUMBER,
|
|
|
|
testOpen, /* open */
|
|
|
|
testClose, /* close */
|
|
|
|
NULL, /* type */
|
|
|
|
testGetVersion, /* version */
|
2007-03-08 08:31:07 +00:00
|
|
|
NULL, /* getMaxVcpus */
|
2007-01-18 21:08:21 +00:00
|
|
|
testNodeGetInfo, /* nodeGetInfo */
|
2007-03-15 17:24:56 +00:00
|
|
|
testGetCapabilities, /* getCapabilities */
|
2007-01-18 21:08:21 +00:00
|
|
|
testListDomains, /* listDomains */
|
|
|
|
testNumOfDomains, /* numOfDomains */
|
|
|
|
testDomainCreateLinux, /* domainCreateLinux */
|
|
|
|
testLookupDomainByID, /* domainLookupByID */
|
|
|
|
testLookupDomainByUUID, /* domainLookupByUUID */
|
|
|
|
testLookupDomainByName, /* domainLookupByName */
|
|
|
|
testPauseDomain, /* domainSuspend */
|
|
|
|
testResumeDomain, /* domainResume */
|
|
|
|
testShutdownDomain, /* domainShutdown */
|
|
|
|
testRebootDomain, /* domainReboot */
|
|
|
|
testDestroyDomain, /* domainDestroy */
|
|
|
|
testGetOSType, /* domainGetOSType */
|
|
|
|
testGetMaxMemory, /* domainGetMaxMemory */
|
|
|
|
testSetMaxMemory, /* domainSetMaxMemory */
|
|
|
|
testSetMemory, /* domainSetMemory */
|
|
|
|
testGetDomainInfo, /* domainGetInfo */
|
|
|
|
NULL, /* domainSave */
|
|
|
|
NULL, /* domainRestore */
|
|
|
|
NULL, /* domainCoreDump */
|
|
|
|
testSetVcpus, /* domainSetVcpus */
|
|
|
|
NULL, /* domainPinVcpu */
|
|
|
|
NULL, /* domainGetVcpus */
|
2007-03-08 08:31:07 +00:00
|
|
|
NULL, /* domainGetMaxVcpus */
|
2007-01-18 21:08:21 +00:00
|
|
|
testDomainDumpXML, /* domainDumpXML */
|
|
|
|
testListDefinedDomains, /* listDefinedDomains */
|
|
|
|
testNumOfDefinedDomains, /* numOfDefinedDomains */
|
|
|
|
testDomainCreate, /* domainCreate */
|
|
|
|
testDomainDefineXML, /* domainDefineXML */
|
|
|
|
testDomainUndefine, /* domainUndefine */
|
|
|
|
NULL, /* domainAttachDevice */
|
|
|
|
NULL, /* domainDetachDevice */
|
2007-02-23 08:51:30 +00:00
|
|
|
NULL, /* domainGetAutostart */
|
|
|
|
NULL, /* domainSetAutostart */
|
2006-06-06 03:32:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct _testDev {
|
2007-01-18 21:08:21 +00:00
|
|
|
char name[20];
|
|
|
|
virDeviceMode mode;
|
2006-06-06 03:32:51 +00:00
|
|
|
} testDev;
|
|
|
|
|
|
|
|
#define MAX_DEVICES 10
|
|
|
|
|
|
|
|
typedef struct _testDom {
|
2007-01-18 21:08:21 +00:00
|
|
|
int active;
|
2007-01-22 16:25:27 +00:00
|
|
|
int id;
|
2007-01-18 21:08:21 +00:00
|
|
|
char name[20];
|
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 14:39:45 +00:00
|
|
|
unsigned char uuid[VIR_UUID_BUFLEN];
|
2007-01-18 21:08:21 +00:00
|
|
|
virDomainKernel kernel;
|
|
|
|
virDomainInfo info;
|
|
|
|
unsigned int maxVCPUs;
|
|
|
|
virDomainRestart onRestart; /* What to do at end of current shutdown procedure */
|
|
|
|
virDomainRestart onReboot;
|
|
|
|
virDomainRestart onPoweroff;
|
|
|
|
virDomainRestart onCrash;
|
|
|
|
int numDevices;
|
|
|
|
testDev devices[MAX_DEVICES];
|
2006-06-06 03:32:51 +00:00
|
|
|
} testDom;
|
|
|
|
|
|
|
|
#define MAX_DOMAINS 20
|
|
|
|
|
|
|
|
typedef struct _testCon {
|
2007-01-18 21:08:21 +00:00
|
|
|
int active;
|
|
|
|
virNodeInfo nodeInfo;
|
|
|
|
int numDomains;
|
|
|
|
testDom domains[MAX_DOMAINS];
|
2006-06-06 03:32:51 +00:00
|
|
|
} testCon;
|
|
|
|
|
|
|
|
#define MAX_CONNECTIONS 5
|
|
|
|
|
|
|
|
typedef struct _testNode {
|
2007-01-18 21:08:21 +00:00
|
|
|
int numConnections;
|
|
|
|
testCon connections[MAX_CONNECTIONS];
|
2006-06-06 03:32:51 +00:00
|
|
|
} testNode;
|
|
|
|
|
|
|
|
/* XXX, how about we stuff this in a SHM
|
|
|
|
segment so multiple apps can run tests
|
|
|
|
against the mock hypervisor concurrently.
|
|
|
|
Would need a pthread process shared mutex
|
|
|
|
too probably */
|
|
|
|
static testNode *node = NULL;
|
2007-01-18 21:08:21 +00:00
|
|
|
static int nextDomID = 1;
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-03-15 17:24:56 +00:00
|
|
|
#define TEST_MODEL "i686"
|
|
|
|
#define TEST_MODEL_WORDSIZE "32"
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
static const virNodeInfo defaultNodeInfo = {
|
2007-03-15 17:24:56 +00:00
|
|
|
TEST_MODEL,
|
2007-01-18 21:08:21 +00:00
|
|
|
1024*1024*3, /* 3 GB */
|
|
|
|
16,
|
|
|
|
1400,
|
|
|
|
2,
|
|
|
|
2,
|
|
|
|
2,
|
|
|
|
2,
|
2006-06-06 03:32:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
testError(virConnectPtr con,
|
2007-01-18 21:08:21 +00:00
|
|
|
virDomainPtr dom,
|
|
|
|
virErrorNumber error,
|
|
|
|
const char *info)
|
2006-06-06 03:32:51 +00:00
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
const char *errmsg;
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (error == VIR_ERR_OK)
|
|
|
|
return;
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
errmsg = __virErrorMsg(error, info);
|
Tue Feb 14 15:37:17 EST 2007 Mark McLoughlin <markmc@redhat.com>
Note: potential ABI break here, but people should
only really be using virError structs returned from
libvirt itself.
* include/libvirt/virterror.h: add virNetwork
to virError
* src/internal.h, src/virterror.c: add network param
to __virRaiseError()
* src/conf.c, src/hash.c, src/libvirt.c, src/proxy_internal.c,
src/qemu_internal.c, src/sexpr.c, src/test.c, src/xen_internal.c,
src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c,
src/xs_internal.c: update.
2007-02-14 15:40:53 +00:00
|
|
|
__virRaiseError(con, dom, NULL, VIR_FROM_XEN, error, VIR_ERR_ERROR,
|
2007-01-18 21:08:21 +00:00
|
|
|
errmsg, info, NULL, 0, 0, errmsg, info, 0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
static int testRestartStringToFlag(const char *str) {
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const char *testRestartFlagToString(int flag) {
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* testRegister:
|
|
|
|
*
|
|
|
|
* Registers the test driver
|
|
|
|
*/
|
|
|
|
void testRegister(void)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
virRegisterDriver(&testDriver);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
static int testLoadDomain(virConnectPtr conn,
|
2007-01-18 21:08:21 +00:00
|
|
|
int domid,
|
|
|
|
xmlDocPtr xml) {
|
|
|
|
xmlNodePtr root = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
xmlXPathObjectPtr obj = NULL;
|
|
|
|
char *name = NULL;
|
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 14:39:45 +00:00
|
|
|
unsigned char rawuuid[VIR_UUID_BUFLEN];
|
2007-01-18 21:08:21 +00:00
|
|
|
char *dst_uuid;
|
|
|
|
testCon *con;
|
|
|
|
struct timeval tv;
|
|
|
|
unsigned long memory = 0;
|
|
|
|
unsigned long maxMem = 0;
|
|
|
|
int nrVirtCpu;
|
|
|
|
char *conv;
|
|
|
|
int handle = -1, i;
|
|
|
|
virDomainRestart onReboot = VIR_DOMAIN_RESTART;
|
|
|
|
virDomainRestart onPoweroff = VIR_DOMAIN_DESTROY;
|
|
|
|
virDomainRestart onCrash = VIR_DOMAIN_RENAME_RESTART;
|
|
|
|
|
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
|
|
|
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
|
|
|
|
return (-1);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
root = xmlDocGetRootElement(xml);
|
|
|
|
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "domain"))) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
ctxt = xmlXPathNewContext(xml);
|
|
|
|
if (ctxt == NULL) {
|
|
|
|
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/name[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("domain name"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
name = strdup((const char *)obj->stringval);
|
2006-08-16 16:36:39 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/uuid[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
dst_uuid = (char *) &rawuuid[0];
|
|
|
|
if (!(virParseUUID((char **)&dst_uuid, (const char *)obj->stringval))) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain uuid"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/memory[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
maxMem = strtoll((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain memory"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_STRING) ||
|
|
|
|
(obj->stringval == NULL) || (obj->stringval[0] == 0)) {
|
|
|
|
nrVirtCpu = 1;
|
|
|
|
} else {
|
|
|
|
nrVirtCpu = strtoll((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain vcpus"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/on_reboot[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain reboot behaviour"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/on_poweroff[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain poweroff behaviour"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/domain/on_crash[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
if (!(onReboot = testRestartStringToFlag((const char *)obj->stringval))) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("domain crash behaviour"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[conn->handle];
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
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;
|
2007-01-22 16:25:27 +00:00
|
|
|
con->domains[handle].id = domid;
|
2007-01-18 21:08:21 +00:00
|
|
|
strncpy(con->domains[handle].name, name, sizeof(con->domains[handle].name));
|
2006-08-16 16:36:39 +00:00
|
|
|
free(name);
|
2007-01-18 21:08:21 +00:00
|
|
|
name = NULL;
|
|
|
|
|
|
|
|
if (memory > maxMem)
|
|
|
|
memory = maxMem;
|
|
|
|
|
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 14:39:45 +00:00
|
|
|
memmove(con->domains[handle].uuid, rawuuid, VIR_UUID_BUFLEN);
|
2007-01-18 21:08:21 +00:00
|
|
|
con->domains[handle].info.maxMem = maxMem;
|
|
|
|
con->domains[handle].info.memory = memory;
|
|
|
|
con->domains[handle].info.state = domid < 0 ? VIR_DOMAIN_SHUTOFF : VIR_DOMAIN_RUNNING;
|
|
|
|
con->domains[handle].info.nrVirtCpu = nrVirtCpu;
|
|
|
|
con->domains[handle].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
|
|
|
|
con->domains[handle].maxVCPUs = nrVirtCpu;
|
|
|
|
|
|
|
|
con->domains[handle].onReboot = onReboot;
|
|
|
|
con->domains[handle].onPoweroff = onPoweroff;
|
|
|
|
con->domains[handle].onCrash = onCrash;
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
if (name)
|
|
|
|
free(name);
|
|
|
|
return (-1);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int testLoadDomainFromDoc(virConnectPtr conn,
|
2007-01-18 21:08:21 +00:00
|
|
|
int domid,
|
|
|
|
const char *doc) {
|
|
|
|
int ret;
|
|
|
|
xmlDocPtr xml;
|
|
|
|
if (!(xml = xmlReadDoc(BAD_CAST doc, "domain.xml", NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = testLoadDomain(conn, domid, xml);
|
|
|
|
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
|
|
|
|
return (ret);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int testLoadDomainFromFile(virConnectPtr conn,
|
2007-01-18 21:08:21 +00:00
|
|
|
int domid,
|
|
|
|
const char *file) {
|
|
|
|
int ret, fd;
|
|
|
|
xmlDocPtr xml;
|
|
|
|
|
|
|
|
if ((fd = open(file, O_RDONLY)) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("load domain definition file"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(xml = xmlReadFd(fd, file, NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("domain"));
|
|
|
|
close(fd);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
close(fd);
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
ret = testLoadDomain(conn, domid, xml);
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
xmlFreeDoc(xml);
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
return (ret);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int testOpenDefault(virConnectPtr conn,
|
2007-01-18 21:08:21 +00:00
|
|
|
int connid) {
|
|
|
|
int u;
|
|
|
|
struct timeval tv;
|
|
|
|
|
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
conn->handle = connid;
|
|
|
|
node->connections[connid].active = 1;
|
|
|
|
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
|
|
|
|
|
|
|
|
node->connections[connid].numDomains = 1;
|
|
|
|
node->connections[connid].domains[0].active = 1;
|
2007-01-22 16:25:27 +00:00
|
|
|
node->connections[connid].domains[0].id = nextDomID++;
|
2007-01-18 21:08:21 +00:00
|
|
|
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");
|
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 14:39:45 +00:00
|
|
|
for (u = 0 ; u < VIR_UUID_BUFLEN ; u++) {
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static char *testBuildFilename(const char *relativeTo,
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int testOpenFromFile(virConnectPtr conn,
|
2007-01-18 21:08:21 +00:00
|
|
|
int connid,
|
|
|
|
const char *file) {
|
|
|
|
int fd, i;
|
|
|
|
xmlDocPtr xml;
|
|
|
|
xmlNodePtr root = NULL;
|
|
|
|
xmlXPathContextPtr ctxt = NULL;
|
|
|
|
xmlXPathObjectPtr obj = NULL;
|
|
|
|
virNodeInfoPtr nodeInfo;
|
|
|
|
|
|
|
|
if ((fd = open(file, O_RDONLY)) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
|
|
|
|
return (-1);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (!(xml = xmlReadFd(fd, file, NULL,
|
|
|
|
XML_PARSE_NOENT | XML_PARSE_NONET |
|
|
|
|
XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("host"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
close(fd);
|
|
|
|
fd = -1;
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
root = xmlDocGetRootElement(xml);
|
|
|
|
if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "node"))) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
ctxt = xmlXPathNewContext(xml);
|
|
|
|
if (ctxt == NULL) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("creating xpath context"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
conn->handle = connid;
|
|
|
|
node->connections[connid].active = 1;
|
|
|
|
node->connections[connid].numDomains = 0;
|
|
|
|
memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
|
|
|
|
|
|
|
|
nodeInfo = &node->connections[connid].nodeInfo;
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/nodes[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->nodes = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu numa nodes"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/sockets[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->sockets = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu sockets"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/cores[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->cores = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu cores"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/threads[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->threads = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu threads"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
}
|
|
|
|
nodeInfo->cpus = nodeInfo->cores * nodeInfo->threads * nodeInfo->sockets * nodeInfo->nodes;
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/active[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
unsigned int active = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node active cpu"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (active < nodeInfo->cpus) {
|
|
|
|
nodeInfo->cpus = active;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
}
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/mhz[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->mhz = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node cpu mhz"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
}
|
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/cpu/model[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
strncpy(nodeInfo->model, (const char *)obj->stringval, sizeof(nodeInfo->model)-1);
|
|
|
|
nodeInfo->model[sizeof(nodeInfo->model)-1] = '\0';
|
|
|
|
xmlXPathFreeObject(obj);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "string(/node/memory[1])", ctxt);
|
|
|
|
if ((obj != NULL) && (obj->type == XPATH_STRING) &&
|
|
|
|
(obj->stringval != NULL) && (obj->stringval[0] != 0)) {
|
|
|
|
char *conv = NULL;
|
|
|
|
nodeInfo->memory = strtol((const char*)obj->stringval, &conv, 10);
|
|
|
|
if (conv == (const char*)obj->stringval) {
|
|
|
|
testError(conn, NULL, VIR_ERR_XML_ERROR, _("node memory"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
obj = xmlXPathEval(BAD_CAST "/node/domain", ctxt);
|
|
|
|
if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
|
|
|
|
(obj->nodesetval == NULL)) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_XML_ERROR, _("node domain list"));
|
|
|
|
goto error;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
for (i = 0 ; i < obj->nodesetval->nodeNr ; i++) {
|
|
|
|
xmlChar *domFile = xmlGetProp(obj->nodesetval->nodeTab[i], BAD_CAST "file");
|
|
|
|
char *absFile = testBuildFilename(file, (const char *)domFile);
|
|
|
|
int domid = nextDomID++;
|
|
|
|
free(domFile);
|
|
|
|
if (!absFile) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("resolving domain filename"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
if (testLoadDomainFromFile(conn, domid, absFile) != 0) {
|
|
|
|
free(absFile);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
free(absFile);
|
|
|
|
node->connections[connid].numDomains++;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
xmlFreeDoc(xml);
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
return (0);
|
2006-08-16 16:36:39 +00:00
|
|
|
|
|
|
|
error:
|
2007-01-18 21:08:21 +00:00
|
|
|
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;
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
if (obj)
|
|
|
|
xmlXPathFreeObject(obj);
|
|
|
|
if (xml)
|
|
|
|
xmlFreeDoc(xml);
|
|
|
|
if (fd != -1)
|
|
|
|
close(fd);
|
|
|
|
return (-1);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int getNextConnection(void) {
|
2007-01-18 21:08:21 +00:00
|
|
|
int i;
|
|
|
|
if (node == NULL) {
|
|
|
|
node = calloc(1, sizeof(testNode));
|
|
|
|
nextDomID = 1;
|
|
|
|
if (!node) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating node"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0 ; i < MAX_CONNECTIONS ; i++) {
|
|
|
|
if (!node->connections[i].active) {
|
|
|
|
return (i);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
static int getDomainIndex(virDomainPtr domain) {
|
|
|
|
int i;
|
|
|
|
testCon *con;
|
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
2007-01-22 16:25:27 +00:00
|
|
|
if (domain->id >= 0) {
|
|
|
|
if (domain->id == con->domains[i].id)
|
2007-01-18 21:08:21 +00:00
|
|
|
return (i);
|
|
|
|
} else {
|
|
|
|
if (!strcmp(domain->name, con->domains[i].name))
|
|
|
|
return (i);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
return (-1);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
|
|
|
|
int testOpen(virConnectPtr conn,
|
|
|
|
const char *name,
|
|
|
|
int flags)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
xmlURIPtr uri;
|
|
|
|
int ret, connid;
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (!name) {
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
uri = xmlParseURI(name);
|
|
|
|
if (uri == NULL) {
|
|
|
|
if (!(flags & VIR_DRV_OPEN_QUIET))
|
|
|
|
testError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
|
|
|
|
return(-1);
|
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (!uri->scheme ||
|
|
|
|
strcmp(uri->scheme, "test") ||
|
|
|
|
!uri->path) {
|
|
|
|
xmlFreeURI(uri);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testClose(virConnectPtr conn)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
con->active = 0;
|
|
|
|
conn->handle = -1;
|
|
|
|
memset(con, 0, sizeof(testCon));
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-08-08 22:22:55 +00:00
|
|
|
int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
|
2006-06-06 03:32:51 +00:00
|
|
|
unsigned long *hvVer)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
*hvVer = 2;
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
int testNodeGetInfo(virConnectPtr conn,
|
2006-06-06 03:32:51 +00:00
|
|
|
virNodeInfoPtr info)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2007-03-15 17:24:56 +00:00
|
|
|
char *
|
|
|
|
testGetCapabilities (virConnectPtr conn)
|
|
|
|
{
|
|
|
|
static char caps[] = "\
|
|
|
|
<capabilities>\n\
|
|
|
|
<host>\n\
|
|
|
|
<cpu>\n\
|
|
|
|
<arch>" TEST_MODEL "</arch>\n\
|
|
|
|
<features>\n\
|
|
|
|
<pae/>\n\
|
|
|
|
<nonpae/>\n\
|
|
|
|
</features>\n\
|
|
|
|
</cpu>\n\
|
|
|
|
</host>\n\
|
|
|
|
\n\
|
|
|
|
<guest>\n\
|
|
|
|
<os_type>linux</os_type>\n\
|
|
|
|
<arch name=\"" TEST_MODEL "\">\n\
|
|
|
|
<wordsize>" TEST_MODEL_WORDSIZE "</wordsize>\n\
|
|
|
|
<domain type=\"test\"/>\n\
|
|
|
|
</arch>\n\
|
|
|
|
<features>\n\
|
|
|
|
<pae/>\n\
|
|
|
|
<nonpae/>\n\
|
|
|
|
</features>\n\
|
|
|
|
</guest>\n\
|
|
|
|
</capabilities>\n\
|
|
|
|
";
|
|
|
|
|
|
|
|
char *caps_copy = strdup (caps);
|
|
|
|
if (!caps_copy) {
|
|
|
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return caps_copy;
|
|
|
|
}
|
|
|
|
|
2006-06-06 03:32:51 +00:00
|
|
|
int testNumOfDomains(virConnectPtr conn)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
int numActive = 0, i;
|
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
|
|
|
if (!con->domains[i].active ||
|
|
|
|
con->domains[i].info.state == VIR_DOMAIN_SHUTOFF)
|
|
|
|
continue;
|
|
|
|
numActive++;
|
|
|
|
}
|
|
|
|
return (numActive);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
virDomainPtr
|
|
|
|
testDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
|
2007-01-18 21:08:21 +00:00
|
|
|
unsigned int flags ATTRIBUTE_UNUSED)
|
2006-08-16 16:36:39 +00:00
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domid, handle = -1, i;
|
|
|
|
virDomainPtr dom;
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (!VIR_IS_CONNECT(conn)) {
|
|
|
|
testError(conn, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
if (xmlDesc == NULL) {
|
|
|
|
testError(conn, NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
if (conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(conn, NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (NULL);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
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++) {
|
2007-01-22 16:25:27 +00:00
|
|
|
if (con->domains[i].id == domid) {
|
2007-01-18 21:08:21 +00:00
|
|
|
handle = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dom = virGetDomain(conn, con->domains[handle].name, con->domains[handle].uuid);
|
|
|
|
if (dom == NULL) {
|
|
|
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
con->numDomains++;
|
|
|
|
return (dom);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-06-06 03:32:51 +00:00
|
|
|
virDomainPtr testLookupDomainByID(virConnectPtr conn,
|
|
|
|
int id)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
virDomainPtr dom;
|
|
|
|
int i, idx = -1;
|
|
|
|
|
|
|
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
|
|
|
if (con->domains[i].active &&
|
2007-01-22 16:25:27 +00:00
|
|
|
con->domains[i].id == id) {
|
2007-01-18 21:08:21 +00:00
|
|
|
idx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx < 0) {
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
dom = virGetDomain(conn, con->domains[idx].name, con->domains[idx].uuid);
|
|
|
|
if (dom == NULL) {
|
|
|
|
testError(conn, NULL, VIR_ERR_NO_MEMORY, _("allocating domain"));
|
|
|
|
return(NULL);
|
|
|
|
}
|
2007-01-22 16:25:27 +00:00
|
|
|
dom->id = id;
|
2007-01-18 21:08:21 +00:00
|
|
|
return (dom);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
|
|
|
|
const unsigned char *uuid)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
int i, idx = -1;
|
|
|
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
|
|
|
if (con->domains[i].active &&
|
Mon Jan 23 14:36:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add VIR_UUID_BUFLEN and
VIR_UUID_STRING_BUFLEN
* libvirt/proxy/libvirt_proxy.c, libvirt/src/hash.c,
libvirt/src/internal.h, libvirt/src/libvirt.c,
libvirt/src/proxy_internal.c, libvirt/src/test.c,
libvirt/src/virsh.c, libvirt/src/xend_internal.c,
libvirt/src/xm_internal.c, libvirt/src/xml.c,
libvirt/python/libvir.c: use them
2007-01-23 14:39:45 +00:00
|
|
|
memcmp(uuid, con->domains[i].uuid, VIR_UUID_BUFLEN) == 0) {
|
2007-01-18 21:08:21 +00:00
|
|
|
idx = i;
|
|
|
|
break;
|
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
2007-01-22 16:25:27 +00:00
|
|
|
dom->id = con->domains[idx].id;
|
2007-01-18 21:08:21 +00:00
|
|
|
}
|
|
|
|
return (dom);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virDomainPtr testLookupDomainByName(virConnectPtr conn,
|
|
|
|
const char *name)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
int i, idx = -1;
|
|
|
|
for (i = 0 ; i < MAX_DOMAINS ; i++) {
|
|
|
|
if (con->domains[i].active &&
|
|
|
|
strcmp(name, con->domains[i].name) == 0) {
|
|
|
|
idx = i;
|
|
|
|
break;
|
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
2007-01-22 16:25:27 +00:00
|
|
|
dom->id = con->domains[idx].id;
|
2007-01-18 21:08:21 +00:00
|
|
|
}
|
|
|
|
return (dom);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testListDomains (virConnectPtr conn,
|
|
|
|
int *ids,
|
|
|
|
int maxids)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con = &node->connections[conn->handle];
|
|
|
|
int n, i;
|
|
|
|
|
|
|
|
for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
|
|
|
|
if (con->domains[i].active &&
|
|
|
|
con->domains[i].info.state != VIR_DOMAIN_SHUTOFF) {
|
2007-01-22 16:25:27 +00:00
|
|
|
ids[n++] = con->domains[i].id;
|
2007-01-18 21:08:21 +00:00
|
|
|
}
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
return (n);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testDestroyDomain (virDomainPtr domain)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
con->domains[domidx].active = 0;
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testResumeDomain (virDomainPtr domain)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testPauseDomain (virDomainPtr domain)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;\
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_PAUSED;
|
|
|
|
return (0);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2006-06-14 23:58:34 +00:00
|
|
|
/* We don't do an immediate shutdown. We basically pretend that
|
|
|
|
out shutdown sequence takes 'n' seconds to complete. SO, here
|
|
|
|
we just set state to shutdown, and subsquent calls to getDomainInfo
|
|
|
|
will check to see if shutdown ought to be marked complete. */
|
|
|
|
int testShutdownDomain (virDomainPtr domain)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
struct timeval tv;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-06-14 23:58:34 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
|
2007-01-22 16:25:27 +00:00
|
|
|
domain->id = -1;
|
|
|
|
con->domains[domidx].id = -1;
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
return (0);
|
2006-06-14 23:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Similar behaviour as shutdown */
|
|
|
|
int testRebootDomain (virDomainPtr domain, virDomainRestart action)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
struct timeval tv;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!action)
|
|
|
|
action = VIR_DOMAIN_RESTART;
|
|
|
|
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_SHUTDOWN;
|
|
|
|
switch (action) {
|
|
|
|
case VIR_DOMAIN_DESTROY:
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_RESTART:
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_PRESERVE:
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_RENAME_RESTART:
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
|
|
|
|
break;
|
2006-06-14 23:58:34 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
default:
|
|
|
|
con->domains[domidx].info.state = VIR_DOMAIN_SHUTOFF;
|
|
|
|
break;
|
|
|
|
}
|
2007-01-22 16:25:27 +00:00
|
|
|
domain->id = -1;
|
|
|
|
con->domains[domidx].id = -1;
|
2006-06-14 23:58:34 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
return (0);
|
2006-06-14 23:58:34 +00:00
|
|
|
}
|
|
|
|
|
2006-06-06 03:32:51 +00:00
|
|
|
int testGetDomainInfo (virDomainPtr domain,
|
|
|
|
virDomainInfoPtr info)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
struct timeval tv;
|
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
|
|
|
|
if (gettimeofday(&tv, NULL) < 0) {
|
|
|
|
testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (con->domains[domidx].info.state == VIR_DOMAIN_SHUTOFF) {
|
|
|
|
con->domains[domidx].info.cpuTime = 0;
|
|
|
|
con->domains[domidx].info.memory = 0;
|
|
|
|
} else {
|
|
|
|
con->domains[domidx].info.cpuTime = ((tv.tv_sec * 1000ll * 1000ll * 1000ll) + (tv.tv_usec * 1000ll));
|
|
|
|
}
|
|
|
|
memcpy(info, &con->domains[domidx].info, sizeof(virDomainInfo));
|
|
|
|
return (0);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2006-11-08 18:54:57 +00:00
|
|
|
char *testGetOSType(virDomainPtr dom ATTRIBUTE_UNUSED) {
|
2007-01-18 21:08:21 +00:00
|
|
|
return strdup("linux");
|
2006-11-08 18:54:57 +00:00
|
|
|
}
|
|
|
|
|
2006-08-16 16:36:39 +00:00
|
|
|
unsigned long testGetMaxMemory(virDomainPtr domain) {
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
return con->domains[domidx].info.maxMem;
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
int testSetMaxMemory(virDomainPtr domain,
|
|
|
|
unsigned long memory)
|
2006-06-06 03:32:51 +00:00
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
/* XXX validate not over host memory wrt to other domains */
|
|
|
|
con->domains[domidx].info.maxMem = memory;
|
|
|
|
return (0);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
int testSetMemory(virDomainPtr domain,
|
|
|
|
unsigned long memory)
|
2006-08-16 16:36:39 +00:00
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
if (memory > con->domains[domidx].info.maxMem) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con->domains[domidx].info.memory = memory;
|
|
|
|
return (0);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int testSetVcpus(virDomainPtr domain,
|
2007-01-18 21:08:21 +00:00
|
|
|
unsigned int nrCpus) {
|
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con = &node->connections[domain->conn->handle];
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
/* We allow more cpus in guest than host */
|
|
|
|
if (nrCpus > 32) {
|
|
|
|
testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
|
|
|
|
return (-1);
|
|
|
|
}
|
2006-08-16 16:36:39 +00:00
|
|
|
|
2007-01-18 21:08:21 +00:00
|
|
|
con->domains[domidx].info.nrVirtCpu = nrCpus;
|
|
|
|
return (0);
|
2006-08-16 16:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
char * testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
|
|
|
|
{
|
2007-01-18 21:08:21 +00:00
|
|
|
virBufferPtr buf;
|
|
|
|
char *xml;
|
|
|
|
unsigned char *uuid;
|
|
|
|
testCon *con;
|
|
|
|
int domidx;
|
|
|
|
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
|
|
|
|
((domidx = getDomainIndex(domain)) < 0)) {
|
|
|
|
testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
|
|
|
|
__FUNCTION__);
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
con = &node->connections[domain->conn->handle];
|
|
|
|
|
|
|
|
if (!(buf = virBufferNew(4000))) {
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
virBufferVSprintf(buf, "<domain type='test' id='%d'>\n", domain->id);
|
2007-01-18 21:08:21 +00:00
|
|
|
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]);
|
|
|
|
|
2007-03-16 15:03:21 +00:00
|
|
|
virBufferVSprintf(buf, " <memory>%lu</memory>\n", con->domains[domidx].info.maxMem);
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
2006-06-06 03:32:51 +00:00
|
|
|
}
|
2007-01-18 21:08:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
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,
|
2007-03-06 21:55:44 +00:00
|
|
|
char **const names,
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
domain->id = con->domains[domidx].id = nextDomID++;
|
2007-01-18 21:08:21 +00:00
|
|
|
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);
|
|
|
|
}
|
2007-03-15 07:43:16 +00:00
|
|
|
#endif /* WITH_TEST */
|
2007-01-18 21:08:21 +00:00
|
|
|
|
2007-03-15 17:24:56 +00:00
|
|
|
/*
|
|
|
|
* vim: set tabstop=4:
|
|
|
|
* vim: set shiftwidth=4:
|
|
|
|
* vim: set expandtab:
|
|
|
|
*/
|
2007-01-18 21:08:21 +00:00
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* indent-tabs-mode: nil
|
|
|
|
* c-indent-level: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* tab-width: 4
|
|
|
|
* End:
|
|
|
|
*/
|