[openib-general] [PATCH 2/2] Wean libehca off of libsysfs

Roland Dreier rdreier at cisco.com
Thu Apr 20 12:13:28 PDT 2006


As discussed in <http://thread.gmane.org/gmane.linux.drivers.openib/24250>
I would like to start moving the libibverbs interface to lower-level
drivers away from using libsysfs data structures.

This patch implements that scheme for libehca, and adds an
ibv_driver_init() entry point in a backwards compatible way: it will
work with existing releases of libibverbs 1.0, and should be source
compatible with libibverbs 1.1.

Compile tested only, as I don't have ehca hardware (yet...).  Please
test and apply if it looks good to you.

Signed-off-by: Roland Dreier <rolandd at cisco.com>

--- src/userspace/libehca/configure.in	(revision 6541)
+++ src/userspace/libehca/configure.in	(working copy)
@@ -16,6 +16,9 @@ AC_CHECK_LIB(ibverbs, 
              [], 
              AC_MSG_ERROR([libibverbs not installed]))
 
+dnl Checks for library functions
+AC_CHECK_FUNCS(ibv_read_sysfs_file)
+
 dnl Checks for programs.
 AC_PROG_CC
 AC_OUTPUT([Makefile])
--- src/userspace/libehca/src/ehca_uinit.c	(revision 6541)
+++ src/userspace/libehca/src/ehca_uinit.c	(working copy)
@@ -38,12 +38,19 @@
  *  $Id: ehca_uinit.c,v 1.6 2006/04/11 13:45:31 nguyen Exp $
  */
 
+#if HAVE_CONFIG_H
+#  include <config.h>
+#endif /* HAVE_CONFIG_H */
+
 #include <infiniband/driver.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <sys/mman.h>
 #include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "ehca_uclasses.h"
 
@@ -144,42 +151,58 @@ static struct ibv_device_ops ehcau_dev_o
 	.free_context = ehcau_free_context
 };
 
-struct ibv_device *openib_driver_init(struct sysfs_class_device *sysdev)
+/*
+ * Keep a private implementation of HAVE_IBV_READ_SYSFS_FILE to handle
+ * old versions of libibverbs that didn't implement it.  This can be
+ * removed when libibverbs 1.0.3 or newer is available "everywhere."
+ */
+#ifndef HAVE_IBV_READ_SYSFS_FILE
+static int ibv_read_sysfs_file(const char *dir, const char *file,
+			       char *buf, size_t size)
+{
+	char path[256];
+	int fd;
+	int len;
+
+	snprintf(path, sizeof path, "%s/%s", dir, file);
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	len = read(fd, buf, size);
+
+	close(fd);
+
+	if (len > 0 && buf[len - 1] == '\n')
+		buf[--len] = '\0';
+
+	return len;
+}
+#endif /* HAVE_IBV_READ_SYSFS_FILE */
+
+struct ibv_device *ibv_driver_init(const char *uverbs_sys_path,
+				   int abi_version)
 {
 	struct ehcau_device *my_dev = NULL;
-	struct sysfs_device *sysfs_dev = NULL;
-	struct sysfs_attribute *sysfs_attr = NULL;
-	char *dev_name = NULL;
+	char value[64];
 	int num_ports = 0;
 
 	EDEB_EN(7, "");
 
-	/* check devices existence */
-	sysfs_dev = sysfs_get_classdev_device(sysdev);
-	if (sysfs_dev == NULL) {
-		return NULL;
-	}
 
-	sysfs_attr = sysfs_get_device_attr(sysfs_dev, "name");
-	if (sysfs_attr == NULL) {
+	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
+				value, sizeof value) < 0)
 		return NULL;
-	}
-	if (asprintf(&dev_name, "%s", sysfs_attr->value)<0) {
-		return NULL;
-	}
-	sysfs_close_attribute(sysfs_attr);
-	if (strcmp("lhca", str_strip(dev_name)) != 0) {
-		free(dev_name);
+
+	if (strcmp("lhca", str_strip(value)) != 0)
 		return NULL;
-	}
-	free(dev_name);
 
-	sysfs_attr = sysfs_get_device_attr(sysfs_dev, "num_ports");
-	if (sysfs_attr == NULL) {
+	if (ibv_read_sysfs_file(uverbs_sys_path, "device/num_ports",
+				value, sizeof value) < 0)
 		return NULL;
-	}
-	sscanf(sysfs_attr->value, "%i", &num_ports);
-	sysfs_close_attribute(sysfs_attr);
+
+	sscanf(value, "%i", &num_ports);
 	if (num_ports<1) {
 		return NULL;
 	}
@@ -188,7 +211,7 @@ struct ibv_device *openib_driver_init(st
 	my_dev = malloc(sizeof *my_dev);
 	if (!my_dev) {
 		fprintf(stderr, "Fatal: couldn't allocate device for %s\n",
-			sysdev->name);
+			uverbs_sys_path);
 		abort();
 	}
 
@@ -198,6 +221,18 @@ struct ibv_device *openib_driver_init(st
 	return &my_dev->ibv_dev;
 }
 
+struct ibv_device *openib_driver_init(struct sysfs_class_device *sysdev)
+{
+	int abi_ver = 0;
+	char value[8];
+
+	if (ibv_read_sysfs_file(sysdev->path, "abi_version",
+				value, sizeof value) > 0)
+		abi_ver = strtol(value, NULL, 10);
+
+	return ibv_driver_init(sysdev->path, abi_ver);
+}
+
 /** @brief module initialization
  */
 int libehca_trlevel = 5;
--- src/userspace/libehca/src/libehca.map	(revision 6541)
+++ src/userspace/libehca/src/libehca.map	(working copy)
@@ -1,5 +1,6 @@
 LIBEHCA_1.0 {
 	global:
+		ibv_driver_init;
 		openib_driver_init;
 	 	ehcau_query_qp;	
 		ehcau_send_wr_trigger;



More information about the general mailing list