From 50c7daf5981e73e37d052ee223ed54dd6539c846 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Tue, 11 Apr 2006 23:27:38 +0000 Subject: [PATCH] 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 --- ChangeLog | 7 +++ Makefile.am | 2 +- include/infiniband/driver.h | 8 +++ src/device.c | 8 +-- src/init.c | 41 +++++---------- src/libibverbs.map | 3 ++ src/sysfs.c | 101 ++++++++++++++++++++++++++++++++++++ src/verbs.c | 50 ++++++------------ 8 files changed, 154 insertions(+), 66 deletions(-) create mode 100644 src/sysfs.c diff --git a/ChangeLog b/ChangeLog index 8acd8b5..d4abeae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2006-04-11 Roland Dreier + * 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 +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include +#include +#include + +#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) -- 2.46.0