From 2a8115ab21d5efa526e982ea825b42037fc163eb Mon Sep 17 00:00:00 2001 Message-Id: <2a8115ab21d5efa526e982ea825b42037fc163eb@dist-git> From: Laine Stump Date: Thu, 13 Apr 2017 14:29:28 -0400 Subject: [PATCH] util: new function virNetDevPFGetVF() 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. Resolves: https://bugzilla.redhat.com/1442040 (RHEL 7.3.z) Resolves: https://bugzilla.redhat.com/1415609 (RHEL 7.4) (cherry picked from commit 554253ad04463e0442030f4630f0a4a02613a595) --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ src/util/virnetdev.h | 3 +++ 3 files changed, 65 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b9e85449b..f91703f2e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1899,6 +1899,7 @@ virNetDevGetVLanID; virNetDevIfStateTypeFromString; virNetDevIfStateTypeToString; virNetDevIsVirtualFunction; +virNetDevPFGetVF; virNetDevReplaceMacAddress; virNetDevReplaceNetConfig; virNetDevRestoreMacAddress; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index ffc2fb4e4..807b67697 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -1311,6 +1311,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 @@ -1391,6 +1442,16 @@ virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED, } 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, int *vf ATTRIBUTE_UNUSED) diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index c3e8ffce9..d534a3946 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -176,6 +176,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, -- 2.12.2