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

[libvirt] [PATCH] protect the scsi controller to be deleted when it is in use



Steps to reproduce this bug:
1. virsh attach-disk domain --source imagefile --target sdb --sourcetype file --driver qemu --subdriver raw
2. virsh detach-device controller.xml # remove scsi controller 0
3. virsh detach-disk domain sdb
   error: Failed to detach disk
   error: operation failed: detaching scsi0-0-1 device failed: Device 'scsi0-0-1' not found

I think we should not detach a controller when it is used by some other device.

Signed-off-by: Wen Congyang <wency cn fujitsu com>

---
 src/qemu/qemu_hotplug.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index fb9db5a..2c8bc3b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1297,6 +1297,56 @@ cleanup:
     return ret;
 }
 
+static bool qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
+                                           virDomainControllerDefPtr detach)
+{
+    int i;
+    virDomainDiskDefPtr disk;
+
+    for (i = 0; i < vm->def->ndisks; i++) {
+        disk = vm->def->disks[i];
+        if (disk->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE)
+            /* the disk does not use disk controller */
+            continue;
+
+        /* check whether the disk uses this type controller */
+        if (disk->bus == VIR_DOMAIN_DISK_BUS_IDE &&
+            detach->type != VIR_DOMAIN_CONTROLLER_TYPE_IDE)
+            continue;
+        if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC &&
+            detach->type != VIR_DOMAIN_CONTROLLER_TYPE_FDC)
+            continue;
+        if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI &&
+            detach->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
+            continue;
+
+        if (disk->info.addr.drive.controller == detach->idx)
+            return true;
+    }
+
+    return false;
+}
+
+static bool qemuDomainControllerIsBusy(virDomainObjPtr vm,
+                                       virDomainControllerDefPtr detach)
+{
+    switch (detach->type) {
+    case VIR_DOMAIN_CONTROLLER_TYPE_IDE:
+    case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
+    case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
+        return qemuDomainDiskControllerIsBusy(vm, detach);
+
+    case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
+    case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
+    case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
+    default:
+        /* libvirt does not support sata controller, and does not support to
+         * detach virtio and smart card controller.
+         */
+        return true;
+    }
+}
+
 int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
                                         virDomainObjPtr vm,
                                         virDomainDeviceDefPtr dev,
@@ -1329,6 +1379,12 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
         goto cleanup;
     }
 
+    if (qemuDomainControllerIsBusy(vm, detach)) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
+                        _("device cannot be detached: device is busy"));
+        goto cleanup;
+    }
+
     if (qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE) {
         if (qemuAssignDeviceControllerAlias(detach) < 0)
             goto cleanup;
-- 
1.7.1


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