|
|
c401cc |
From c5a1547cc5aa9fed95f2bb48d9dcb4c659e640d1 Mon Sep 17 00:00:00 2001
|
|
|
c401cc |
Message-Id: <c5a1547cc5aa9fed95f2bb48d9dcb4c659e640d1.1390394206.git.jdenemar@redhat.com>
|
|
|
c401cc |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
Date: Mon, 20 Jan 2014 14:41:12 +0100
|
|
|
c401cc |
Subject: [PATCH] pci: Fix failure paths in detach
|
|
|
c401cc |
|
|
|
c401cc |
https://bugzilla.redhat.com/show_bug.cgi?id=1046919
|
|
|
c401cc |
|
|
|
c401cc |
Since commit v0.9.0-47-g4e8969e (released in 0.9.1) some failures during
|
|
|
c401cc |
device detach were reported to callers of virPCIDeviceBindToStub as
|
|
|
c401cc |
success. For example, even though a device seemed to be detached
|
|
|
c401cc |
|
|
|
c401cc |
virsh # nodedev-detach pci_0000_07_05_0 --driver vfio
|
|
|
c401cc |
Device pci_0000_07_05_0 detached
|
|
|
c401cc |
|
|
|
c401cc |
one could find similar message in libvirt logs:
|
|
|
c401cc |
|
|
|
c401cc |
Failed to bind PCI device '0000:07:05.0' to vfio-pci: No such device
|
|
|
c401cc |
|
|
|
c401cc |
This patch fixes these paths and also avoids overwriting real errors
|
|
|
c401cc |
with errors encountered during a cleanup phase.
|
|
|
c401cc |
|
|
|
c401cc |
(cherry picked from commit d8ab981bdd137f15675ee0d101abeabf42680cc1)
|
|
|
c401cc |
|
|
|
c401cc |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
c401cc |
---
|
|
|
c401cc |
src/util/virpci.c | 39 +++++++++++++++++++++++----------------
|
|
|
c401cc |
1 file changed, 23 insertions(+), 16 deletions(-)
|
|
|
c401cc |
|
|
|
c401cc |
diff --git a/src/util/virpci.c b/src/util/virpci.c
|
|
|
c401cc |
index b48e433..f689961 100644
|
|
|
c401cc |
--- a/src/util/virpci.c
|
|
|
c401cc |
+++ b/src/util/virpci.c
|
|
|
c401cc |
@@ -1091,16 +1091,17 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|
|
c401cc |
{
|
|
|
c401cc |
int result = -1;
|
|
|
c401cc |
int reprobe = false;
|
|
|
c401cc |
-
|
|
|
c401cc |
char *stubDriverPath = NULL;
|
|
|
c401cc |
char *driverLink = NULL;
|
|
|
c401cc |
char *oldDriverPath = NULL;
|
|
|
c401cc |
char *oldDriverName = NULL;
|
|
|
c401cc |
char *path = NULL; /* reused for different purposes */
|
|
|
c401cc |
- const char *newDriverName = NULL;
|
|
|
c401cc |
+ char *newDriverName = NULL;
|
|
|
c401cc |
+ virErrorPtr err = NULL;
|
|
|
c401cc |
|
|
|
c401cc |
if (virPCIDriverDir(&stubDriverPath, stubDriverName) < 0 ||
|
|
|
c401cc |
- virPCIFile(&driverLink, dev->name, "driver") < 0)
|
|
|
c401cc |
+ virPCIFile(&driverLink, dev->name, "driver") < 0 ||
|
|
|
c401cc |
+ VIR_STRDUP(newDriverName, stubDriverName) < 0)
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
|
|
|
c401cc |
if (virFileExists(driverLink)) {
|
|
|
c401cc |
@@ -1108,7 +1109,6 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|
|
c401cc |
/* The device is already bound to the correct driver */
|
|
|
c401cc |
VIR_DEBUG("Device %s is already bound to %s",
|
|
|
c401cc |
dev->name, stubDriverName);
|
|
|
c401cc |
- newDriverName = stubDriverName;
|
|
|
c401cc |
result = 0;
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
}
|
|
|
c401cc |
@@ -1140,6 +1140,7 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|
|
c401cc |
if (virFileLinkPointsTo(driverLink, stubDriverPath)) {
|
|
|
c401cc |
dev->unbind_from_stub = true;
|
|
|
c401cc |
dev->remove_slot = true;
|
|
|
c401cc |
+ result = 0;
|
|
|
c401cc |
goto remove_id;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1148,16 +1149,15 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|
|
c401cc |
* PCI device happens to be IDE controller for the disk hosting
|
|
|
c401cc |
* your root filesystem.
|
|
|
c401cc |
*/
|
|
|
c401cc |
- if (virPCIFile(&path, dev->name, "driver/unbind") < 0) {
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
- }
|
|
|
c401cc |
+ if (virPCIFile(&path, dev->name, "driver/unbind") < 0)
|
|
|
c401cc |
+ goto remove_id;
|
|
|
c401cc |
|
|
|
c401cc |
if (virFileExists(path)) {
|
|
|
c401cc |
if (virFileWriteStr(path, dev->name, 0) < 0) {
|
|
|
c401cc |
virReportSystemError(errno,
|
|
|
c401cc |
_("Failed to unbind PCI device '%s'"),
|
|
|
c401cc |
dev->name);
|
|
|
c401cc |
- goto cleanup;
|
|
|
c401cc |
+ goto remove_id;
|
|
|
c401cc |
}
|
|
|
c401cc |
dev->reprobe = reprobe;
|
|
|
c401cc |
}
|
|
|
c401cc |
@@ -1192,7 +1192,11 @@ virPCIDeviceBindToStub(virPCIDevicePtr dev,
|
|
|
c401cc |
dev->unbind_from_stub = true;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
+ result = 0;
|
|
|
c401cc |
+
|
|
|
c401cc |
remove_id:
|
|
|
c401cc |
+ err = virSaveLastError();
|
|
|
c401cc |
+
|
|
|
c401cc |
/* If 'remove_id' exists, remove the device id from pci-stub's dynamic
|
|
|
c401cc |
* ID table so that 'drivers_probe' works below.
|
|
|
c401cc |
*/
|
|
|
c401cc |
@@ -1203,6 +1207,7 @@ remove_id:
|
|
|
c401cc |
"cannot be probed again.", dev->id, stubDriverName);
|
|
|
c401cc |
}
|
|
|
c401cc |
dev->reprobe = false;
|
|
|
c401cc |
+ result = -1;
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
@@ -1217,12 +1222,10 @@ remove_id:
|
|
|
c401cc |
"cannot be probed again.", dev->id, stubDriverName);
|
|
|
c401cc |
}
|
|
|
c401cc |
dev->reprobe = false;
|
|
|
c401cc |
+ result = -1;
|
|
|
c401cc |
goto cleanup;
|
|
|
c401cc |
}
|
|
|
c401cc |
|
|
|
c401cc |
- newDriverName = stubDriverName;
|
|
|
c401cc |
- result = 0;
|
|
|
c401cc |
-
|
|
|
c401cc |
cleanup:
|
|
|
c401cc |
VIR_FREE(stubDriverPath);
|
|
|
c401cc |
VIR_FREE(driverLink);
|
|
|
c401cc |
@@ -1230,13 +1233,17 @@ cleanup:
|
|
|
c401cc |
VIR_FREE(oldDriverName);
|
|
|
c401cc |
VIR_FREE(path);
|
|
|
c401cc |
|
|
|
c401cc |
- if (newDriverName &&
|
|
|
c401cc |
- STRNEQ_NULLABLE(dev->stubDriver, newDriverName)) {
|
|
|
c401cc |
+ if (result < 0) {
|
|
|
c401cc |
+ VIR_FREE(newDriverName);
|
|
|
c401cc |
+ virPCIDeviceUnbindFromStub(dev);
|
|
|
c401cc |
+ } else {
|
|
|
c401cc |
VIR_FREE(dev->stubDriver);
|
|
|
c401cc |
- result = VIR_STRDUP(dev->stubDriver, newDriverName);
|
|
|
c401cc |
+ dev->stubDriver = newDriverName;
|
|
|
c401cc |
}
|
|
|
c401cc |
- if (result < 0)
|
|
|
c401cc |
- virPCIDeviceUnbindFromStub(dev);
|
|
|
c401cc |
+
|
|
|
c401cc |
+ if (err)
|
|
|
c401cc |
+ virSetError(err);
|
|
|
c401cc |
+ virFreeError(err);
|
|
|
c401cc |
|
|
|
c401cc |
return result;
|
|
|
c401cc |
}
|
|
|
c401cc |
--
|
|
|
c401cc |
1.8.5.3
|
|
|
c401cc |
|