Re-wrote xenDomainLookupByID to use more efficient XenD access

This commit is contained in:
Daniel P. Berrange 2006-07-07 18:58:35 +00:00
parent 4d56d3c638
commit 3ffac4a188
4 changed files with 89 additions and 50 deletions

View File

@ -1,3 +1,11 @@
Fri Jul 7 09:47:14 EDT 2006 Daniel Berrange <berrange@redhat.com>
* src/xend_internal.c: changed xenDaemonLookupByID to simply do
an sexpr GET on /xend/domain/[ID] instead of listing all names
and iterating over /xend/domain/[NAME]. Reduces the running time
and number of GETs from O(n^2) to O(n).
* src/xend_internal.c: fixed xenDaemonOpen() to try both unix and
Wed Jul 5 17:11:32 IST 2006 Mark McLoughlin <markmc@redhat.com> Wed Jul 5 17:11:32 IST 2006 Mark McLoughlin <markmc@redhat.com>
* xml.c: allow a <domain> to not have any <disk> devices - e.g. * xml.c: allow a <domain> to not have any <disk> devices - e.g.

View File

@ -454,33 +454,14 @@ retry2:
} }
break; break;
case VIR_PROXY_LOOKUP_ID: { case VIR_PROXY_LOOKUP_ID: {
char **names;
char **tmp;
int ident, len;
char *name = NULL; char *name = NULL;
unsigned char uuid[16]; unsigned char uuid[16];
int len;
if (req->len != sizeof(virProxyPacket)) if (req->len != sizeof(virProxyPacket))
goto comm_error; goto comm_error;
/* if (xenDaemonDomainLookupByID(conn, req->data.arg, &name, uuid) < 0) {
* Xend API forces to collect the full domain list by names, and
* then query each of them until the id is found
*/
names = xenDaemonListDomainsOld(conn);
tmp = names;
if (names != NULL) {
while (*tmp != NULL) {
ident = xenDaemonDomainLookupByName_ids(conn, *tmp, &uuid[0]);
if (ident == req->data.arg) {
name = *tmp;
break;
}
tmp++;
}
}
if (name == NULL) {
req->data.arg = -1; req->data.arg = -1;
} else { } else {
len = strlen(name); len = strlen(name);
@ -492,7 +473,8 @@ retry2:
memcpy(&request.extra.str[0], uuid, 16); memcpy(&request.extra.str[0], uuid, 16);
strcpy(&request.extra.str[16], name); strcpy(&request.extra.str[16], name);
} }
free(names); if (name)
free(name);
break; break;
} }
case VIR_PROXY_LOOKUP_UUID: { case VIR_PROXY_LOOKUP_UUID: {

View File

@ -1082,7 +1082,7 @@ xenDaemonDomainCreateLinux(virConnectPtr xend, const char *sexpr)
*/ */
int int
xenDaemonDomainLookupByName_ids(virConnectPtr xend, const char *domname, xenDaemonDomainLookupByName_ids(virConnectPtr xend, const char *domname,
unsigned char *uuid) unsigned char *uuid)
{ {
struct sexpr *root; struct sexpr *root;
const char *value; const char *value;
@ -1119,6 +1119,62 @@ xenDaemonDomainLookupByName_ids(virConnectPtr xend, const char *domname,
return (ret); return (ret);
} }
/**
* xenDaemonDomainLookupByID:
* @xend: A xend instance
* @id: The id of the domain
* @name: return value for the name if not NULL
* @uuid: return value for the UUID if not NULL
*
* This method looks up the name of a domain based on its id
*
* Returns the 0 on success; -1 (with errno) on error
*/
int
xenDaemonDomainLookupByID(virConnectPtr xend,
int id,
char **domname,
unsigned char *uuid)
{
const char *name = NULL;
char *dst_uuid;
struct sexpr *root;
memset(uuid, 0, 16);
root = sexpr_get(xend, "/xend/domain/%d?detail=1", id);
if (root == NULL)
goto error;
name = sexpr_node(root, "domain/name");
if (name == NULL) {
virXendError(xend, VIR_ERR_INTERNAL_ERROR,
"domain informations incomplete, missing name");
goto error;
}
if (domname)
*domname = strdup(name);
dst_uuid = (char *)&uuid[0];
if (sexpr_uuid(&dst_uuid, root, "domain/uuid") == NULL) {
virXendError(xend, VIR_ERR_INTERNAL_ERROR,
"domain informations incomplete, missing uuid");
goto error;
}
sexpr_free(root);
return (0);
error:
sexpr_free(root);
if (domname && *domname) {
free(*domname);
*domname = NULL;
}
return (-1);
}
/** /**
* xend_get_node: * xend_get_node:
* @xend: A xend instance * @xend: A xend instance
@ -2264,33 +2320,13 @@ error:
*/ */
static virDomainPtr static virDomainPtr
xenDaemonLookupByID(virConnectPtr conn, int id) { xenDaemonLookupByID(virConnectPtr conn, int id) {
char **names;
char **tmp;
int ident;
char *name = NULL; char *name = NULL;
unsigned char uuid[16]; unsigned char uuid[16];
virDomainPtr ret; virDomainPtr ret;
/* if (xenDaemonDomainLookupByID(conn, id, &name, uuid) < 0) {
* Xend API forces to collect the full domain list by names, and then
* query each of them until the id is found
*/
names = xenDaemonListDomainsOld(conn);
tmp = names;
if (names != NULL) {
while (*tmp != NULL) {
ident = xenDaemonDomainLookupByName_ids(conn, *tmp, &uuid[0]);
if (ident == id) {
name = strdup(*tmp);
break;
}
tmp++;
}
free(names);
}
if (name == NULL)
goto error; goto error;
}
ret = virGetDomain(conn, name, uuid); ret = virGetDomain(conn, name, uuid);
if (ret == NULL) { if (ret == NULL) {
@ -2298,13 +2334,12 @@ xenDaemonLookupByID(virConnectPtr conn, int id) {
goto error; goto error;
} }
ret->handle = id; ret->handle = id;
if (name != NULL) free(name);
free(name);
return (ret); return (ret);
error: error:
if (name != NULL) if (name != NULL)
free(name); free(name);
return (NULL); return (NULL);
} }

View File

@ -534,6 +534,20 @@ int xenDaemonDomainLookupByName_ids(virConnectPtr xend,
const char *name, unsigned char *uuid); const char *name, unsigned char *uuid);
/**
* \brief Lookup the name of a domain
* \param xend A xend instance
* \param id The id of the domain
* \param name pointer to store a copy of the name
* \param uuid pointer to store a copy of the uuid
*
* This method looks up the name/uuid of a domain
*/
int xenDaemonDomainLookupByID(virConnectPtr xend,
int id,
char **name, unsigned char *uuid);
/** /**
* \brief Lookup information about the host machine * \brief Lookup information about the host machine
* \param xend A xend instance * \param xend A xend instance