[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] fix detach-disk for inactive xen domains



detach-disk was not working for inactive xen domains due to lookup of
device ID from xenstore.  When detaching disks there is no need to use
device id as device name can be used directly.  Unfortunately that same
is not true for network devices.  In fact, AFAICT, there is no way to
"hot unplug" a network device from inactive domain using xen tools.

I have tested attaching/detaching disks to/from both active and inactive
domains.  I've also ensured no regressions in attaching/detaching
network devices on active domains and attaching network devices on
inactive domains.  As noted above, detaching network devices from
inactive domains does not work, but I'm not sure what we can do about
that since xen tools themselves don't support this.  Any suggestions are
kindly welcomed.  Oh, and I also ensured all of these scenarios work
with both PV and HVM domains.

Regards,
Jim

commit 769a887434faf76f8e80aa505e3880d4fdbe572e
Author: Jim Fehlig <jfehlig novell com>
Date:   Fri Nov 13 15:34:44 2009 -0700

    Fix detach-disk for inactive xen domains.
    
    Looking in xenstore for device ID of disk won't work for inactive
    xen domains.  Instead, use the device name, e.g. xvda, hda, etc.
    The device name can be used to remove disk device regardless if
    domain is active or inactive.

diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index d61e9e6..b98e83b 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -96,6 +96,14 @@ virDomainXMLDevID(virDomainPtr domain,
                   char *class,
                   char *ref,
                   int ref_len);
+
+static int
+virDomainGetDevInfo(virDomainPtr domain,
+                    virDomainDeviceDefPtr dev,
+                    char *class,
+                    int class_len,
+                    char *ref,
+                    int ref_len);
 #endif
 
 #define virXendError(conn, code, fmt...)                                     \
@@ -4231,8 +4239,8 @@ xenDaemonDetachDevice(virDomainPtr domain, const char *xml)
                                         def, xml, VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (virDomainXMLDevID(domain, dev, class, ref, sizeof(ref)))
-        goto cleanup;
+    if (virDomainGetDevInfo(domain, dev, class, sizeof(class),
+                            ref, sizeof(ref)))
 
     ret = xend_op(domain->conn, domain->name, "op", "device_destroy",
                   "type", class, "dev", ref, "force", "0", "rm_cfg", "1", NULL);
@@ -5967,4 +5975,52 @@ virDomainXMLDevID(virDomainPtr domain,
     return 0;
 }
 
+
+/**
+ * virDomainGetDevInfo:
+ * @domain: pointer to domain object
+ * @dev: pointer to device config object
+ * @class: Xen device class "vbd", "tap", or "vif" (OUT)
+ * @class_len: Length of class
+ * @ref: Xen device reference (OUT)
+ * @ref_len: Length of ref
+ *
+ * Set class according to driver name, and:
+ *  - if disk, copy in ref the target name from description
+ *  - otherwise call virDomainXMLDevID to populate class and ref
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+static int
+virDomainGetDevInfo(virDomainPtr domain,
+                    virDomainDeviceDefPtr dev,
+                    char *class,
+                    int class_len,
+                    char *ref,
+                    int ref_len)
+{
+    char *tmp;
+
+    if (dev->type == VIR_DOMAIN_DEVICE_DISK) {
+        if (dev->data.disk->driverName &&
+            STREQ(dev->data.disk->driverName, "tap"))
+            tmp = virStrcpy(class, "tap", class_len);
+        else
+            tmp = virStrcpy(class, "vbd", class_len);
+        if (tmp == NULL)
+            return -1;
+
+        if (dev->data.disk->dst == NULL)
+            return -1;
+
+        tmp = virStrcpy(ref, dev->data.disk->dst, ref_len);
+        if (tmp == NULL)
+            return -1;
+
+        return 0;
+    }
+
+    return virDomainXMLDevID(domain, dev, class, ref, ref_len);
+}
+
 #endif /* ! PROXY */

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]