* src/hash.c src/internal.h: add virGetDomainByID() to speed up

some processing but not used yet
* src/libvirt.c src/xen_internal.c src/xen_internal.h: added domain
  listing and number queries entry points based on the hypervisor
  which should speed up some processing as root.
Daniel
This commit is contained in:
Daniel Veillard 2006-04-24 18:21:29 +00:00
parent b68bd23d9b
commit 91b0ae89dd
6 changed files with 226 additions and 10 deletions

View File

@ -1,3 +1,11 @@
Mon Apr 24 18:23:29 EDT 2006 Daniel Veillard <veillard@redhat.com>
* src/hash.c src/internal.h: add virGetDomainByID() to speed up
some processing but not used yet
* src/libvirt.c src/xen_internal.c src/xen_internal.h: added domain
listing and number queries entry points based on the hypervisor
which should speed up some processing as root.
Thu Apr 20 14:31:13 EDT 2006 Daniel Veillard <veillard@redhat.com> Thu Apr 20 14:31:13 EDT 2006 Daniel Veillard <veillard@redhat.com>
* src/xend_internal.c: fix an uninitialized memory access in error * src/xend_internal.c: fix an uninitialized memory access in error

View File

@ -723,3 +723,47 @@ done:
return(ret); return(ret);
} }
/**
* virGetDomainByID:
* @conn: the hypervisor connection
* @id: the ID number for the domain
*
* Lookup if the domain ID is already registered for that connection,
* if yes return a new pointer to it, if no return NULL
*
* Returns a pointer to the domain, or NULL if not found
*/
virDomainPtr
virGetDomainByID(virConnectPtr conn, int id) {
virDomainPtr ret = NULL, cur;
virHashEntryPtr iter, next;
virHashTablePtr table;
int key;
if ((!VIR_IS_CONNECT(conn)) || (id < 0)) {
virHashError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
xmlMutexLock(conn->domains_mux);
table = conn->domains;
if ((table == NULL) || (table->nbElems == 0))
goto done;
for (key = 0;key < table->size;key++) {
if (table->table[key].valid == 0)
continue;
iter = &(table->table[key]);
while (iter != NULL) {
next = iter->next;
cur = (virDomainPtr) iter->payload;
if ((cur != NULL) && (cur->handle == id)) {
ret = cur;
goto done;
}
iter = next;
}
}
done:
xmlMutexUnlock(conn->domains_mux);
return(ret);
}

View File

@ -172,7 +172,7 @@ const char *__virErrorMsg(virErrorNumber error, const char *info);
/************************************************************************ /************************************************************************
* * * *
* API for domain/connections (de)allocations * * API for domain/connections (de)allocations and lookups *
* * * *
************************************************************************/ ************************************************************************/
@ -183,6 +183,8 @@ virDomainPtr virGetDomain (virConnectPtr conn,
const char *uuid); const char *uuid);
int virFreeDomain (virConnectPtr conn, int virFreeDomain (virConnectPtr conn,
virDomainPtr domain); virDomainPtr domain);
virDomainPtr virGetDomainByID(virConnectPtr conn,
int id);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -407,7 +407,7 @@ int
virConnectListDomains(virConnectPtr conn, int *ids, int maxids) virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
{ {
int ret = -1; int ret = -1;
unsigned int i; int i;
long id; long id;
char **idlist = NULL; char **idlist = NULL;
@ -421,8 +421,18 @@ virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
return (-1); return (-1);
} }
/* Go though the driver registered entry points */
for (i = 0;i < conn->nb_drivers;i++) {
if ((conn->drivers[i] != NULL) &&
(conn->drivers[i]->listDomains != NULL)) {
ret = conn->drivers[i]->listDomains(conn, ids, maxids);
if (ret >= 0)
return(ret);
}
}
/* /*
* try first though the Xen Daemon * try then though the Xen Daemon
*/ */
idlist = xenDaemonListDomains(conn); idlist = xenDaemonListDomains(conn);
if (idlist != NULL) { if (idlist != NULL) {
@ -454,6 +464,7 @@ int
virConnectNumOfDomains(virConnectPtr conn) virConnectNumOfDomains(virConnectPtr conn)
{ {
int ret = -1; int ret = -1;
int i;
char **idlist = NULL; char **idlist = NULL;
if (!VIR_IS_CONNECT(conn)) { if (!VIR_IS_CONNECT(conn)) {
@ -461,9 +472,18 @@ virConnectNumOfDomains(virConnectPtr conn)
return (-1); return (-1);
} }
/* TODO: there must be a way to do that with an hypervisor call too ! */ /* Go though the driver registered entry points */
for (i = 0;i < conn->nb_drivers;i++) {
if ((conn->drivers[i] != NULL) &&
(conn->drivers[i]->numOfDomains != NULL)) {
ret = conn->drivers[i]->numOfDomains(conn);
if (ret >= 0)
return(ret);
}
}
/* /*
* try first with Xend interface * try then with Xend interface
*/ */
idlist = xenDaemonListDomains(conn); idlist = xenDaemonListDomains(conn);
if (idlist != NULL) { if (idlist != NULL) {

View File

@ -48,8 +48,8 @@ static virDriver xenHypervisorDriver = {
NULL, /* type */ NULL, /* type */
xenHypervisorGetVersion, /* version */ xenHypervisorGetVersion, /* version */
NULL, /* nodeGetInfo */ NULL, /* nodeGetInfo */
NULL, /* listDomains */ xenHypervisorListDomains, /* listDomains */
NULL, /* numOfDomains */ xenHypervisorNumOfDomains, /* numOfDomains */
NULL, /* domainCreateLinux */ NULL, /* domainCreateLinux */
NULL, /* domainLookupByID */ NULL, /* domainLookupByID */
NULL, /* domainLookupByUUID */ NULL, /* domainLookupByUUID */
@ -131,7 +131,7 @@ xenHypervisorOpen(virConnectPtr conn, const char *name, int flags)
} }
conn->handle = ret; conn->handle = ret;
return (ret); return(0);
} }
/** /**
@ -233,6 +233,144 @@ xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
return(0); return(0);
} }
/**
* xenHypervisorNumOfDomains:
* @conn: pointer to the connection block
*
* Provides the number of active domains.
*
* Returns the number of domain found or -1 in case of error
*/
int
xenHypervisorNumOfDomains(virConnectPtr conn)
{
dom0_op_t op;
dom0_getdomaininfo_t *dominfos;
int ret, nbids;
static int last_maxids = 2;
int maxids = last_maxids;
if ((conn == NULL) || (conn->handle < 0))
return (-1);
retry:
dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
if (dominfos == NULL) {
virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
maxids);
return(-1);
}
memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
virXenError(VIR_ERR_XEN_CALL, " locking",
sizeof(dom0_getdomaininfo_t) * maxids);
free(dominfos);
return (-1);
}
op.cmd = DOM0_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = (domid_t) 0;
op.u.getdomaininfolist.max_domains = maxids;
op.u.getdomaininfolist.buffer = dominfos;
op.u.getdomaininfolist.num_domains = maxids;
ret = xenHypervisorDoOp(conn->handle, &op);
if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release",
sizeof(dom0_getdomaininfo_t) * maxids);
ret = -1;
}
free(dominfos);
if (ret < 0)
return (-1);
nbids = op.u.getdomaininfolist.num_domains;
if (nbids == maxids) {
last_maxids *= 2;
maxids *= 2;
goto retry;
}
if ((nbids < 0) || (nbids > maxids))
return(-1);
return(nbids);
}
/**
* xenHypervisorListDomains:
* @conn: pointer to the connection block
* @ids: array to collect the list of IDs of active domains
* @maxids: size of @ids
*
* Collect the list of active domains, and store their ID in @maxids
*
* Returns the number of domain found or -1 in case of error
*/
int
xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
{
dom0_op_t op;
dom0_getdomaininfo_t *dominfos;
int ret, nbids, i;
if ((conn == NULL) || (conn->handle < 0) ||
(ids == NULL) || (maxids < 1))
return (-1);
dominfos = malloc(maxids * sizeof(dom0_getdomaininfo_t));
if (dominfos == NULL) {
virXenError(VIR_ERR_NO_MEMORY, "failed to allocate %d domain info",
maxids);
return(-1);
}
memset(dominfos, 0, sizeof(dom0_getdomaininfo_t) * maxids);
memset(ids, 0, maxids * sizeof(int));
if (mlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
virXenError(VIR_ERR_XEN_CALL, " locking",
sizeof(dom0_getdomaininfo_t) * maxids);
free(dominfos);
return (-1);
}
op.cmd = DOM0_GETDOMAININFOLIST;
op.u.getdomaininfolist.first_domain = (domid_t) 0;
op.u.getdomaininfolist.max_domains = maxids;
op.u.getdomaininfolist.buffer = dominfos;
op.u.getdomaininfolist.num_domains = maxids;
ret = xenHypervisorDoOp(conn->handle, &op);
if (munlock(dominfos, sizeof(dom0_getdomaininfo_t) * maxids) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release",
sizeof(dom0_getdomaininfo_t) * maxids);
ret = -1;
}
if (ret < 0) {
free(dominfos);
return (-1);
}
nbids = op.u.getdomaininfolist.num_domains;
if ((nbids < 0) || (nbids > maxids)) {
free(dominfos);
return(-1);
}
for (i = 0;i < nbids;i++) {
ids[i] = dominfos[i].domain;
}
free(dominfos);
return (nbids);
}
/** /**
* xenHypervisorGetDomainInfo: * xenHypervisorGetDomainInfo:
* @domain: pointer to the domain block * @domain: pointer to the domain block
@ -256,7 +394,7 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
memset(info, 0, sizeof(virDomainInfo)); memset(info, 0, sizeof(virDomainInfo));
memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t)); memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t));
if (mlock(info, sizeof(dom0_getdomaininfo_t)) < 0) { if (mlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
virXenError(VIR_ERR_XEN_CALL, " locking", virXenError(VIR_ERR_XEN_CALL, " locking",
sizeof(dom0_getdomaininfo_t)); sizeof(dom0_getdomaininfo_t));
return (-1); return (-1);
@ -271,7 +409,7 @@ xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
ret = xenHypervisorDoOp(domain->conn->handle, &op); ret = xenHypervisorDoOp(domain->conn->handle, &op);
if (munlock(info, sizeof(dom0_getdomaininfo_t)) < 0) { if (munlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release", virXenError(VIR_ERR_XEN_CALL, " release",
sizeof(dom0_getdomaininfo_t)); sizeof(dom0_getdomaininfo_t));
ret = -1; ret = -1;

View File

@ -25,6 +25,10 @@ int xenHypervisorOpen (virConnectPtr conn,
int xenHypervisorClose (virConnectPtr conn); int xenHypervisorClose (virConnectPtr conn);
int xenHypervisorGetVersion (virConnectPtr conn, int xenHypervisorGetVersion (virConnectPtr conn,
unsigned long *hvVer); unsigned long *hvVer);
int xenHypervisorNumOfDomains (virConnectPtr conn);
int xenHypervisorListDomains (virConnectPtr conn,
int *ids,
int maxids);
int xenHypervisorDestroyDomain (virDomainPtr domain); int xenHypervisorDestroyDomain (virDomainPtr domain);
int xenHypervisorResumeDomain (virDomainPtr domain); int xenHypervisorResumeDomain (virDomainPtr domain);
int xenHypervisorPauseDomain (virDomainPtr domain); int xenHypervisorPauseDomain (virDomainPtr domain);