]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: change virPCIGetNetName() to not return error if device has no net name
authorLaine Stump <laine@laine.org>
Fri, 3 Mar 2017 16:54:59 +0000 (11:54 -0500)
committerLaine Stump <laine@laine.org>
Fri, 24 Mar 2017 04:37:19 +0000 (00:37 -0400)
...and cleanup the callers to report it when it *is* an error.

In many cases It's useful for virPCIGetNetName() to not log an error
and simply return a NULL pointer when the given device isn't bound to
a net driver (e.g. we're looking at a VF that is permanently bound to
vfio-pci). The existing code would silently return an error in this
case, which could eventually lead to the dreaded "An error occurred
but the cause is unknown" log message.

This patch changes virPCIGetNetName() to still return success if the
device simply isn't bound to a net driver, and adjusts all the callers
that require a non-null netname to check for that condition and log an
error when it happens.

src/util/virhostdev.c
src/util/virnetdev.c
src/util/virpci.c

index e84a6d608239a01cb38c8d7ff73de54fb6689bf5..faa46aa83aaee8f020ad7f9a421d5d03fbe2cd9d 100644 (file)
@@ -317,8 +317,21 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev, char **linkdev,
                                          vf) < 0)
             goto cleanup;
     } else {
+        /* In practice this should never happen, since we currently
+         * only support assigning SRIOV VFs via <interface
+         * type='hostdev'>, and it is only those devices that should
+         * end up calling this function.
+         */
         if (virPCIGetNetName(sysfs_path, linkdev) < 0)
             goto cleanup;
+
+        if (!linkdev) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("The device at %s has no network device name"),
+                             sysfs_path);
+            goto cleanup;
+        }
+
         *vf = -1;
     }
 
index 05557ad672fac7a97d9458dd09c83921d0f60f1a..ac5200035ad93edfca905fb36f23d8d07086b85a 100644 (file)
@@ -1231,6 +1231,9 @@ virNetDevGetVirtualFunctions(const char *pfname,
         }
 
         if (virPCIGetNetName(pci_sysfs_device_link, &((*vfname)[i])) < 0)
+            goto cleanup;
+
+        if (!(*vfname)[i])
             VIR_INFO("VF does not have an interface name");
     }
 
@@ -1327,10 +1330,22 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     if (virNetDevSysfsDeviceFile(&physfn_sysfs_path, ifname, "physfn") < 0)
         return ret;
 
-    ret = virPCIGetNetName(physfn_sysfs_path, pfname);
+    if (virPCIGetNetName(physfn_sysfs_path, pfname) < 0)
+        goto cleanup;
 
-    VIR_FREE(physfn_sysfs_path);
+    if (!*pfname) {
+        /* this shouldn't be possible. A VF can't exist unless its
+         * PF device is bound to a network driver
+         */
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("The PF device for VF %s has no network device name"),
+                       ifname);
+        goto cleanup;
+    }
 
+    ret = 0;
+ cleanup:
+    VIR_FREE(physfn_sysfs_path);
     return ret;
 }
 
index 3c1e13b6a5a4218b7ad1fe87d20bf227fc921b41..337afdab51c3e328b966e1cd945209f0a546fcf6 100644 (file)
@@ -2854,8 +2854,11 @@ virPCIGetNetName(char *device_link_sysfs_path, char **netname)
         return -1;
     }
 
-    if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0)
+    if (virDirOpenQuiet(&dir, pcidev_sysfs_net_path) < 0) {
+        /* this *isn't* an error - caller needs to check for netname == NULL */
+        ret = 0;
         goto out;
+    }
 
     while (virDirRead(dir, &entry, pcidev_sysfs_net_path) > 0) {
         /* Assume a single directory entry */
@@ -2881,24 +2884,35 @@ virPCIGetVirtualFunctionInfo(const char *vf_sysfs_device_path,
     int ret = -1;
 
     if (virPCIGetPhysicalFunction(vf_sysfs_device_path, &pf_config_address) < 0)
-        return ret;
+        goto cleanup;
 
     if (!pf_config_address)
-        return ret;
+        goto cleanup;
 
     if (virPCIDeviceAddressGetSysfsFile(pf_config_address,
                                         &pf_sysfs_device_path) < 0) {
+        goto cleanup;
+    }
 
-        VIR_FREE(pf_config_address);
-        return ret;
+    if (virPCIGetVirtualFunctionIndex(pf_sysfs_device_path,
+                                      vf_sysfs_device_path, vf_index) < 0) {
+        goto cleanup;
     }
 
-    if (virPCIGetVirtualFunctionIndex(pf_sysfs_device_path, vf_sysfs_device_path,
-                                      vf_index) < 0)
+    if (virPCIGetNetName(pf_sysfs_device_path, pfname) < 0)
         goto cleanup;
 
-    ret = virPCIGetNetName(pf_sysfs_device_path, pfname);
+    if (!*pfname) {
+        /* this shouldn't be possible. A VF can't exist unless its
+         * PF device is bound to a network driver
+         */
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("The PF device for VF %s has no network device name"),
+                       vf_sysfs_device_path);
+        goto cleanup;
+    }
 
+    ret = 0;
  cleanup:
     VIR_FREE(pf_config_address);
     VIR_FREE(pf_sysfs_device_path);