c034c1a3b2
- Add PCI host device hotplug support - Allow PCI bus reset to reset other devices (#499678) - Fix stupid PCI reset error message (bug #499678) - Allow PM reset on multi-function PCI devices (bug #515689) - Re-attach PCI host devices after guest shuts down (bug #499561) - Fix list corruption after disk hot-unplug - Fix minor 'virsh nodedev-list --tree' annoyance
142 lines
5.1 KiB
Diff
142 lines
5.1 KiB
Diff
From c8a9dbe131713de83bdc67c563c4ab149e32c489 Mon Sep 17 00:00:00 2001
|
|
From: Mark McLoughlin <markmc@redhat.com>
|
|
Date: Fri, 14 Aug 2009 08:31:11 +0100
|
|
Subject: [PATCH] Improve PCI host device reset error message
|
|
|
|
https://bugzilla.redhat.com/499678
|
|
|
|
Currently, if we are unable to reset a PCI device we return a fairly
|
|
generic 'No PCI reset capability available' error message.
|
|
|
|
Fix that by returning an error from the individual reset messages and
|
|
using that error to construct the higher level error mesage.
|
|
|
|
* src/pci.c: set errors in pciTryPowerManagementReset() and
|
|
pciTrySecondaryBusReset() on failure; use those error messages
|
|
in pciResetDevice(), or explain that no reset support is available
|
|
|
|
(cherry picked from commit ebea34185612c3b96d7d3bbd8b7c2ce6c9f4fe6f)
|
|
|
|
Fedora-patch: libvirt-improve-pci-hostdev-reset-error-message.patch
|
|
---
|
|
src/pci.c | 44 +++++++++++++++++++++++++++++++-------------
|
|
src/qemu_driver.c | 4 ++--
|
|
2 files changed, 33 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/src/pci.c b/src/pci.c
|
|
index 11b3e8b..74f7ef0 100644
|
|
--- a/src/pci.c
|
|
+++ b/src/pci.c
|
|
@@ -456,15 +456,18 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
|
* are not in use by the host or other guests.
|
|
*/
|
|
if (pciBusContainsOtherDevices(conn, dev)) {
|
|
- VIR_WARN("Other devices on bus with %s, not doing bus reset",
|
|
- dev->name);
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Other devices on bus with %s, not doing bus reset"),
|
|
+ dev->name);
|
|
return -1;
|
|
}
|
|
|
|
/* Find the parent bus */
|
|
parent = pciGetParentDevice(conn, dev);
|
|
if (!parent) {
|
|
- VIR_WARN("Failed to find parent device for %s", dev->name);
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Failed to find parent device for %s"),
|
|
+ dev->name);
|
|
return -1;
|
|
}
|
|
|
|
@@ -475,7 +478,9 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
|
* are multiple devices/functions
|
|
*/
|
|
if (pciRead(dev, 0, config_space, PCI_CONF_LEN) < 0) {
|
|
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Failed to save PCI config space for %s"),
|
|
+ dev->name);
|
|
goto out;
|
|
}
|
|
|
|
@@ -492,9 +497,12 @@ pciTrySecondaryBusReset(virConnectPtr conn, pciDevice *dev)
|
|
|
|
usleep(200 * 1000); /* sleep 200ms */
|
|
|
|
- if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0)
|
|
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
|
|
-
|
|
+ if (pciWrite(dev, 0, config_space, PCI_CONF_LEN) < 0) {
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Failed to restore PCI config space for %s"),
|
|
+ dev->name);
|
|
+ goto out;
|
|
+ }
|
|
ret = 0;
|
|
out:
|
|
pciFreeDevice(conn, parent);
|
|
@@ -516,7 +524,9 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
|
|
|
/* Save and restore the device's config space. */
|
|
if (pciRead(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
|
|
- VIR_WARN("Failed to save PCI config space for %s", dev->name);
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Failed to save PCI config space for %s"),
|
|
+ dev->name);
|
|
return -1;
|
|
}
|
|
|
|
@@ -533,8 +543,12 @@ pciTryPowerManagementReset(virConnectPtr conn ATTRIBUTE_UNUSED, pciDevice *dev)
|
|
|
|
usleep(10 * 1000); /* sleep 10ms */
|
|
|
|
- if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0)
|
|
- VIR_WARN("Failed to restore PCI config space for %s", dev->name);
|
|
+ if (pciWrite(dev, 0, &config_space[0], PCI_CONF_LEN) < 0) {
|
|
+ pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
+ _("Failed to restore PCI config space for %s"),
|
|
+ dev->name);
|
|
+ return -1;
|
|
+ }
|
|
|
|
return 0;
|
|
}
|
|
@@ -582,10 +596,14 @@ pciResetDevice(virConnectPtr conn, pciDevice *dev)
|
|
if (ret < 0 && dev->bus != 0)
|
|
ret = pciTrySecondaryBusReset(conn, dev);
|
|
|
|
- if (ret < 0)
|
|
+ if (ret < 0) {
|
|
+ virErrorPtr err = virGetLastError();
|
|
pciReportError(conn, VIR_ERR_NO_SUPPORT,
|
|
- _("No PCI reset capability available for %s"),
|
|
- dev->name);
|
|
+ _("Unable to reset PCI device %s: %s"),
|
|
+ dev->name,
|
|
+ err ? err->message : _("no FLR, PM reset or bus reset available"));
|
|
+ }
|
|
+
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
|
|
index 4ce7a54..fd39fc2 100644
|
|
--- a/src/qemu_driver.c
|
|
+++ b/src/qemu_driver.c
|
|
@@ -1465,9 +1465,9 @@ qemuDomainReAttachHostDevices(virConnectPtr conn, virDomainDefPtr def)
|
|
continue;
|
|
}
|
|
|
|
- if (pciDettachDevice(conn, dev) < 0) {
|
|
+ if (pciReAttachDevice(conn, dev) < 0) {
|
|
virErrorPtr err = virGetLastError();
|
|
- VIR_ERROR(_("Failed to reset PCI device: %s\n"),
|
|
+ VIR_ERROR(_("Failed to re-attach PCI device: %s\n"),
|
|
err ? err->message : "");
|
|
virResetError(err);
|
|
}
|
|
--
|
|
1.6.2.5
|
|
|