9119d9
From 4d1a798e093f8251d2f045529eae85ad68fc3dd1 Mon Sep 17 00:00:00 2001
9119d9
Message-Id: <4d1a798e093f8251d2f045529eae85ad68fc3dd1@dist-git>
9119d9
From: John Ferlan <jferlan@redhat.com>
9119d9
Date: Mon, 6 Oct 2014 11:14:32 -0400
9119d9
Subject: [PATCH] qemu: Fix hot unplug of SCSI_HOST device
9119d9
9119d9
https://bugzilla.redhat.com/show_bug.cgi?id=1141732
9119d9
9119d9
Introduced by commit id '8f76ad99' the logic to detach a scsi_host
9119d9
device (SCSI or iSCSI) fails when attempting to remove the 'drive'
9119d9
because as I found in my investigation - the DelDevice takes care of
9119d9
that for us.
9119d9
9119d9
The investigation turned up commits to adjust the logic for the
9119d9
qemuMonitorDelDevice and qemuMonitorDriveDel processing for interfaces
9119d9
(commit id '81f76598'), disk bus=VIRTIO,SCSI,USB (commit id '0635785b'),
9119d9
and chr devices (commit id '55b21f9b'), but nothing with the host devices.
9119d9
9119d9
This commit uses the model for the previous set of changes and applies
9119d9
it to the hostdev path. The call to qemuDomainDetachHostSCSIDevice will
9119d9
return to qemuDomainDetachThisHostDevice handling either the audit of
9119d9
the failure or the wait for the removal and then call into
9119d9
qemuDomainRemoveHostDevice for the event, removal from the domain hostdev
9119d9
list, and audit of the removal similar to other paths.
9119d9
9119d9
NOTE: For now the 'conn' param to +qemuDomainDetachHostSCSIDevice is left
9119d9
as ATTRIBUTE_UNUSED.  Removing requires a cascade of other changes to be
9119d9
left for a future patch.
9119d9
9119d9
(cherry picked from commit d2774e54cde2377c78a7572eb3fec0a663e5017f)
9119d9
Signed-off-by: John Ferlan <jferlan@redhat.com>
9119d9
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
9119d9
---
9119d9
 src/qemu/qemu_hotplug.c | 50 +++++++++++++++++++++++++------------------------
9119d9
 1 file changed, 26 insertions(+), 24 deletions(-)
9119d9
9119d9
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
9119d9
index 8eb2419..fe4994a 100644
9119d9
--- a/src/qemu/qemu_hotplug.c
9119d9
+++ b/src/qemu/qemu_hotplug.c
9119d9
@@ -2622,10 +2622,26 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
9119d9
     virDomainNetDefPtr net = NULL;
9119d9
     virObjectEventPtr event;
9119d9
     size_t i;
9119d9
+    int ret = -1;
9119d9
+    qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
+    char *drivestr = NULL;
9119d9
 
9119d9
     VIR_DEBUG("Removing host device %s from domain %p %s",
9119d9
               hostdev->info->alias, vm, vm->def->name);
9119d9
 
9119d9
+    if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
9119d9
+        /* build the actual drive id string as generated during
9119d9
+         * qemuBuildSCSIHostdevDrvStr that is passed to qemu */
9119d9
+        if (virAsprintf(&drivestr, "%s-%s",
9119d9
+                        virDomainDeviceAddressTypeToString(hostdev->info->type),
9119d9
+                        hostdev->info->alias) < 0)
9119d9
+            goto cleanup;
9119d9
+
9119d9
+        qemuDomainObjEnterMonitor(driver, vm);
9119d9
+        qemuMonitorDriveDel(priv->mon, drivestr);
9119d9
+        qemuDomainObjExitMonitor(driver, vm);
9119d9
+    }
9119d9
+
9119d9
     event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
9119d9
     if (event)
9119d9
         qemuDomainEventQueue(driver, event);
9119d9
@@ -2678,8 +2694,12 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
9119d9
         networkReleaseActualDevice(vm->def, net);
9119d9
         virDomainNetDefFree(net);
9119d9
     }
9119d9
+    ret = 0;
9119d9
+
9119d9
+ cleanup:
9119d9
+    VIR_FREE(drivestr);
9119d9
     virObjectUnref(cfg);
9119d9
-    return 0;
9119d9
+    return ret;
9119d9
 }
9119d9
 
9119d9
 
9119d9
@@ -3305,14 +3325,12 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
9119d9
 }
9119d9
 
9119d9
 static int
9119d9
-qemuDomainDetachHostSCSIDevice(virConnectPtr conn,
9119d9
+qemuDomainDetachHostSCSIDevice(virConnectPtr conn ATTRIBUTE_UNUSED,
9119d9
                                virQEMUDriverPtr driver,
9119d9
                                virDomainObjPtr vm,
9119d9
                                virDomainHostdevDefPtr detach)
9119d9
 {
9119d9
     qemuDomainObjPrivatePtr priv = vm->privateData;
9119d9
-    char *drvstr = NULL;
9119d9
-    char *devstr = NULL;
9119d9
     int ret = -1;
9119d9
 
9119d9
     if (!detach->info->alias) {
9119d9
@@ -3327,33 +3345,17 @@ qemuDomainDetachHostSCSIDevice(virConnectPtr conn,
9119d9
         return -1;
9119d9
     }
9119d9
 
9119d9
-    if (!(drvstr = qemuBuildSCSIHostdevDrvStr(conn, detach, priv->qemuCaps,
9119d9
-                                              &buildCommandLineCallbacks)))
9119d9
-        goto cleanup;
9119d9
-    if (!(devstr = qemuBuildSCSIHostdevDevStr(vm->def, detach, priv->qemuCaps)))
9119d9
-        goto cleanup;
9119d9
-
9119d9
     qemuDomainMarkDeviceForRemoval(vm, detach->info);
9119d9
 
9119d9
     qemuDomainObjEnterMonitor(driver, vm);
9119d9
-    if ((ret = qemuMonitorDelDevice(priv->mon, detach->info->alias)) == 0) {
9119d9
-        if ((ret = qemuMonitorDriveDel(priv->mon, drvstr)) < 0) {
9119d9
-            virErrorPtr orig_err = virSaveLastError();
9119d9
-            if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
9119d9
-                VIR_WARN("Unable to add device %s (%s) after failed "
9119d9
-                         "qemuMonitorDriveDel",
9119d9
-                         drvstr, devstr);
9119d9
-            if (orig_err) {
9119d9
-                virSetError(orig_err);
9119d9
-                virFreeError(orig_err);
9119d9
-            }
9119d9
-        }
9119d9
+    if (qemuMonitorDelDevice(priv->mon, detach->info->alias) < 0) {
9119d9
+        qemuDomainObjExitMonitor(driver, vm);
9119d9
+        goto cleanup;
9119d9
     }
9119d9
     qemuDomainObjExitMonitor(driver, vm);
9119d9
+    ret = 0;
9119d9
 
9119d9
  cleanup:
9119d9
-    VIR_FREE(drvstr);
9119d9
-    VIR_FREE(devstr);
9119d9
     return ret;
9119d9
 }
9119d9
 
9119d9
-- 
9119d9
2.1.2
9119d9