Currently, on device detach, we parse given XML, find the device
in domain object, free it and try to restore security labels.
However, in some cases (e.g. usb hostdev) parsed XML contains
less information than freed device. In usb case it is bus & device
IDs. These are needed during label restoring as a symlink into
/dev/bus is generated from them. Therefore don't drop device
configuration until security labels are restored.
---
src/qemu/qemu_hotplug.c | 38 ++++++++++++++++++++++++++------------
src/qemu/qemu_hotplug.h | 6 ------
2 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b28a8cb..4067bb0 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1952,9 +1952,11 @@ cleanup:
return ret;
}
-int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev)
+static int
+qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ virDomainHostdevDefPtr *detach_ret)
{
virDomainHostdevDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -2050,14 +2052,19 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
VIR_FREE(vm->def->hostdevs);
vm->def->nhostdevs = 0;
}
- virDomainHostdevDefFree(detach);
+ if (detach_ret)
+ *detach_ret = detach;
+ else
+ virDomainHostdevDefFree(detach);
return ret;
}
-int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev)
+static int
+qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ virDomainHostdevDefPtr *detach_ret)
{
virDomainHostdevDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -2129,7 +2136,10 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
VIR_FREE(vm->def->hostdevs);
vm->def->nhostdevs = 0;
}
- virDomainHostdevDefFree(detach);
+ if (detach_ret)
+ *detach_ret = detach;
+ else
+ virDomainHostdevDefFree(detach);
return ret;
}
@@ -2139,6 +2149,7 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
virDomainDeviceDefPtr dev)
{
virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+ virDomainHostdevDefPtr detach = NULL;
int ret;
if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
@@ -2150,10 +2161,10 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
switch (hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
- ret = qemuDomainDetachHostPciDevice(driver, vm, dev);
+ ret = qemuDomainDetachHostPciDevice(driver, vm, dev, &detach);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
- ret = qemuDomainDetachHostUsbDevice(driver, vm, dev);
+ ret = qemuDomainDetachHostUsbDevice(driver, vm, dev, &detach);
break;
default:
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -2162,10 +2173,13 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
return -1;
}
- if (virSecurityManagerRestoreHostdevLabel(driver->securityManager,
- vm, dev->data.hostdev) < 0)
+ if (ret == 0 &&
+ virSecurityManagerRestoreHostdevLabel(driver->securityManager,
+ vm, detach) < 0)
VIR_WARN("Failed to restore host device labelling");
+ virDomainHostdevDefFree(detach);
+
return ret;
}
diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h
index 6c69225..0310361 100644
--- a/src/qemu/qemu_hotplug.h
+++ b/src/qemu/qemu_hotplug.h
@@ -92,12 +92,6 @@ int qemuDomainDetachPciControllerDevice(struct qemud_driver *driver,
int qemuDomainDetachNetDevice(struct qemud_driver *driver,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev);
-int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev);
-int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
- virDomainObjPtr vm,
- virDomainDeviceDefPtr dev);
int qemuDomainDetachHostDevice(struct qemud_driver *driver,
virDomainObjPtr vm,
virDomainDeviceDefPtr dev);
--
1.7.3.4