[libvirt] [PATCH 6/6] Implement hotremove for SCSI disks

Wolfgang Mauerer wolfgang.mauerer at siemens.com
Fri Feb 26 13:09:19 UTC 2010


Recent qemu versions allow us to add disks dynamically into the system
via the drive_add/device_add mechanism. Removing them is now just a
matter of using device_del, and this patch adds the required bits
and pieces to libvirt.

Signed-off-by: Wolfgang Mauerer <wolfgang.mauerer at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
---
 src/qemu/qemu_driver.c |   57 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d683b1c..ecbb23d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5494,6 +5494,60 @@ qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver *driver,
 }
 
 
+static int qemudDomainDetachSCSIDisk(struct qemud_driver *driver,
+                                     virDomainObjPtr vm,
+                                     virDomainDeviceDefPtr dev,
+                                     unsigned int qemuCmdFlags)
+{
+    int i;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainDiskDefPtr detach = NULL;
+
+    if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+        return -1;
+    }
+
+    for (i = 0 ; i < vm->def->ndisks ; i++) {
+        if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
+            detach = vm->def->disks[i];
+            break;
+        }
+    }
+
+    if (!detach) {
+        qemuReportError(VIR_ERR_OPERATION_FAILED,
+                        _("disk %s not found"), dev->data.disk->dst);
+        return -1;
+    }
+
+    qemuDomainObjEnterMonitorWithDriver(driver, vm);
+    /* Note: drive_del does not exist, but device_del will
+       automatically erase the associated drive as well */
+    if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
+        qemuDomainObjExitMonitor(vm);
+        return -1;
+    }
+    qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+    if (vm->def->ndisks > 1) {
+        memmove(vm->def->disks + i,
+                vm->def->disks + i + 1,
+                sizeof(*vm->def->disks) *
+                (vm->def->ndisks - (i + 1)));
+        vm->def->ndisks--;
+        if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
+            /* ignore, harmless */
+        }
+    } else {
+        VIR_FREE(vm->def->disks);
+        vm->def->ndisks = 0;
+    }
+    virDomainDiskDefFree(detach);
+
+    return 0;
+}
+
+
 static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver,
                                      virDomainObjPtr vm,
                                      virDomainDiskDefPtr disk,
@@ -6563,6 +6617,9 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
         dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
         dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
         ret = qemudDomainDetachPciDiskDevice(driver, vm, dev);
+    } else if(dev->type == VIR_DOMAIN_DEVICE_DISK &&
+              dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+        ret = qemudDomainDetachSCSIDisk(driver, vm, dev, qemuCmdFlags);
     } else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
         ret = qemudDomainDetachNetDevice(driver, vm, dev);
     } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
-- 
1.6.4




More information about the libvir-list mailing list