Disk devices can be referenced by name in Xen, e.g. when modifying
their configuration or remvoving them. As such, don't search
xenstore for a device ID corresponding to the disk device. Instead,
search the disks contained in the domain definition and use the
disk's target name if found.
This approach allows removing a disk when domain is inactive. We
obviously can't search xenstore when the domain is inactive.
---
src/xen/xend_internal.c | 38 +++++++++++++++++++++++---------------
1 files changed, 23 insertions(+), 15 deletions(-)
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 9d95291..d0d32e2 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -93,6 +93,7 @@ xenDaemonFormatSxprOnePCI(virConnectPtr conn,
static int
virDomainXMLDevID(virDomainPtr domain,
+ virDomainDefPtr domDef,
virDomainDeviceDefPtr dev,
char *class,
char *ref,
@@ -4212,7 +4213,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml,
sexpr = virBufferContentAndReset(&buf);
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref))) {
+ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref))) {
/* device doesn't exist, define it */
ret = xend_op(domain->conn, domain->name, "op",
"device_create",
"config", sexpr, NULL);
@@ -4306,7 +4307,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml,
def, xml, VIR_DOMAIN_XML_INACTIVE)))
goto cleanup;
- if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref)))
+ if (virDomainXMLDevID(domain, def, dev, class, ref, sizeof(ref)))
goto cleanup;
if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
@@ -6048,6 +6049,7 @@ error:
*/
static int
virDomainXMLDevID(virDomainPtr domain,
+ virDomainDefPtr domDef,
virDomainDeviceDefPtr dev,
char *class,
char *ref,
@@ -6056,27 +6058,33 @@ virDomainXMLDevID(virDomainPtr domain,
xenUnifiedPrivatePtr priv = domain->conn->privateData;
char *xref;
char *tmp;
+ unsigned int i;
+ virDomainDiskDefPtr disk;
if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+ if (dev->data.disk->dst == NULL)
+ return -1;
if (dev->data.disk->driverName &&
STREQ(dev->data.disk->driverName, "tap"))
strcpy(class, "tap");
else
strcpy(class, "vbd");
- if (dev->data.disk->dst == NULL)
- return -1;
- xenUnifiedLock(priv);
- xref = xenStoreDomainGetDiskID(domain->conn, domain->id,
- dev->data.disk->dst);
- xenUnifiedUnlock(priv);
- if (xref == NULL)
- return -1;
-
- tmp = virStrcpy(ref, xref, ref_len);
- VIR_FREE(xref);
- if (tmp == NULL)
- return -1;
+ /* For disks, the device name can be used directly.
+ * If disk device exists in domain definintion,
+ * copy it to ref and return success.
+ */
+ for (i = 0; i < domDef->ndisks; i++) {
+ disk = domDef->disks[i];
+ if (STREQ(dev->data.disk->dst, disk->dst)) {
+ tmp = virStrcpy(ref, disk->dst, ref_len);
+ if (tmp == NULL)
+ return -1;
+ else
+ return 0;
+ }
+ }
+ return -1;
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
char mac[30];
virDomainNetDefPtr def =
dev->data.net;
--
1.6.0.2