--- src/qemu/qemu_driver.c | 31 +++++++++--- src/qemu/qemu_hotplug.c | 127 ++++++++++++++++++------------------------------ src/qemu/qemu_hotplug.h | 4 +- 3 files changed, 73 insertions(+), 89 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 495867a..436ce6a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6401,21 +6401,43 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, } static int +qemuFindDisk(virDomainDefPtr def, const char *dst) +{ + size_t i; + + for (i = 0; i < def->ndisks; i++) { + if (STREQ(def->disks[i]->dst, dst)) { + return i; + } + } + + return -1; +} + +static int qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev) { - virDomainDiskDefPtr disk = dev->data.disk; + virDomainDiskDefPtr disk; int ret = -1; + int idx; + + if ((idx = qemuFindDisk(vm->def, dev->data.disk->dst)) < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("disk %s not found"), dev->data.disk->dst); + return -1; + } + disk = vm->def->disks[idx]; switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_DISK: case VIR_DOMAIN_DISK_DEVICE_LUN: if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) - ret = qemuDomainDetachVirtioDiskDevice(driver, vm, dev); + ret = qemuDomainDetachVirtioDiskDevice(driver, vm, disk); else if (disk->bus == VIR_DOMAIN_DISK_BUS_SCSI || disk->bus == VIR_DOMAIN_DISK_BUS_USB) - ret = qemuDomainDetachDiskDevice(driver, vm, dev); + ret = qemuDomainDetachDiskDevice(driver, vm, disk); else virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", _("This type of disk cannot be hot unplugged")); @@ -6427,9 +6449,6 @@ qemuDomainDetachDeviceDiskLive(virQEMUDriverPtr driver, break; } - if (ret == 0) - ignore_value(qemuRemoveSharedDevice(driver, dev, vm->def->name)); - return ret; } diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 2a57fef..6db789d 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2071,19 +2071,6 @@ cleanup: } -static inline int qemuFindDisk(virDomainDefPtr def, const char *dst) -{ - size_t i; - - for (i = 0; i < def->ndisks; i++) { - if (STREQ(def->disks[i]->dst, dst)) { - return i; - } - } - - return -1; -} - static int qemuComparePCIDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, virDomainDeviceDefPtr device ATTRIBUTE_UNUSED, virDomainDeviceInfoPtr info1, @@ -2112,30 +2099,58 @@ static bool qemuIsMultiFunctionDevice(virDomainDefPtr def, } +static void +qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainDiskDefPtr disk) +{ + virDomainDeviceDef dev; + size_t i; + + VIR_DEBUG("Removing disk %s from domain %p %s", + disk->info.alias, vm, vm->def->name); + + virDomainAuditDisk(vm, disk->src, NULL, "detach", true); + + for (i = 0; i < vm->def->ndisks; i++) { + if (vm->def->disks[i] == disk) { + virDomainDiskRemove(vm->def, i); + break; + } + } + + qemuDomainReleaseDeviceAddress(vm, &disk->info, disk->src); + + if (virSecurityManagerRestoreImageLabel(driver->securityManager, + vm->def, disk) < 0) + VIR_WARN("Unable to restore security label on %s", disk->src); + + if (qemuTeardownDiskCgroup(vm, disk) < 0) + VIR_WARN("Failed to tear down cgroup for disk path %s", disk->src); + + if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0) + VIR_WARN("Unable to release lock on %s", disk->src); + + dev.type = VIR_DOMAIN_DEVICE_DISK; + dev.data.disk = disk; + ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name)); + + virDomainDiskDefFree(disk); +} + + int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDiskDefPtr detach) { - int idx; int ret = -1; - virDomainDiskDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; char *drivestr = NULL; - idx = qemuFindDisk(vm->def, dev->data.disk->dst); - - if (idx < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("disk %s not found"), dev->data.disk->dst); - goto cleanup; - } - - detach = vm->def->disks[idx]; - if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) { virReportError(VIR_ERR_OPERATION_FAILED, _("cannot hot unplug multifunction PCI device: %s"), - dev->data.disk->dst); + detach->dst); goto cleanup; } @@ -2183,27 +2198,7 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, qemuDomainObjExitMonitor(driver, vm); - virDomainAuditDisk(vm, detach->src, NULL, "detach", true); - - qemuDomainReleaseDeviceAddress(vm, &detach->info, dev->data.disk->src); - - virDomainDiskRemove(vm->def, idx); - - dev->data.disk->backingChain = detach->backingChain; - detach->backingChain = NULL; - virDomainDiskDefFree(detach); - - if (virSecurityManagerRestoreImageLabel(driver->securityManager, - vm->def, dev->data.disk) < 0) - VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); - - if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0) - VIR_WARN("Failed to teardown cgroup for disk path %s", - NULLSTR(dev->data.disk->src)); - - if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0) - VIR_WARN("Unable to release lock on %s", dev->data.disk->src); - + qemuDomainRemoveDiskDevice(driver, vm, detach); ret = 0; cleanup: @@ -2213,31 +2208,19 @@ cleanup: int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev) + virDomainDiskDefPtr detach) { - int idx; int ret = -1; - virDomainDiskDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; char *drivestr = NULL; - idx = qemuFindDisk(vm->def, dev->data.disk->dst); - - if (idx < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("disk %s not found"), dev->data.disk->dst); - goto cleanup; - } - if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { virReportError(VIR_ERR_OPERATION_FAILED, _("Underlying qemu does not support %s disk removal"), - virDomainDiskBusTypeToString(dev->data.disk->bus)); + virDomainDiskBusTypeToString(detach->bus)); goto cleanup; } - detach = vm->def->disks[idx]; - if (detach->mirror) { virReportError(VIR_ERR_BLOCK_COPY_ACTIVE, _("disk '%s' is in an active block copy job"), @@ -2263,25 +2246,7 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, qemuDomainObjExitMonitor(driver, vm); - virDomainAuditDisk(vm, detach->src, NULL, "detach", true); - - virDomainDiskRemove(vm->def, idx); - - dev->data.disk->backingChain = detach->backingChain; - detach->backingChain = NULL; - virDomainDiskDefFree(detach); - - if (virSecurityManagerRestoreImageLabel(driver->securityManager, - vm->def, dev->data.disk) < 0) - VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); - - if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0) - VIR_WARN("Failed to teardown cgroup for disk path %s", - NULLSTR(dev->data.disk->src)); - - if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0) - VIR_WARN("Unable to release lock on disk %s", dev->data.disk->src); - + qemuDomainRemoveDiskDevice(driver, vm, detach); ret = 0; cleanup: diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index da20eb1..da802ee 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -85,10 +85,10 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver, int linkstate); int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDiskDefPtr disk); int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, - virDomainDeviceDefPtr dev); + virDomainDiskDefPtr disk); int qemuDomainDetachPciControllerDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainDeviceDefPtr dev); -- 1.8.3.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list