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