]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: new function virNetDevPFGetVF()
authorLaine Stump <laine@laine.org>
Thu, 2 Mar 2017 19:55:01 +0000 (14:55 -0500)
committerLaine Stump <laine@laine.org>
Fri, 24 Mar 2017 04:39:31 +0000 (00:39 -0400)
Given an SRIOV PF netdev name (e.g. "enp2s0f0") and VF#, this new
function returns the netdev name of the referenced VF device
(e.g. "enp2s11f6"), or NULL if the device isn't bound to a net driver.

src/libvirt_private.syms
src/util/virnetdev.c
src/util/virnetdev.h

index 77f03d966775745c87a7f2b556ae885df2e48a8f..e99bdb0289debab7d3e6777ce4d58fb95aaf5ee9 100644 (file)
@@ -2010,6 +2010,7 @@ virNetDevGetVLanID;
 virNetDevIfStateTypeFromString;
 virNetDevIfStateTypeToString;
 virNetDevIsVirtualFunction;
+virNetDevPFGetVF;
 virNetDevReplaceMacAddress;
 virNetDevReplaceNetConfig;
 virNetDevRestoreMacAddress;
index ddc723fc2939eda61a9c074e868724ada2c769e8..b9e9cbe54cb00492035b112afd9d932bb22a311d 100644 (file)
@@ -1380,6 +1380,57 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     return ret;
 }
 
+
+/**
+ * virNetDevPFGetVF:
+ *
+ * @pfname: netdev name of the physical function (PF)
+ * @vf: virtual function (VF) number for the device of interest
+ * @vfname: name of the physical function interface name
+ *
+ * Finds the netdev name of VF# @vf of SRIOV PF @pfname, and puts it
+ * in @vfname. The caller must free @vfname when it's finished with
+ * it.
+ *
+ * Returns 0 on success, -1 on failure
+ *
+ * NB: if the VF has no netdev name, that is *not* considered an
+ * error; *vfname simply gets a NULL and the return value is 0
+ * (success).
+ */
+int
+virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
+{
+    char *virtfnName = NULL;
+    char *virtfnSysfsPath = NULL;
+    int ret = -1;
+
+    if (virAsprintf(&virtfnName, "virtfn%d", vf) < 0)
+        goto cleanup;
+
+    /* this provides the path to the VF's directory in sysfs,
+     * e.g. "/sys/class/net/enp2s0f0/virtfn3"
+     */
+    if (virNetDevSysfsDeviceFile(&virtfnSysfsPath, pfname, virtfnName) < 0)
+        goto cleanup;
+
+    /* and this gets the netdev name associated with it, which is a
+     * directory entry in [virtfnSysfsPath]/net,
+     * e.g. "/sys/class/net/enp2s0f0/virtfn3/net/enp2s11f4" - in this
+     * example the VF for enp2s0f0 vf#3 is "enp2s11f4". (If the VF
+     * isn't bound to a netdev driver, it won't have a netdev name,
+     * and vfname will be NULL).
+     */
+    ret = virPCIGetNetName(virtfnSysfsPath, vfname);
+
+ cleanup:
+    VIR_FREE(virtfnName);
+    VIR_FREE(virtfnSysfsPath);
+
+    return ret;
+}
+
+
 /**
  * virNetDevGetVirtualFunctionInfo:
  * @vfname: name of the virtual function interface
@@ -1459,6 +1510,16 @@ virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED,
     return -1;
 }
 
+int
+virNetDevPFGetVF(const char *pfname ATTRIBUTE_UNUSED,
+                 int vf ATTRIBUTE_UNUSED,
+                 char **vfname ATTRUBUTE_UNUSED)
+{
+    virReportSystemError(ENOSYS, "%s",
+                         _("Unable to get virtual function name on this platform"));
+    return -1;
+}
+
 int
 virNetDevGetVirtualFunctionInfo(const char *vfname ATTRIBUTE_UNUSED,
                                 char **pfname ATTRIBUTE_UNUSED,
index 104e00a28e83967ec5397ddd5e096a21ab76d99a..01f6d8b2321236ecb7efc97a6a938e997d1cd469 100644 (file)
@@ -183,6 +183,9 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
 int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
 
+int virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
 int virNetDevGetVirtualFunctions(const char *pfname,
                                  char ***vfname,
                                  virPCIDeviceAddressPtr **virt_fns,