From 13d5a6b83d5252ce323889022e142e797a96d89c Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 15 Dec 2011 17:51:56 +0100 Subject: [PATCH] qemu: Don't drop hostdev config until security label restore 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 b28a8cb1ea..4067bb08ec 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 6c692255e7..03103611dc 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);