|
|
5c27b6 |
From 5862ba139392fab763092ccffcb109eb8e5b52a9 Mon Sep 17 00:00:00 2001
|
|
|
5c27b6 |
Message-Id: <5862ba139392fab763092ccffcb109eb8e5b52a9@dist-git>
|
|
|
5c27b6 |
From: Laine Stump <laine@laine.org>
|
|
|
5c27b6 |
Date: Thu, 13 Apr 2017 14:29:24 -0400
|
|
|
5c27b6 |
Subject: [PATCH] util: change virPCIGetNetName() to not return error if device
|
|
|
5c27b6 |
has no net name
|
|
|
5c27b6 |
|
|
|
5c27b6 |
...and cleanup the callers to report it when it *is* an error.
|
|
|
5c27b6 |
|
|
|
5c27b6 |
In many cases It's useful for virPCIGetNetName() to not log an error
|
|
|
5c27b6 |
and simply return a NULL pointer when the given device isn't bound to
|
|
|
5c27b6 |
a net driver (e.g. we're looking at a VF that is permanently bound to
|
|
|
5c27b6 |
vfio-pci). The existing code would silently return an error in this
|
|
|
5c27b6 |
case, which could eventually lead to the dreaded "An error occurred
|
|
|
5c27b6 |
but the cause is unknown" log message.
|
|
|
5c27b6 |
|
|
|
5c27b6 |
This patch changes virPCIGetNetName() to still return success if the
|
|
|
5c27b6 |
device simply isn't bound to a net driver, and adjusts all the callers
|
|
|
5c27b6 |
that require a non-null netname to check for that condition and log an
|
|
|
5c27b6 |
error when it happens.
|
|
|
5c27b6 |
|
|
|
5c27b6 |
Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z)
|
|
|
5c27b6 |
Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4)
|
|
|
5c27b6 |
|
|
|
5c27b6 |
(cherry picked from commit d6ee56d723761d408eeef32a96e3c118e0e742c2)
|
|
|
5c27b6 |
---
|
|
|
5c27b6 |
src/util/virhostdev.c | 13 +++++++++++++
|
|
|
5c27b6 |
src/util/virnetdev.c | 19 +++++++++++++++++--
|
|
|
5c27b6 |
src/util/virpci.c | 32 +++++++++++++++++++++++---------
|
|
|
5c27b6 |
3 files changed, 53 insertions(+), 11 deletions(-)
|
|
|
5c27b6 |
|
|
|
5c27b6 |
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
|
|
|
5c27b6 |
index 1e4bb1e7d..93b69501c 100644
|
|
|
5c27b6 |
--- a/src/util/virhostdev.c
|
|
|
5c27b6 |
+++ b/src/util/virhostdev.c
|
|
|
5c27b6 |
@@ -313,8 +313,21 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
|
|
|
5c27b6 |
vf) < 0)
|
|
|
5c27b6 |
goto cleanup;
|
|
|
5c27b6 |
} else {
|
|
|
5c27b6 |
+ /* In practice this should never happen, since we currently
|
|
|
5c27b6 |
+ * only support assigning SRIOV VFs via
|
|
|
5c27b6 |
+ * type='hostdev'>, and it is only those devices that should
|
|
|
5c27b6 |
+ * end up calling this function.
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
if (virPCIGetNetName(sysfs_path, linkdev) < 0)
|
|
|
5c27b6 |
goto cleanup;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ if (!linkdev) {
|
|
|
5c27b6 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
5c27b6 |
+ _("The device at %s has no network device name"),
|
|
|
5c27b6 |
+ sysfs_path);
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+ }
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
*vf = -1;
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
|
|
|
5c27b6 |
index 30a4a01ee..766638dd3 100644
|
|
|
5c27b6 |
--- a/src/util/virnetdev.c
|
|
|
5c27b6 |
+++ b/src/util/virnetdev.c
|
|
|
5c27b6 |
@@ -1162,6 +1162,9 @@ virNetDevGetVirtualFunctions(const char *pfname,
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0)
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ if (!(*vfname)[i])
|
|
|
5c27b6 |
VIR_INFO("VF does not have an interface name");
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
@@ -1258,10 +1261,22 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
|
|
|
5c27b6 |
if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
|
|
|
5c27b6 |
return ret;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
- ret = virPCIGetNetName(physfn_sysfs_path, pfname);
|
|
|
5c27b6 |
+ if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0)
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
+ if (!*pfname) {
|
|
|
5c27b6 |
+ /* this shouldn't be possible. A VF can't exist unless its
|
|
|
5c27b6 |
+ * PF device is bound to a network driver
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
5c27b6 |
+ _("The PF device for VF %s has no network device name"),
|
|
|
5c27b6 |
+ ifname);
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+ }
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ ret = 0;
|
|
|
5c27b6 |
+ cleanup:
|
|
|
5c27b6 |
VIR_FREE(physfn_sysfs_path);
|
|
|
5c27b6 |
-
|
|
|
5c27b6 |
return ret;
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
diff --git a/src/util/virpci.c b/src/util/virpci.c
|
|
|
5c27b6 |
index 132948d32..f6d1e48c7 100644
|
|
|
5c27b6 |
--- a/src/util/virpci.c
|
|
|
5c27b6 |
+++ b/src/util/virpci.c
|
|
|
5c27b6 |
@@ -2683,8 +2683,11 @@ virPCIGetNetName(char *device_link_sysfs_path, char **netname)
|
|
|
5c27b6 |
return -1;
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
- if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0)
|
|
|
5c27b6 |
+ if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) {
|
|
|
5c27b6 |
+ /* this *isn't* an error - caller needs to check for netname == NULL */
|
|
|
5c27b6 |
+ ret = 0;
|
|
|
5c27b6 |
goto out;
|
|
|
5c27b6 |
+ }
|
|
|
5c27b6 |
|
|
|
5c27b6 |
while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
|
|
|
5c27b6 |
/* Assume a single directory entry */
|
|
|
5c27b6 |
@@ -2710,24 +2713,35 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
|
|
|
5c27b6 |
int ret = -1;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
if (virPCIGetPhysicalFunction(vf_sysfs_device_path, &pf_config_address) < 0)
|
|
|
5c27b6 |
- return ret;
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
if (!pf_config_address)
|
|
|
5c27b6 |
- return ret;
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
if (virPCIDeviceAddressGetSysfsFile(pf_config_address,
|
|
|
5c27b6 |
&pf_sysfs_device_path) < 0) {
|
|
|
5c27b6 |
-
|
|
|
5c27b6 |
- VIR_FREE(pf_config_address);
|
|
|
5c27b6 |
- return ret;
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
- if (virPCIGetVirtualFunctionIndex(pf_sysfs_device_path, vf_sysfs_device_path,
|
|
|
5c27b6 |
- vf_index) < 0)
|
|
|
5c27b6 |
+ if (virPCIGetVirtualFunctionIndex(pf_sysfs_device_path,
|
|
|
5c27b6 |
+ vf_sysfs_device_path, vf_index) < 0) {
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+ }
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0)
|
|
|
5c27b6 |
goto cleanup;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
- ret = virPCIGetNetName(pf_sysfs_device_path, pfname);
|
|
|
5c27b6 |
+ if (!*pfname) {
|
|
|
5c27b6 |
+ /* this shouldn't be possible. A VF can't exist unless its
|
|
|
5c27b6 |
+ * PF device is bound to a network driver
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
5c27b6 |
+ _("The PF device for VF %s has no network device name"),
|
|
|
5c27b6 |
+ vf_sysfs_device_path);
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+ }
|
|
|
5c27b6 |
|
|
|
5c27b6 |
+ ret = 0;
|
|
|
5c27b6 |
cleanup:
|
|
|
5c27b6 |
VIR_FREE(pf_config_address);
|
|
|
5c27b6 |
VIR_FREE(pf_sysfs_device_path);
|
|
|
5c27b6 |
--
|
|
|
5c27b6 |
2.12.2
|
|
|
5c27b6 |
|