mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-13 08:05:16 +00:00
pci: Fix failure paths in detach
https://bugzilla.redhat.com/show_bug.cgi?id=1046919 Since commit v0.9.0-47-g4e8969e (released in 0.9.1) some failures during device detach were reported to callers of virPCIDeviceBindToStub as success. For example, even though a device seemed to be detached virsh # nodedev-detach pci_0000_07_05_0 --driver vfio Device pci_0000_07_05_0 detached one could find similar message in libvirt logs: Failed to bind PCI device '0000:07:05.0' to vfio-pci: No such device This patch fixes these paths and also avoids overwriting real errors with errors encountered during a cleanup phase.
This commit is contained in:
parent
c982e5e84f
commit
d8ab981bdd
@ -1123,14 +1123,15 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|||||||
{
|
{
|
||||||
int result = -1;
|
int result = -1;
|
||||||
int reprobe = false;
|
int reprobe = false;
|
||||||
|
|
||||||
char *stubDriverPath = NULL;
|
char *stubDriverPath = NULL;
|
||||||
char *driverLink = NULL;
|
char *driverLink = NULL;
|
||||||
char *path = NULL; /* reused for different purposes */
|
char *path = NULL; /* reused for different purposes */
|
||||||
const char *newDriverName = NULL;
|
char *newDriverName = NULL;
|
||||||
|
virErrorPtr err = NULL;
|
||||||
|
|
||||||
if (virPCIDriverDir(&stubDriverPath, stubDriverName) < 0 ||
|
if (virPCIDriverDir(&stubDriverPath, stubDriverName) < 0 ||
|
||||||
virPCIFile(&driverLink, dev->name, "driver") < 0)
|
virPCIFile(&driverLink, dev->name, "driver") < 0 ||
|
||||||
|
VIR_STRDUP(newDriverName, stubDriverName) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virFileExists(driverLink)) {
|
if (virFileExists(driverLink)) {
|
||||||
@ -1138,7 +1139,6 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|||||||
/* The device is already bound to the correct driver */
|
/* The device is already bound to the correct driver */
|
||||||
VIR_DEBUG("Device %s is already bound to %s",
|
VIR_DEBUG("Device %s is already bound to %s",
|
||||||
dev->name, stubDriverName);
|
dev->name, stubDriverName);
|
||||||
newDriverName = stubDriverName;
|
|
||||||
result = 0;
|
result = 0;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -1170,6 +1170,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|||||||
if (virFileLinkPointsTo(driverLink, stubDriverPath)) {
|
if (virFileLinkPointsTo(driverLink, stubDriverPath)) {
|
||||||
dev->unbind_from_stub = true;
|
dev->unbind_from_stub = true;
|
||||||
dev->remove_slot = true;
|
dev->remove_slot = true;
|
||||||
|
result = 0;
|
||||||
goto remove_id;
|
goto remove_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1178,16 +1179,15 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|||||||
* PCI device happens to be IDE controller for the disk hosting
|
* PCI device happens to be IDE controller for the disk hosting
|
||||||
* your root filesystem.
|
* your root filesystem.
|
||||||
*/
|
*/
|
||||||
if (virPCIFile(&path, dev->name, "driver/unbind") < 0) {
|
if (virPCIFile(&path, dev->name, "driver/unbind") < 0)
|
||||||
goto cleanup;
|
goto remove_id;
|
||||||
}
|
|
||||||
|
|
||||||
if (virFileExists(path)) {
|
if (virFileExists(path)) {
|
||||||
if (virFileWriteStr(path, dev->name, 0) < 0) {
|
if (virFileWriteStr(path, dev->name, 0) < 0) {
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
_("Failed to unbind PCI device '%s'"),
|
_("Failed to unbind PCI device '%s'"),
|
||||||
dev->name);
|
dev->name);
|
||||||
goto cleanup;
|
goto remove_id;
|
||||||
}
|
}
|
||||||
dev->reprobe = reprobe;
|
dev->reprobe = reprobe;
|
||||||
}
|
}
|
||||||
@ -1222,7 +1222,11 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|||||||
dev->unbind_from_stub = true;
|
dev->unbind_from_stub = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
remove_id:
|
remove_id:
|
||||||
|
err = virSaveLastError();
|
||||||
|
|
||||||
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
|
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
|
||||||
* ID table so that 'drivers_probe' works below.
|
* ID table so that 'drivers_probe' works below.
|
||||||
*/
|
*/
|
||||||
@ -1233,6 +1237,7 @@ remove_id:
|
|||||||
"cannot be probed again.", dev->id, stubDriverName);
|
"cannot be probed again.", dev->id, stubDriverName);
|
||||||
}
|
}
|
||||||
dev->reprobe = false;
|
dev->reprobe = false;
|
||||||
|
result = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1247,24 +1252,26 @@ remove_id:
|
|||||||
"cannot be probed again.", dev->id, stubDriverName);
|
"cannot be probed again.", dev->id, stubDriverName);
|
||||||
}
|
}
|
||||||
dev->reprobe = false;
|
dev->reprobe = false;
|
||||||
|
result = -1;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
newDriverName = stubDriverName;
|
|
||||||
result = 0;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(stubDriverPath);
|
VIR_FREE(stubDriverPath);
|
||||||
VIR_FREE(driverLink);
|
VIR_FREE(driverLink);
|
||||||
VIR_FREE(path);
|
VIR_FREE(path);
|
||||||
|
|
||||||
if (newDriverName &&
|
if (result < 0) {
|
||||||
STRNEQ_NULLABLE(dev->stubDriver, newDriverName)) {
|
VIR_FREE(newDriverName);
|
||||||
VIR_FREE(dev->stubDriver);
|
|
||||||
result = VIR_STRDUP(dev->stubDriver, newDriverName);
|
|
||||||
}
|
|
||||||
if (result < 0)
|
|
||||||
virPCIDeviceUnbindFromStub(dev);
|
virPCIDeviceUnbindFromStub(dev);
|
||||||
|
} else {
|
||||||
|
VIR_FREE(dev->stubDriver);
|
||||||
|
dev->stubDriver = newDriverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
virSetError(err);
|
||||||
|
virFreeError(err);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user