[Open-FCoE] [PATCH] libhbalinux: use ethtool to get driver name and version

Yi Zou yi.zou at intel.com
Tue Jan 6 00:41:29 UTC 2009


I came across this issue after having my nic driver as built-in, so fix this
by instead of using sys/sys/class/net/%ifname/device/driver/module, changing
to query by ethtool, o.w., if the driver is built-in, the above path in invalid.

also, since this info. is not critical, do not fail the query even if the
driver and version info. is not available, just return w/ dummy info.

Signed-off-by: Yi Zou <yi.zou at intel.com>
---

 src/lport.c |   85 ++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/src/lport.c b/src/lport.c
index 9c47887..0c08318 100644
--- a/src/lport.c
+++ b/src/lport.c
@@ -19,6 +19,12 @@
 #include "utils.h"
 #include "api_lib.h"
 #include "adapt_impl.h"
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+
 
 #ifndef HBA_STATUS_ERROR_ILLEGAL_FCID
 #define HBA_STATUS_ERROR_ILLEGAL_FCID 33	/* defined after HBA-API 2.2 */
@@ -98,6 +104,57 @@ counting_rports(struct dirent *dp, void *arg)
 	return HBA_STATUS_OK;
 }
 
+#define DUMMY_DRVNAME "name: n/a"
+#define DUMMY_DRVVER "version: n/a"
+/*
+ * get_drvinfo - use ethtool get if driver name and version
+ * use this so we can get driver name and version for both module driver or
+ * built-in driver. When this fails, fills the info. w/ dummy string.
+ *
+ * Returns: none
+ */
+static int get_drvinfo(const char *ifname,	HBA_ADAPTERATTRIBUTES *atp)
+{
+	int s;
+	struct ifreq rq;
+	struct ethtool_drvinfo di;
+
+	/* maybe a built-in w/o module info in sysfs, try ethtool */
+	s = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s == -1) {
+		fprintf(stderr, "%s: ioctl(SIOCETHTOOL) failed, errno=0x%x\n",
+				__func__, errno);
+		goto use_dummy;
+	}
+	memset(&di, 0, sizeof(rq));
+	di.cmd = ETHTOOL_GDRVINFO;
+
+	memset(&rq, 0, sizeof(rq));
+	strncpy(rq.ifr_name, ifname, sizeof(rq.ifr_name)-1);
+	rq.ifr_data = (char *) &di;
+
+	if (ioctl(s, SIOCETHTOOL, &rq) == -1) {
+		fprintf(stderr, "%s: socket failed, errno=0x%x\n",
+			__func__, errno);
+		close(s);
+		goto use_dummy;
+	}
+	sa_strncpy_safe(atp->DriverVersion, sizeof(atp->DriverVersion),
+		di.version, sizeof(atp->DriverVersion));
+	sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
+		di.driver, sizeof(atp->DriverName));
+	close(s);
+	return 0;
+
+use_dummy:
+	/* fill dummy info to avoid failing */
+	sa_strncpy_safe(atp->DriverVersion, sizeof(atp->DriverVersion),
+			DUMMY_DRVVER, sizeof(atp->DriverVersion));
+	sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
+			DUMMY_DRVNAME, sizeof(atp->DriverName));
+	return -1;
+}
+
 static int
 sysfs_scan(struct dirent *dp, void *arg)
 {
@@ -108,9 +165,8 @@ sysfs_scan(struct dirent *dp, void *arg)
 	struct hba_info hba_info;
 	struct adapter_info *ap;
 	struct port_info *pp;
-	char host_dir[80], hba_dir[80], drv_dir[80];
+	char host_dir[80], hba_dir[80];
 	char ifname[20], buf[256];
-	char *driverName;
 	int data[32], rc, i;
 
 	/* Found a local port! */
@@ -337,10 +393,6 @@ sysfs_scan(struct dirent *dp, void *arg)
 	/* Get VendorSpecificID (TODO) */
 	atp->VendorSpecificID = HBA_VENDOR_SPECIFIC_ID;
 
-	/* Get DriverVersion */
-	rc = sa_sys_read_line(hba_dir, SYSFS_MODULE_VER,
-			atp->DriverVersion, sizeof(atp->DriverVersion));
-
 	/* Get NodeSymbolicName */
 	sa_strncpy_safe(atp->NodeSymbolicName, sizeof(atp->NodeSymbolicName),
 			ap->ad_name, sizeof(atp->NodeSymbolicName));
@@ -351,25 +403,8 @@ sysfs_scan(struct dirent *dp, void *arg)
 	memcpy((char *)&atp->NodeWWN, (char *)&pap->NodeWWN,
 		sizeof(pap->NodeWWN));
 
-	/* Get DriverName */
-	snprintf(drv_dir, sizeof(drv_dir), "%s" SYSFS_MODULE , hba_dir);
-	i = readlink(drv_dir, buf, sizeof(buf));
-	if (i < 0) {
-		printf("Fatal! readlink %s failed\n", drv_dir);
-		return HBA_STATUS_ERROR;
-	}
-	buf[i] = '\0';
-	if (!strstr(buf, "module")) {
-		/*
-		 * Does not find "module" in the string.
-		 * This should not happen. In this case, set
-		 * the driver name to "Unknown".
-		 */
-		driverName = "Unknown";
-	} else
-		driverName = strstr(buf, "module") + 7;
-	sa_strncpy_safe(atp->DriverName, sizeof(atp->DriverName),
-			driverName, sizeof(atp->DriverName));
+	/* Get DriverName and DriverVersion */
+	get_drvinfo(ifname, atp);
 
 	/*
 	 * Give HBA to library




More information about the devel mailing list