mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 15:15:25 +00:00
Check for active PCI devices when doing nodedevice operations.
In the current libvirt PCI code, there is no checking whether a PCI device is in use by a guest when doing node device detach or reattach. This causes problems when a device is assigned to a guest, and the administrator starts issuing nodedevice commands. Make it so that we check the list of active devices when trying to detach/reattach, and only allow the operation if the device is not assigned to a guest. Signed-off-by: Chris Lalancette <clalance@redhat.com>
This commit is contained in:
parent
415b14903e
commit
53a1db4dfc
@ -2865,7 +2865,7 @@ qemuPrepareHostPCIDevices(struct qemud_driver *driver,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (pciDeviceGetManaged(dev) &&
|
if (pciDeviceGetManaged(dev) &&
|
||||||
pciDettachDevice(dev) < 0)
|
pciDettachDevice(dev, driver->activePciHostdevs) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2967,7 +2967,7 @@ qemuPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemudReattachManagedDevice(pciDevice *dev)
|
qemudReattachManagedDevice(pciDevice *dev, struct qemud_driver *driver)
|
||||||
{
|
{
|
||||||
int retries = 100;
|
int retries = 100;
|
||||||
|
|
||||||
@ -2977,7 +2977,7 @@ qemudReattachManagedDevice(pciDevice *dev)
|
|||||||
usleep(100*1000);
|
usleep(100*1000);
|
||||||
retries--;
|
retries--;
|
||||||
}
|
}
|
||||||
if (pciReAttachDevice(dev) < 0) {
|
if (pciReAttachDevice(dev, driver->activePciHostdevs) < 0) {
|
||||||
virErrorPtr err = virGetLastError();
|
virErrorPtr err = virGetLastError();
|
||||||
VIR_ERROR(_("Failed to re-attach PCI device: %s"),
|
VIR_ERROR(_("Failed to re-attach PCI device: %s"),
|
||||||
err ? err->message : _("unknown error"));
|
err ? err->message : _("unknown error"));
|
||||||
@ -3024,7 +3024,7 @@ qemuDomainReAttachHostDevices(struct qemud_driver *driver,
|
|||||||
|
|
||||||
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
|
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
|
||||||
pciDevice *dev = pciDeviceListGet(pcidevs, i);
|
pciDevice *dev = pciDeviceListGet(pcidevs, i);
|
||||||
qemudReattachManagedDevice(dev);
|
qemudReattachManagedDevice(dev, driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
pciDeviceListFree(pcidevs);
|
pciDeviceListFree(pcidevs);
|
||||||
@ -7772,7 +7772,7 @@ static int qemudDomainAttachHostPciDevice(struct qemud_driver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!pciDeviceIsAssignable(pci, !driver->relaxedACS) ||
|
if (!pciDeviceIsAssignable(pci, !driver->relaxedACS) ||
|
||||||
(hostdev->managed && pciDettachDevice(pci) < 0) ||
|
(hostdev->managed && pciDettachDevice(pci, driver->activePciHostdevs) < 0) ||
|
||||||
pciResetDevice(pci, driver->activePciHostdevs) < 0) {
|
pciResetDevice(pci, driver->activePciHostdevs) < 0) {
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
return -1;
|
return -1;
|
||||||
@ -7860,7 +7860,7 @@ error:
|
|||||||
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
|
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
|
||||||
VIR_WARN0("Unable to reset PCI device after assign failure");
|
VIR_WARN0("Unable to reset PCI device after assign failure");
|
||||||
else if (hostdev->managed &&
|
else if (hostdev->managed &&
|
||||||
pciReAttachDevice(pci) < 0)
|
pciReAttachDevice(pci, driver->activePciHostdevs) < 0)
|
||||||
VIR_WARN0("Unable to re-attach PCI device after assign failure");
|
VIR_WARN0("Unable to re-attach PCI device after assign failure");
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
|
|
||||||
@ -8771,7 +8771,7 @@ static int qemudDomainDetachHostPciDevice(struct qemud_driver *driver,
|
|||||||
pciDeviceListDel(driver->activePciHostdevs, pci);
|
pciDeviceListDel(driver->activePciHostdevs, pci);
|
||||||
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
|
if (pciResetDevice(pci, driver->activePciHostdevs) < 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
qemudReattachManagedDevice(pci);
|
qemudReattachManagedDevice(pci, driver);
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11277,6 +11277,7 @@ out:
|
|||||||
static int
|
static int
|
||||||
qemudNodeDeviceDettach (virNodeDevicePtr dev)
|
qemudNodeDeviceDettach (virNodeDevicePtr dev)
|
||||||
{
|
{
|
||||||
|
struct qemud_driver *driver = dev->conn->privateData;
|
||||||
pciDevice *pci;
|
pciDevice *pci;
|
||||||
unsigned domain, bus, slot, function;
|
unsigned domain, bus, slot, function;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -11288,11 +11289,13 @@ qemudNodeDeviceDettach (virNodeDevicePtr dev)
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pciDettachDevice(pci) < 0)
|
qemuDriverLock(driver);
|
||||||
|
if (pciDettachDevice(pci, driver->activePciHostdevs) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -11300,6 +11303,7 @@ out:
|
|||||||
static int
|
static int
|
||||||
qemudNodeDeviceReAttach (virNodeDevicePtr dev)
|
qemudNodeDeviceReAttach (virNodeDevicePtr dev)
|
||||||
{
|
{
|
||||||
|
struct qemud_driver *driver = dev->conn->privateData;
|
||||||
pciDevice *pci;
|
pciDevice *pci;
|
||||||
unsigned domain, bus, slot, function;
|
unsigned domain, bus, slot, function;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -11311,11 +11315,13 @@ qemudNodeDeviceReAttach (virNodeDevicePtr dev)
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pciReAttachDevice(pci) < 0)
|
qemuDriverLock(driver);
|
||||||
|
if (pciReAttachDevice(pci, driver->activePciHostdevs) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
pciFreeDevice(pci);
|
pciFreeDevice(pci);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -814,7 +814,7 @@ pciBindDeviceToStub(pciDevice *dev, const char *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pciDettachDevice(pciDevice *dev)
|
pciDettachDevice(pciDevice *dev, pciDeviceList *activeDevs)
|
||||||
{
|
{
|
||||||
const char *driver = pciFindStubDriver();
|
const char *driver = pciFindStubDriver();
|
||||||
if (!driver) {
|
if (!driver) {
|
||||||
@ -823,6 +823,12 @@ pciDettachDevice(pciDevice *dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
|
||||||
|
pciReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Not detaching active device %s"), dev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return pciBindDeviceToStub(dev, driver);
|
return pciBindDeviceToStub(dev, driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,7 +881,7 @@ pciUnBindDeviceFromStub(pciDevice *dev, const char *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pciReAttachDevice(pciDevice *dev)
|
pciReAttachDevice(pciDevice *dev, pciDeviceList *activeDevs)
|
||||||
{
|
{
|
||||||
const char *driver = pciFindStubDriver();
|
const char *driver = pciFindStubDriver();
|
||||||
if (!driver) {
|
if (!driver) {
|
||||||
@ -884,6 +890,12 @@ pciReAttachDevice(pciDevice *dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (activeDevs && pciDeviceListFind(activeDevs, dev)) {
|
||||||
|
pciReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Not reattaching active device %s"), dev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return pciUnBindDeviceFromStub(dev, driver);
|
return pciUnBindDeviceFromStub(dev, driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +32,8 @@ pciDevice *pciGetDevice (unsigned domain,
|
|||||||
unsigned slot,
|
unsigned slot,
|
||||||
unsigned function);
|
unsigned function);
|
||||||
void pciFreeDevice (pciDevice *dev);
|
void pciFreeDevice (pciDevice *dev);
|
||||||
int pciDettachDevice (pciDevice *dev);
|
int pciDettachDevice (pciDevice *dev, pciDeviceList *activeDevs);
|
||||||
int pciReAttachDevice (pciDevice *dev);
|
int pciReAttachDevice (pciDevice *dev, pciDeviceList *activeDevs);
|
||||||
int pciResetDevice (pciDevice *dev,
|
int pciResetDevice (pciDevice *dev,
|
||||||
pciDeviceList *activeDevs);
|
pciDeviceList *activeDevs);
|
||||||
void pciDeviceSetManaged(pciDevice *dev,
|
void pciDeviceSetManaged(pciDevice *dev,
|
||||||
|
@ -1846,7 +1846,7 @@ xenUnifiedNodeDeviceDettach (virNodeDevicePtr dev)
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pciDettachDevice(pci) < 0)
|
if (pciDettachDevice(pci, NULL) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1869,7 +1869,7 @@ xenUnifiedNodeDeviceReAttach (virNodeDevicePtr dev)
|
|||||||
if (!pci)
|
if (!pci)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pciReAttachDevice(pci) < 0)
|
if (pciReAttachDevice(pci, NULL) < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user