On Thu, Mar 01, 2007 at 06:11:44PM +0900, Tatsuro Enokura wrote: > Hi, Dan > > Daniel P. Berrange wrote: > >> and shut-off domain's information is got from xend. > >> I make a patch for xend_internal.c > >> > >> The attached patch resolve this issue in the following way: > >> > >> 1) If the domain's name can't be pulled out from > >> the running domains list by uuid, request xend by > >> "/xend/domains/<uuid>". > >> 2) If the domain's data can be teken from xend, pull out > >> the domain's name. > > > > It looks like a reasonable patch - I'll do a little testing and if > > it works on Fedora 7 I'll add it to CVS. > > Could you tell me the test result on this patch? > If the test is fine, please commit it. So, in previous XenD you were not able to request a domain based on UUID, eg GET /xen/domain/3ef946bb4d5033a8cdba29f405de11ea was not a valid URL served by XenD. So we basically did a get on /xen/domain/ to build a list of names, and then iterate over them, fetching each one in turn until we found the one we wanted. This is obviously horribly slow, but the only option we had on Xen < 3.0.4 Now, that XenD does allow lookups based on UUID, I am changing your patch so that it *always* does the lookup based on UUID, so that we avoid the slow path completely on Xen >= 3.0.4 I propose to apply the attached patch version - anyone else with comments ? Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
Index: xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.95 diff -u -p -r1.95 xend_internal.c --- xend_internal.c 27 Feb 2007 15:50:03 -0000 1.95 +++ xend_internal.c 1 Mar 2007 18:05:56 -0000 @@ -1331,7 +1331,16 @@ xend_parse_sexp_desc(virConnectPtr conn, buf.size = 4000; buf.use = 0; - domid = sexpr_int(root, "domain/domid"); + tmp = sexpr_node(root, "domain/domid"); + if (tmp == NULL && xendConfigVersion < 3) { /* Old XenD, domid was mandatory */ + virXendError(conn, VIR_ERR_INTERNAL_ERROR, + _("domain information incomplete, missing id")); + goto error; + } + if (tmp) + domid = sexpr_int(root, "domain/domid"); + else + domid = -1; virBufferVSprintf(&buf, "<domain type='xen' id='%d'>\n", domid); tmp = sexpr_node(root, "domain/name"); @@ -2767,47 +2776,67 @@ xenDaemonLookupByUUID(virConnectPtr conn { virDomainPtr ret; char *name = NULL; - char **names; - char **tmp; - unsigned char ident[VIR_UUID_BUFLEN]; int id = -1; + printf("Try lllookup uuid\n"); + /* Old approach for xen <= 3.0.3 */ + if (conn->xendConfigVersion < 3) { + char **names, **tmp; + unsigned char ident[VIR_UUID_BUFLEN]; + names = xenDaemonListDomainsOld(conn); + tmp = names; - names = xenDaemonListDomainsOld(conn); - tmp = names; - - if (names == NULL) { - TODO /* try to fallback to xenstore lookup */ + if (names == NULL) { return (NULL); - } - while (*tmp != NULL) { - id = xenDaemonDomainLookupByName_ids(conn, *tmp, &ident[0]); - if (id >= 0) { - if (!memcmp(uuid, ident, VIR_UUID_BUFLEN)) { - name = strdup(*tmp); - break; + } + while (*tmp != NULL) { + id = xenDaemonDomainLookupByName_ids(conn, *tmp, &ident[0]); + if (id >= 0) { + if (!memcmp(uuid, ident, VIR_UUID_BUFLEN)) { + name = strdup(*tmp); + break; + } } + tmp++; } - tmp++; + free(names); + } else { /* New approach for xen >= 3.0.4 */ + char *domname = NULL; + char uuidstr[VIR_UUID_STRING_BUFLEN]; + struct sexpr *root = NULL; + + memset(uuidstr, '\0', VIR_UUID_STRING_BUFLEN); + + snprintf(uuidstr, VIR_UUID_STRING_BUFLEN, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + 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]); + printf("Dpooing %s\n", uuidstr); + root = sexpr_get(conn, "/xend/domain/%s?detail=1", uuidstr); + if (root == NULL) + return (NULL); + domname = (char*)sexpr_node(root, "domain/name"); + if (sexpr_node(root, "domain/domid")) /* only active domains have domid */ + id = sexpr_int(root, "domain/domid"); + else + id = -1; + name = domname ? strdup(domname) : NULL; + sexpr_free(root); } - free(names); if (name == NULL) - goto error; + return (NULL); ret = virGetDomain(conn, name, uuid); if (ret == NULL) { - virXendError(conn, VIR_ERR_NO_MEMORY, _("allocating domain")); - goto error; + virXendError(conn, VIR_ERR_NO_MEMORY, _("allocating domain")); + free(name); + return (NULL); } ret->id = id; - if (name != NULL) - free(name); + free(name); return (ret); - -error: - if (name != NULL) - free(name); - return (NULL); } /**