return -1;
}
+static int
+qemuCheckPciHostDevice(virConnectPtr conn,
+ virDomainObjPtr owner_vm,
+ pciDevice *dev)
+{
+ struct qemud_driver *driver = conn->privateData;
+ int ret = 1, i;
+
+ for (i = 0; i < driver->domains.count && ret; i++) {
+ virDomainObjPtr vm = driver->domains.objs[i];
+
+ if (vm == owner_vm)
+ continue;
+
+ virDomainObjLock(vm);
+
+ if (virDomainIsActive(vm)) {
+ int j;
+
+ for (j = 0; j < vm->def->nhostdevs && ret; j++) {
+ virDomainHostdevDefPtr hostdev = vm->def->hostdevs[j];
+
+ if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+ continue;
+ if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ continue;
+
+ if (pciDeviceEquals(conn, dev,
+ hostdev->source.subsys.u.pci.domain,
+ hostdev->source.subsys.u.pci.bus,
+ hostdev->source.subsys.u.pci.slot,
+ hostdev->source.subsys.u.pci.function))
+ ret = 0;
+ }
+ }
+
+ virDomainObjUnlock(vm);
+ }
+
+ return ret;
+}
+
static int
qemuPrepareHostDevices(virConnectPtr conn, virDomainObjPtr vm)
{
if (!dev)
goto error;
- if (pciResetDevice(conn, vm, dev, NULL) < 0) {
+ if (pciResetDevice(conn, vm, dev, qemuCheckPciHostDevice) < 0) {
pciFreeDevice(conn, dev);
goto error;
}
continue;
}
- if (pciResetDevice(conn, vm, dev, NULL) < 0) {
+ if (pciResetDevice(conn, vm, dev, qemuCheckPciHostDevice) < 0) {
virErrorPtr err = virGetLastError();
VIR_ERROR(_("Failed to reset PCI device: %s\n"),
err ? err->message : "");
return -1;
if (pciDettachDevice(conn, pci) < 0 ||
- pciResetDevice(conn, vm, pci, NULL) < 0) {
+ pciResetDevice(conn, vm, pci, qemuCheckPciHostDevice) < 0) {
pciFreeDevice(conn, pci);
return -1;
}
static int
qemudNodeDeviceReset (virNodeDevicePtr dev)
{
+ struct qemud_driver *driver = dev->conn->privateData;
pciDevice *pci;
unsigned domain, bus, slot, function;
int ret = -1;
if (!pci)
return -1;
- if (pciResetDevice(dev->conn, NULL, pci, NULL) < 0)
+ qemuDriverLock(driver);
+
+ if (pciResetDevice(dev->conn, NULL, pci, qemuCheckPciHostDevice) < 0)
goto out;
ret = 0;
out:
+ qemuDriverUnlock(driver);
pciFreeDevice(dev->conn, pci);
return ret;
}