Blame SOURCES/libvirt-util-change-virPCIGetNetName-to-not-return-error-if-device-has-no-net-name.patch

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