[libvirt] [PATCHv2 03/14] Fix vmdef usage after domain crash in monitor on device removal
Ján Tomko
jtomko at redhat.com
Wed Jan 7 15:42:30 UTC 2015
https://bugzilla.redhat.com/show_bug.cgi?id=1161024
In the device type-specific functions, exit early
if the domain has disappeared, because the cleanup
should have been done by qemuProcessStop.
Check the return value in processDeviceDeletedEvent
and qemuProcessUpdateDevices.
---
src/qemu/qemu_driver.c | 3 ++-
src/qemu/qemu_hotplug.c | 32 ++++++++++++++++++++------------
src/qemu/qemu_hotplug.h | 6 +++---
src/qemu/qemu_process.c | 6 ++++--
4 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cdf4173..f7c9219 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4044,7 +4044,8 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
if (virDomainDefFindDevice(vm->def, devAlias, &dev, true) < 0)
goto endjob;
- qemuDomainRemoveDevice(driver, vm, &dev);
+ if (qemuDomainRemoveDevice(driver, vm, &dev) < 0)
+ goto endjob;
if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
VIR_WARN("unable to save domain status after removing device %s",
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1714341..ce05f80 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2491,8 +2491,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
qemuDomainObjEnterMonitor(driver, vm);
qemuMonitorDriveDel(priv->mon, drivestr);
- qemuDomainObjExitMonitor(driver, vm);
VIR_FREE(drivestr);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ return -1;
virDomainAuditDisk(vm, disk->src, NULL, "detach", true);
@@ -2607,7 +2608,8 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
qemuDomainObjEnterMonitor(driver, vm);
qemuMonitorDriveDel(priv->mon, drivestr);
- qemuDomainObjExitMonitor(driver, vm);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
}
event = virDomainEventDeviceRemovedNewFromObj(vm, hostdev->info->alias);
@@ -2701,7 +2703,8 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
- qemuDomainObjExitMonitor(driver, vm);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
virDomainAuditNet(vm, net, NULL, "detach", false);
goto cleanup;
}
@@ -2713,12 +2716,14 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("unable to determine original VLAN"));
}
- qemuDomainObjExitMonitor(driver, vm);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
virDomainAuditNet(vm, net, NULL, "detach", false);
goto cleanup;
}
}
- qemuDomainObjExitMonitor(driver, vm);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
virDomainAuditNet(vm, net, NULL, "detach", true);
@@ -2788,7 +2793,8 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
- qemuDomainObjExitMonitor(driver, vm);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ goto cleanup;
virDomainAuditChardev(vm, chr, NULL, "detach", rc == 0);
@@ -2809,27 +2815,28 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
}
-void
+int
qemuDomainRemoveDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev)
{
+ int ret = -1;
switch ((virDomainDeviceType) dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
- qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk);
+ ret = qemuDomainRemoveDiskDevice(driver, vm, dev->data.disk);
break;
case VIR_DOMAIN_DEVICE_CONTROLLER:
- qemuDomainRemoveControllerDevice(driver, vm, dev->data.controller);
+ ret = qemuDomainRemoveControllerDevice(driver, vm, dev->data.controller);
break;
case VIR_DOMAIN_DEVICE_NET:
- qemuDomainRemoveNetDevice(driver, vm, dev->data.net);
+ ret = qemuDomainRemoveNetDevice(driver, vm, dev->data.net);
break;
case VIR_DOMAIN_DEVICE_HOSTDEV:
- qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev);
+ ret = qemuDomainRemoveHostDevice(driver, vm, dev->data.hostdev);
break;
case VIR_DOMAIN_DEVICE_CHR:
- qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
+ ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr);
break;
case VIR_DOMAIN_DEVICE_NONE:
@@ -2855,6 +2862,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
virDomainDeviceTypeToString(dev->type));
break;
}
+ return ret;
}
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index d13c532..19ab9a0 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -107,9 +107,9 @@ virDomainChrDefPtr
qemuDomainChrRemove(virDomainDefPtr vmdef,
virDomainChrDefPtr chr);
-void qemuDomainRemoveDevice(virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev);
+int qemuDomainRemoveDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev);
bool qemuDomainSignalDeviceRemoval(virDomainObjPtr vm,
const char *devAlias);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index c18204b..4528b58 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3547,8 +3547,10 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver,
if ((tmp = old)) {
while (*tmp) {
if (!virStringArrayHasString(priv->qemuDevices, *tmp) &&
- virDomainDefFindDevice(vm->def, *tmp, &dev, false) == 0)
- qemuDomainRemoveDevice(driver, vm, &dev);
+ virDomainDefFindDevice(vm->def, *tmp, &dev, false) == 0 &&
+ qemuDomainRemoveDevice(driver, vm, &dev) < 0) {
+ goto cleanup;
+ }
tmp++;
}
}
--
2.0.4
More information about the libvir-list
mailing list