aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2006-04-11 23:27:38 +0000
committerRoland Dreier <rolandd@cisco.com>2006-11-09 11:36:00 -0800
commit50c7daf5981e73e37d052ee223ed54dd6539c846 (patch)
tree0cda51119a0d9ca742a3ed1fcca5d1371d8c3851
parente2ac6bb02c36e013227c877624f9aa288b4b20db (diff)
downloadlibibverbs-50c7daf5981e73e37d052ee223ed54dd6539c846.tar.gz
Reduce dependency on libsysfs
Reduce libibverbs dependency on libsysfs by using local functions for internal sysfs access. libsysfs is still required because of the ABI, which passes a struct sysfs_class_device * to low-level driver init functions. Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--ChangeLog7
-rw-r--r--Makefile.am2
-rw-r--r--include/infiniband/driver.h8
-rw-r--r--src/device.c8
-rw-r--r--src/init.c41
-rw-r--r--src/libibverbs.map3
-rw-r--r--src/sysfs.c101
-rw-r--r--src/verbs.c50
8 files changed, 154 insertions, 66 deletions
diff --git a/ChangeLog b/ChangeLog
index 8acd8b5..d4abeae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2006-04-11 Roland Dreier <rdreier@cisco.com>
+ * src/device.c (ibv_get_device_guid), src/verbs.c (ibv_query_gid,
+ ibv_query_pkey), src/init.c (init_drivers, check_abi_version): Use
+ libibverbs functions instead of libsysfs functions to get to sysfs.
+
+ * src/sysfs.c (ibv_get_sysfs_path, ibv_read_sysfs_file): Add some
+ simple functions for accessing sysfs without using libsysfs.
+
* include/infiniband/sa-kern-abi.h: Deprecate struct
ib_kern_path_rec name; struct ibv_kern_path_rec is now preferred.
diff --git a/Makefile.am b/Makefile.am
index 171bcec..a3b575a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,7 +15,7 @@ else
endif
src_libibverbs_la_SOURCES = src/cmd.c src/device.c src/init.c src/marshall.c \
- src/memory.c src/verbs.c
+ src/memory.c src/sysfs.c src/verbs.c
src_libibverbs_la_LDFLAGS = -version-info 1 -export-dynamic \
$(libibverbs_version_script)
src_libibverbs_la_DEPENDENCIES = $(srcdir)/src/libibverbs.map
diff --git a/include/infiniband/driver.h b/include/infiniband/driver.h
index 8d2f6e4..6b01275 100644
--- a/include/infiniband/driver.h
+++ b/include/infiniband/driver.h
@@ -136,4 +136,12 @@ int ibv_cmd_destroy_ah(struct ibv_ah *ah);
int ibv_cmd_attach_mcast(struct ibv_qp *qp, union ibv_gid *gid, uint16_t lid);
int ibv_cmd_detach_mcast(struct ibv_qp *qp, union ibv_gid *gid, uint16_t lid);
+/*
+ * sysfs helper functions
+ */
+const char *ibv_get_sysfs_path(void);
+
+int ibv_read_sysfs_file(const char *dir, const char *file,
+ char *buf, size_t size);
+
#endif /* INFINIBAND_DRIVER_H */
diff --git a/src/device.c b/src/device.c
index 1139c96..3ab6ceb 100644
--- a/src/device.c
+++ b/src/device.c
@@ -87,16 +87,16 @@ const char *ibv_get_device_name(struct ibv_device *device)
uint64_t ibv_get_device_guid(struct ibv_device *device)
{
- struct sysfs_attribute *attr;
+ char attr[24];
uint64_t guid = 0;
uint16_t parts[4];
int i;
- attr = sysfs_get_classdev_attr(device->ibdev, "node_guid");
- if (!attr)
+ if (ibv_read_sysfs_file(device->ibdev->path, "node_guid",
+ attr, sizeof attr) < 0)
return 0;
- if (sscanf(attr->value, "%hx:%hx:%hx:%hx",
+ if (sscanf(attr, "%hx:%hx:%hx:%hx",
parts, parts + 1, parts + 2, parts + 3) != 4)
return 0;
diff --git a/src/init.c b/src/init.c
index a15d295..4b943b8 100644
--- a/src/init.c
+++ b/src/init.c
@@ -121,24 +121,21 @@ static void find_drivers(char *dir)
static struct ibv_device *init_drivers(struct sysfs_class_device *verbs_dev)
{
struct sysfs_class_device *ib_dev;
- struct sysfs_attribute *attr;
struct ibv_driver *driver;
struct ibv_device *dev;
char ibdev_name[64];
- attr = sysfs_get_classdev_attr(verbs_dev, "ibdev");
- if (!attr) {
+ if (ibv_read_sysfs_file(verbs_dev->path, "ibdev",
+ ibdev_name, sizeof ibdev_name) < 0) {
fprintf(stderr, PFX "Warning: no ibdev class attr for %s\n",
verbs_dev->name);
return NULL;
}
- sscanf(attr->value, "%63s", ibdev_name);
-
ib_dev = sysfs_open_class_device("infiniband", ibdev_name);
if (!ib_dev) {
fprintf(stderr, PFX "Warning: no infiniband class device %s for %s\n",
- attr->value, verbs_dev->name);
+ ibdev_name, verbs_dev->name);
return NULL;
}
@@ -164,44 +161,34 @@ static struct ibv_device *init_drivers(struct sysfs_class_device *verbs_dev)
static int check_abi_version(void)
{
- char path[256];
- struct sysfs_attribute *attr;
- int ret = -1;
+ const char *path;
+ char value[8];
- if (sysfs_get_mnt_path(path, sizeof path)) {
+ path = ibv_get_sysfs_path();
+ if (!path) {
fprintf(stderr, PFX "Fatal: couldn't find sysfs mount.\n");
return -1;
}
- strncat(path, "/class/infiniband_verbs/abi_version", sizeof path);
-
- attr = sysfs_open_attribute(path);
- if (!attr)
- return -1;
-
- if (sysfs_read_attribute(attr)) {
+ if (ibv_read_sysfs_file(path, "class/infiniband_verbs/abi_version",
+ value, sizeof value) < 0) {
fprintf(stderr, PFX "Fatal: couldn't read uverbs ABI version.\n");
- goto out;
+ return -1;
}
- abi_ver = strtol(attr->value, NULL, 10);
+ abi_ver = strtol(value, NULL, 10);
if (abi_ver < IB_USER_VERBS_MIN_ABI_VERSION ||
abi_ver > IB_USER_VERBS_MAX_ABI_VERSION) {
fprintf(stderr, PFX "Fatal: kernel ABI version %d "
"doesn't match library version %d.\n",
abi_ver, IB_USER_VERBS_MAX_ABI_VERSION);
- goto out;
+ return -1;
}
- ret = 0;
-
-out:
- sysfs_close_attribute(attr);
- return ret;
+ return 0;
}
-
HIDDEN int ibverbs_init(struct ibv_device ***list)
{
char *wr_path, *dir;
@@ -221,7 +208,7 @@ HIDDEN int ibverbs_init(struct ibv_device ***list)
find_drivers(default_path);
/*
- * Only follow the path passed in through the calling user's
+ * Only follow use path passed in through the calling user's
* environment if we're not running SUID.
*/
if (getuid() == geteuid()) {
diff --git a/src/libibverbs.map b/src/libibverbs.map
index 29eb220..fba7026 100644
--- a/src/libibverbs.map
+++ b/src/libibverbs.map
@@ -69,6 +69,9 @@ IBVERBS_1.0 {
ibv_copy_path_rec_to_kern;
ibv_rate_to_mult;
mult_to_ibv_rate;
+ ibv_get_sysfs_path;
+ ibv_read_sysfs_file;
+
ib_copy_qp_attr_from_kern;
ib_copy_path_rec_from_kern;
ib_copy_path_rec_to_kern;
diff --git a/src/sysfs.c b/src/sysfs.c
new file mode 100644
index 0000000..e97f0e8
--- /dev/null
+++ b/src/sysfs.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2006 Cisco Systems. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "ibverbs.h"
+
+static char *sysfs_path;
+
+const char *ibv_get_sysfs_path(void)
+{
+ char *env = NULL;
+
+ if (sysfs_path)
+ return sysfs_path;
+
+ /*
+ * Only follow use path passed in through the calling user's
+ * environment if we're not running SUID.
+ */
+ if (getuid() == geteuid())
+ env = getenv("SYSFS_PATH");
+
+ if (env) {
+ int len;
+
+ sysfs_path = strndup(env, 256);
+ len = strlen(sysfs_path);
+ while (len > 0 && sysfs_path[len - 1] == '/') {
+ --len;
+ sysfs_path[len] = '\0';
+ }
+ } else
+ sysfs_path = "/sys";
+
+ return sysfs_path;
+}
+
+int ibv_read_sysfs_file(const char *dir, const char *file,
+ char *buf, size_t size)
+{
+ char *path;
+ int fd;
+ int len;
+
+ asprintf(&path, "%s/%s", dir, file);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ len = read(fd, buf, size);
+
+ close(fd);
+ free(path);
+
+ if (len > 0 && buf[len - 1] == '\n')
+ buf[--len] = '\0';
+
+ return len;
+}
diff --git a/src/verbs.c b/src/verbs.c
index 0397710..4f63763 100644
--- a/src/verbs.c
+++ b/src/verbs.c
@@ -92,63 +92,45 @@ int ibv_query_port(struct ibv_context *context, uint8_t port_num,
int ibv_query_gid(struct ibv_context *context, uint8_t port_num,
int index, union ibv_gid *gid)
{
- char *attr_name;
- struct sysfs_attribute *attr;
+ char name[24];
+ char attr[41];
uint16_t val;
int i;
- int ret = -1;
- asprintf(&attr_name, "%s/ports/%d/gids/%d",
- context->device->ibdev->path, port_num, index);
+ snprintf(name, sizeof name, "ports/%d/gids/%d", port_num, index);
- attr = sysfs_open_attribute(attr_name);
- if (!attr)
+ if (ibv_read_sysfs_file(context->device->ibdev->path, name,
+ attr, sizeof attr) < 0)
return -1;
- if (sysfs_read_attribute(attr))
- goto out;
-
for (i = 0; i < 8; ++i) {
- if (sscanf(attr->value + i * 5, "%hx", &val) != 1)
- goto out;
+ if (sscanf(attr + i * 5, "%hx", &val) != 1)
+ return -1;
gid->raw[i * 2 ] = val >> 8;
gid->raw[i * 2 + 1] = val & 0xff;
}
- ret = 0;
-
-out:
- sysfs_close_attribute(attr);
- return ret;
+ return 0;
}
int ibv_query_pkey(struct ibv_context *context, uint8_t port_num,
int index, uint16_t *pkey)
{
- char *attr_name;
- struct sysfs_attribute *attr;
+ char name[24];
+ char attr[8];
uint16_t val;
- int ret = -1;
- asprintf(&attr_name, "%s/ports/%d/pkeys/%d",
- context->device->ibdev->path, port_num, index);
+ snprintf(name, sizeof name, "ports/%d/pkeys/%d", port_num, index);
- attr = sysfs_open_attribute(attr_name);
- if (!attr)
+ if (ibv_read_sysfs_file(context->device->ibdev->path, name,
+ attr, sizeof attr) < 0)
return -1;
- if (sysfs_read_attribute(attr))
- goto out;
-
- if (sscanf(attr->value, "%hx", &val) != 1)
- goto out;
+ if (sscanf(attr, "%hx", &val) != 1)
+ return -1;
*pkey = htons(val);
- ret = 0;
-
-out:
- sysfs_close_attribute(attr);
- return ret;
+ return 0;
}
struct ibv_pd *ibv_alloc_pd(struct ibv_context *context)