---
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