|
|
5c27b6 |
From 2a8115ab21d5efa526e982ea825b42037fc163eb Mon Sep 17 00:00:00 2001
|
|
|
5c27b6 |
Message-Id: <2a8115ab21d5efa526e982ea825b42037fc163eb@dist-git>
|
|
|
5c27b6 |
From: Laine Stump <laine@laine.org>
|
|
|
5c27b6 |
Date: Thu, 13 Apr 2017 14:29:28 -0400
|
|
|
5c27b6 |
Subject: [PATCH] util: new function virNetDevPFGetVF()
|
|
|
5c27b6 |
|
|
|
5c27b6 |
Given an SRIOV PF netdev name (e.g. "enp2s0f0") and VF#, this new
|
|
|
5c27b6 |
function returns the netdev name of the referenced VF device
|
|
|
5c27b6 |
(e.g. "enp2s11f6"), or NULL if the device isn't bound to a net driver.
|
|
|
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 554253ad04463e0442030f4630f0a4a02613a595)
|
|
|
5c27b6 |
---
|
|
|
5c27b6 |
src/libvirt_private.syms | 1 +
|
|
|
5c27b6 |
src/util/virnetdev.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
5c27b6 |
src/util/virnetdev.h | 3 +++
|
|
|
5c27b6 |
3 files changed, 65 insertions(+)
|
|
|
5c27b6 |
|
|
|
5c27b6 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
5c27b6 |
index b9e85449b..f91703f2e 100644
|
|
|
5c27b6 |
--- a/src/libvirt_private.syms
|
|
|
5c27b6 |
+++ b/src/libvirt_private.syms
|
|
|
5c27b6 |
@@ -1899,6 +1899,7 @@ virNetDevGetVLanID;
|
|
|
5c27b6 |
virNetDevIfStateTypeFromString;
|
|
|
5c27b6 |
virNetDevIfStateTypeToString;
|
|
|
5c27b6 |
virNetDevIsVirtualFunction;
|
|
|
5c27b6 |
+virNetDevPFGetVF;
|
|
|
5c27b6 |
virNetDevReplaceMacAddress;
|
|
|
5c27b6 |
virNetDevReplaceNetConfig;
|
|
|
5c27b6 |
virNetDevRestoreMacAddress;
|
|
|
5c27b6 |
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
|
|
|
5c27b6 |
index ffc2fb4e4..807b67697 100644
|
|
|
5c27b6 |
--- a/src/util/virnetdev.c
|
|
|
5c27b6 |
+++ b/src/util/virnetdev.c
|
|
|
5c27b6 |
@@ -1311,6 +1311,57 @@ virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
|
|
|
5c27b6 |
return ret;
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+/**
|
|
|
5c27b6 |
+ * virNetDevPFGetVF:
|
|
|
5c27b6 |
+ *
|
|
|
5c27b6 |
+ * @pfname: netdev name of the physical function (PF)
|
|
|
5c27b6 |
+ * @vf: virtual function (VF) number for the device of interest
|
|
|
5c27b6 |
+ * @vfname: name of the physical function interface name
|
|
|
5c27b6 |
+ *
|
|
|
5c27b6 |
+ * Finds the netdev name of VF# @vf of SRIOV PF @pfname, and puts it
|
|
|
5c27b6 |
+ * in @vfname. The caller must free @vfname when it's finished with
|
|
|
5c27b6 |
+ * it.
|
|
|
5c27b6 |
+ *
|
|
|
5c27b6 |
+ * Returns 0 on success, -1 on failure
|
|
|
5c27b6 |
+ *
|
|
|
5c27b6 |
+ * NB: if the VF has no netdev name, that is *not* considered an
|
|
|
5c27b6 |
+ * error; *vfname simply gets a NULL and the return value is 0
|
|
|
5c27b6 |
+ * (success).
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
+int
|
|
|
5c27b6 |
+virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
|
|
|
5c27b6 |
+{
|
|
|
5c27b6 |
+ char *virtfnName = NULL;
|
|
|
5c27b6 |
+ char *virtfnSysfsPath = NULL;
|
|
|
5c27b6 |
+ int ret = -1;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ if (virAsprintf(&virtfnName, "virtfn%d", vf) < 0)
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ /* this provides the path to the VF's directory in sysfs,
|
|
|
5c27b6 |
+ * e.g. "/sys/class/net/enp2s0f0/virtfn3"
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
+ if (virNetDevSysfsDeviceFile(&virtfnSysfsPath, pfname, virtfnName) < 0)
|
|
|
5c27b6 |
+ goto cleanup;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ /* and this gets the netdev name associated with it, which is a
|
|
|
5c27b6 |
+ * directory entry in [virtfnSysfsPath]/net,
|
|
|
5c27b6 |
+ * e.g. "/sys/class/net/enp2s0f0/virtfn3/net/enp2s11f4" - in this
|
|
|
5c27b6 |
+ * example the VF for enp2s0f0 vf#3 is "enp2s11f4". (If the VF
|
|
|
5c27b6 |
+ * isn't bound to a netdev driver, it won't have a netdev name,
|
|
|
5c27b6 |
+ * and vfname will be NULL).
|
|
|
5c27b6 |
+ */
|
|
|
5c27b6 |
+ ret = virPCIGetNetName(virtfnSysfsPath, vfname);
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ cleanup:
|
|
|
5c27b6 |
+ VIR_FREE(virtfnName);
|
|
|
5c27b6 |
+ VIR_FREE(virtfnSysfsPath);
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+ return ret;
|
|
|
5c27b6 |
+}
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
/**
|
|
|
5c27b6 |
* virNetDevGetVirtualFunctionInfo:
|
|
|
5c27b6 |
* @vfname: name of the virtual function interface
|
|
|
5c27b6 |
@@ -1391,6 +1442,16 @@ virNetDevGetPhysicalFunction(const char *ifname ATTRIBUTE_UNUSED,
|
|
|
5c27b6 |
}
|
|
|
5c27b6 |
|
|
|
5c27b6 |
int
|
|
|
5c27b6 |
+virNetDevPFGetVF(const char *pfname ATTRIBUTE_UNUSED,
|
|
|
5c27b6 |
+ int vf ATTRIBUTE_UNUSED,
|
|
|
5c27b6 |
+ char **vfname ATTRUBUTE_UNUSED)
|
|
|
5c27b6 |
+{
|
|
|
5c27b6 |
+ virReportSystemError(ENOSYS, "%s",
|
|
|
5c27b6 |
+ _("Unable to get virtual function name on this platform"));
|
|
|
5c27b6 |
+ return -1;
|
|
|
5c27b6 |
+}
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
+int
|
|
|
5c27b6 |
virNetDevGetVirtualFunctionInfo(const char *vfname ATTRIBUTE_UNUSED,
|
|
|
5c27b6 |
char **pfname ATTRIBUTE_UNUSED,
|
|
|
5c27b6 |
int *vf ATTRIBUTE_UNUSED)
|
|
|
5c27b6 |
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
|
|
|
5c27b6 |
index c3e8ffce9..d534a3946 100644
|
|
|
5c27b6 |
--- a/src/util/virnetdev.h
|
|
|
5c27b6 |
+++ b/src/util/virnetdev.h
|
|
|
5c27b6 |
@@ -176,6 +176,9 @@ int virNetDevGetVirtualFunctionIndex(const char *pfname, const char *vfname,
|
|
|
5c27b6 |
int virNetDevGetPhysicalFunction(const char *ifname, char **pfname)
|
|
|
5c27b6 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
|
|
|
5c27b6 |
|
|
|
5c27b6 |
+int virNetDevPFGetVF(const char *pfname, int vf, char **vfname)
|
|
|
5c27b6 |
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
|
|
5c27b6 |
+
|
|
|
5c27b6 |
int virNetDevGetVirtualFunctions(const char *pfname,
|
|
|
5c27b6 |
char ***vfname,
|
|
|
5c27b6 |
virPCIDeviceAddressPtr **virt_fns,
|
|
|
5c27b6 |
--
|
|
|
5c27b6 |
2.12.2
|
|
|
5c27b6 |
|