From 6bc4ea5af0b24c65f70e0b06cc5996d0d2c5827f Mon Sep 17 00:00:00 2001 From: Wolfgang Mauerer Date: Wed, 5 May 2010 16:52:15 +0200 Subject: [PATCH] Implement SCSI disk unplugging With the introduction of the generic qemu device model, unplugging SCSI disks works like a charm, so support it in libvirt. * src/qemu/qemu_driver.c: Add qemudDomainDetachSCSIDiskDevice() to do the unplugging, extend qemudDomainDetachDeviceAdd(). Signed-off-by: Wolfgang Mauerer Signed-off-by: Eric Blake --- src/qemu/qemu_driver.c | 60 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cbf6602af8..92dc22decc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7939,6 +7939,51 @@ static int qemudDomainDetachPciDiskDevice(struct qemud_driver *driver, qemudShrinkDisks(vm->def, i); + if (driver->securityDriver && + driver->securityDriver->domainRestoreSecurityImageLabel && + driver->securityDriver->domainRestoreSecurityImageLabel(vm, dev->data.disk) < 0) + VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); + + ret = 0; + +cleanup: + return ret; +} + +static int qemudDomainDetachSCSIDiskDevice(struct qemud_driver *driver, + virDomainObjPtr vm, + virDomainDeviceDefPtr dev, + unsigned long long qemuCmdFlags) +{ + int i, ret = -1; + virDomainDiskDefPtr detach = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + + i = qemudFindDisk(vm->def, dev->data.disk->dst); + + if (i < 0) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("disk %s not found"), dev->data.disk->dst); + goto cleanup; + } + + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("Underlying qemu does not support SCSI disk removal")); + goto cleanup; + } + + detach = vm->def->disks[i]; + + qemuDomainObjEnterMonitorWithDriver(driver, vm); + if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) { + qemuDomainObjExitMonitor(vm); + goto cleanup; + } + qemuDomainObjExitMonitorWithDriver(driver, vm); + + qemudShrinkDisks(vm->def, i); + virDomainDiskDefFree(detach); if (driver->securityDriver && @@ -8392,9 +8437,18 @@ static int qemudDomainDetachDevice(virDomainPtr dom, goto endjob; if (dev->type == VIR_DOMAIN_DEVICE_DISK && - dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK && - dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { - ret = qemudDomainDetachPciDiskDevice(driver, vm, dev, qemuCmdFlags); + dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) { + if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) { + ret = qemudDomainDetachPciDiskDevice(driver, vm, dev, qemuCmdFlags); + } + else if (dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) { + ret = qemudDomainDetachSCSIDiskDevice(driver, vm, dev, + qemuCmdFlags); + } + else { + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("This type of disk cannot be hot unplugged")); + } } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { ret = qemudDomainDetachNetDevice(driver, vm, dev, qemuCmdFlags); } else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) { -- GitLab