提交 ee414b5d 编写于 作者: C Cole Robinson

qemu: hotplug: Only label hostdev after checking device conflicts

Similar to what Jiri did for cgroup setup/teardown in 05e149f9, push
it all into the device handler functions so we can do the necessary prep
work before claiming the device.

This also fixes hotplugging USB devices by product/vendor (virt-manager's
default behavior):

https://bugzilla.redhat.com/show_bug.cgi?id=1016511
上级 24fbbb82
...@@ -1153,6 +1153,7 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver, ...@@ -1153,6 +1153,7 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
char *configfd_name = NULL; char *configfd_name = NULL;
bool releaseaddr = false; bool releaseaddr = false;
bool teardowncgroup = false; bool teardowncgroup = false;
bool teardownlabel = false;
int backend = hostdev->source.subsys.u.pci.backend; int backend = hostdev->source.subsys.u.pci.backend;
if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
...@@ -1193,6 +1194,11 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver, ...@@ -1193,6 +1194,11 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
goto error; goto error;
teardowncgroup = true; teardowncgroup = true;
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
goto error;
teardownlabel = true;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto error; goto error;
...@@ -1250,6 +1256,10 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver, ...@@ -1250,6 +1256,10 @@ qemuDomainAttachHostPciDevice(virQEMUDriverPtr driver,
error: error:
if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0) if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail"); VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
if (teardownlabel &&
virSecurityManagerRestoreHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail");
if (releaseaddr) if (releaseaddr)
qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL); qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
...@@ -1445,6 +1455,7 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver, ...@@ -1445,6 +1455,7 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
char *devstr = NULL; char *devstr = NULL;
bool added = false; bool added = false;
bool teardowncgroup = false; bool teardowncgroup = false;
bool teardownlabel = false;
int ret = -1; int ret = -1;
if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0) if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
...@@ -1466,6 +1477,11 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver, ...@@ -1466,6 +1477,11 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
teardowncgroup = true; teardowncgroup = true;
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
goto cleanup;
teardownlabel = true;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto cleanup; goto cleanup;
...@@ -1492,10 +1508,14 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver, ...@@ -1492,10 +1508,14 @@ qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
if (ret < 0 && if (ret < 0) {
teardowncgroup && if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
qemuTeardownHostdevCgroup(vm, hostdev) < 0) VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail"); if (teardownlabel &&
virSecurityManagerRestoreHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail");
}
if (added) if (added)
virUSBDeviceListSteal(driver->activeUsbHostdevs, usb); virUSBDeviceListSteal(driver->activeUsbHostdevs, usb);
virUSBDeviceFree(usb); virUSBDeviceFree(usb);
...@@ -1515,6 +1535,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver, ...@@ -1515,6 +1535,7 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
char *devstr = NULL; char *devstr = NULL;
char *drvstr = NULL; char *drvstr = NULL;
bool teardowncgroup = false; bool teardowncgroup = false;
bool teardownlabel = false;
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) || if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE) ||
!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) || !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) ||
...@@ -1543,6 +1564,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver, ...@@ -1543,6 +1564,11 @@ qemuDomainAttachHostScsiDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
teardowncgroup = true; teardowncgroup = true;
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
goto cleanup;
teardownlabel = true;
if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0) if (qemuAssignDeviceHostdevAlias(vm->def, hostdev, -1) < 0)
goto cleanup; goto cleanup;
...@@ -1584,6 +1610,10 @@ cleanup: ...@@ -1584,6 +1610,10 @@ cleanup:
qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1); qemuDomainReAttachHostScsiDevices(driver, vm->def->name, &hostdev, 1);
if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0) if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail"); VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
if (teardownlabel &&
virSecurityManagerRestoreHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
VIR_WARN("Unable to restore host device labelling on hotplug fail");
} }
VIR_FREE(drvstr); VIR_FREE(drvstr);
VIR_FREE(devstr); VIR_FREE(devstr);
...@@ -1601,10 +1631,6 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver, ...@@ -1601,10 +1631,6 @@ int qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
return -1; return -1;
} }
if (virSecurityManagerSetHostdevLabel(driver->securityManager,
vm->def, hostdev, NULL) < 0)
return -1;
switch (hostdev->source.subsys.type) { switch (hostdev->source.subsys.type) {
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
if (qemuDomainAttachHostPciDevice(driver, vm, if (qemuDomainAttachHostPciDevice(driver, vm,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册