diff --git a/ChangeLog b/ChangeLog index f79981c1e3..785a309266 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Tue Nov 6 12:42:55 CET 2007 Daniel Veillard + + * src/xml.c src/xs_internal.c src/xs_internal.h: applied patch + from Masayuki Sunou to fix xend errors when adding disk + devices, due to improper device id lookup. + Tue Nov 6 10:40:13 CET 2007 Daniel Veillard * src/virsh.c: patch from Masayuki Sunou to fix parameter diff --git a/src/xml.c b/src/xml.c index f2c0ff027c..1866ec27a1 100644 --- a/src/xml.c +++ b/src/xml.c @@ -1922,9 +1922,22 @@ virDomainXMLDevID(virDomainPtr domain, const char *xmldesc, char *class, attr = xmlGetProp(cur, BAD_CAST "dev"); if (attr == NULL) goto error; - strncpy(ref, (char *) attr, ref_len); - ref[ref_len - 1] = '\0'; - goto cleanup; +#ifdef WITH_XEN + xref = xenStoreDomainGetDiskID(domain->conn, domain->id, + (char *) attr); + if (xref != NULL) { + strncpy(ref, xref, ref_len); + free(xref); + ref[ref_len - 1] = '\0'; + goto cleanup; + } +#else /* !WITH_XEN */ + /* hack to avoid the warning that domain is unused */ + if (domain->id < 0) + ret = -1; +#endif /* !WITH_XEN */ + + goto error; } } else if (xmlStrEqual(node->name, BAD_CAST "interface")) { strcpy(class, "vif"); @@ -1945,11 +1958,11 @@ virDomainXMLDevID(virDomainPtr domain, const char *xmldesc, char *class, ref[ref_len - 1] = '\0'; goto cleanup; } -#else /* without xen */ +#else /* !WITH_XEN */ /* hack to avoid the warning that domain is unused */ if (domain->id < 0) ret = -1; -#endif /* WITH_XEN */ +#endif /* !WITH_XEN */ goto error; } diff --git a/src/xs_internal.c b/src/xs_internal.c index 31bf4917a8..7381dcdeb3 100644 --- a/src/xs_internal.c +++ b/src/xs_internal.c @@ -879,6 +879,58 @@ xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac) { return(ret); } +/* + * xenStoreDomainGetDiskID: + * @conn: pointer to the connection. + * @id: the domain id + * @dev: the virtual block device name + * + * Get the reference (i.e. the string number) for the device on that domain + * which uses the given virtual block device name + * + * Returns the new string or NULL in case of error, the string must be + * freed by the caller. + */ +char * +xenStoreDomainGetDiskID(virConnectPtr conn, int id, const char *dev) { + char dir[80], path[128], **list = NULL, *val = NULL; + unsigned int devlen, len, i, num; + char *ret = NULL; + xenUnifiedPrivatePtr priv; + + if (id < 0) + return(NULL); + + priv = (xenUnifiedPrivatePtr) conn->privateData; + if (priv->xshandle == NULL) + return (NULL); + if (dev == NULL) + return (NULL); + devlen = strlen(dev); + if (devlen <= 0) + return (NULL); + + snprintf(dir, sizeof(dir), "/local/domain/0/backend/vbd/%d", id); + list = xs_directory(priv->xshandle, 0, dir, &num); + if (list == NULL) + return(NULL); + for (i = 0; i < num; i++) { + snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "dev"); + val = xs_read(priv->xshandle, 0, path, &len); + if (val == NULL) + break; + if ((devlen != len) || memcmp(val, dev, len)) { + free(val); + } else { + ret = strdup(list[i]); + free(val); + break; + } + } + free(list); + return(ret); +} + char *xenStoreDomainGetName(virConnectPtr conn, int id) { char prop[200]; diff --git a/src/xs_internal.h b/src/xs_internal.h index cd2f0ed55e..2ccc6d6963 100644 --- a/src/xs_internal.h +++ b/src/xs_internal.h @@ -50,6 +50,9 @@ char * xenStoreDomainGetOSTypeID(virConnectPtr conn, char * xenStoreDomainGetNetworkID(virConnectPtr conn, int id, const char *mac); +char * xenStoreDomainGetDiskID(virConnectPtr conn, + int id, + const char *mac); char * xenStoreDomainGetName(virConnectPtr conn, int id);