commit bd1168101a0ea5efcf3b2dc5ee782af6ad911320
Author: Jim Fehlig <jfehlig@suse.com>
Date:   Tue Feb 7 12:05:15 2017 -0700

    libxl: fix disk detach when <driver> not specified
    
    When a user does not explicitly set a <driver> in the disk config,
    libvirt defers selection of a default to libxl. This approach works
    fine when starting a domain with such configuration or attaching a
    disk to a running domain. But when detaching such a disk, libxl
    will fail with "unrecognized disk backend type: 0". libxl makes no
    attempt to recalculate a default backend (driver) on detach and
    simply fails when uninitialized.
    
    This patch updates the libvirt disk config with the backend selected
    by libxl when starting a domain or attaching a disk to a running
    domain. Another benefit of this approach is that the live XML is
    also updated with the backend driver selected by libxl.

Index: libvirt-2.0.0/src/libxl/libxl_conf.c
===================================================================
--- libvirt-2.0.0.orig/src/libxl/libxl_conf.c
+++ libvirt-2.0.0/src/libxl/libxl_conf.c
@@ -878,6 +878,38 @@ libxlMakeDiskList(virDomainDefPtr def, l
     return -1;
 }
 
+/*
+ * Update libvirt disk config with libxl disk config.
+ *
+ * This function can be used to update the libvirt disk config with default
+ * values selected by libxl. Currently only the backend type is selected by
+ * libxl when not explicitly specified by the user.
+ */
+void
+libxlUpdateDiskDef(virDomainDiskDefPtr l_disk, libxl_device_disk *x_disk)
+{
+    const char *driver = NULL;
+
+    if (virDomainDiskGetDriver(l_disk))
+        return;
+
+    switch (x_disk->backend) {
+    case LIBXL_DISK_BACKEND_QDISK:
+        driver = "qemu";
+        break;
+    case LIBXL_DISK_BACKEND_TAP:
+        driver = "tap";
+        break;
+    case LIBXL_DISK_BACKEND_PHY:
+        driver = "phy";
+        break;
+    case LIBXL_DISK_BACKEND_UNKNOWN:
+        break;
+    }
+    if (driver)
+        ignore_value(virDomainDiskSetDriver(l_disk, driver));
+}
+
 int
 libxlMakeNic(virDomainDefPtr def,
              virDomainNetDefPtr l_nic,
Index: libvirt-2.0.0/src/libxl/libxl_conf.h
===================================================================
--- libvirt-2.0.0.orig/src/libxl/libxl_conf.h
+++ libvirt-2.0.0/src/libxl/libxl_conf.h
@@ -173,6 +173,10 @@ int libxlDriverConfigLoadFile(libxlDrive
 
 int
 libxlMakeDisk(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev);
+
+void
+libxlUpdateDiskDef(virDomainDiskDefPtr l_dev, libxl_device_disk *x_dev);
+
 int
 libxlMakeNic(virDomainDefPtr def,
              virDomainNetDefPtr l_nic,
Index: libvirt-2.0.0/src/libxl/libxl_domain.c
===================================================================
--- libvirt-2.0.0.orig/src/libxl/libxl_domain.c
+++ libvirt-2.0.0/src/libxl/libxl_domain.c
@@ -1030,6 +1030,30 @@ libxlDomainCreateIfaceNames(virDomainDef
     }
 }
 
+static void
+libxlDomainUpdateDiskParams(virDomainDefPtr def, libxl_ctx *ctx)
+{
+    libxl_device_disk *disks;
+    int num_disks = 0;
+    size_t i;
+    int idx;
+
+    disks = libxl_device_disk_list(ctx, def->id, &num_disks);
+    if (!disks)
+        return;
+
+    for (i = 0; i < num_disks; i++) {
+        if ((idx = virDomainDiskIndexByName(def, disks[i].vdev, false)) < 0)
+            continue;
+
+        libxlUpdateDiskDef(def->disks[idx], &disks[i]);
+    }
+
+    for (i = 0; i < num_disks; i++)
+        libxl_device_disk_dispose(&disks[i]);
+    VIR_FREE(disks);
+}
+
 
 #ifdef LIBXL_HAVE_SRM_V2
 # define LIBXL_DOMSTART_RESTORE_VER_ATTR /* empty */
@@ -1189,6 +1213,7 @@ libxlDomainStart(libxlDriverPrivatePtr d
         goto destroy_dom;
 
     libxlDomainCreateIfaceNames(vm->def, &d_config);
+    libxlDomainUpdateDiskParams(vm->def, cfg->ctx);
 
     if ((dom_xml = virDomainDefFormat(vm->def, cfg->caps, 0)) == NULL)
         goto destroy_dom;
Index: libvirt-2.0.0/src/libxl/libxl_driver.c
===================================================================
--- libvirt-2.0.0.orig/src/libxl/libxl_driver.c
+++ libvirt-2.0.0/src/libxl/libxl_driver.c
@@ -2936,6 +2936,7 @@ libxlDomainAttachDeviceDiskLive(virDomai
                     goto cleanup;
                 }
 
+                libxlUpdateDiskDef(l_disk, &x_disk);
                 virDomainDiskInsertPreAlloced(vm->def, l_disk);
 
             } else {
