svn commit: r211195 - in projects/ofed/head/contrib/ofed/management:
infiniband-diags/src libibcommon/include/infiniband
libibcommon/src libibumad/include/infiniband libibumad/src
Jeff Roberson
jeff at FreeBSD.org
Wed Aug 11 22:44:10 UTC 2010
Author: jeff
Date: Wed Aug 11 22:44:10 2010
New Revision: 211195
URL: http://svn.freebsd.org/changeset/base/211195
Log:
- Change ib libs from using sysfs to sysctl. This is mostly a trivial
replacement of / with . and open with sysctl.
- Implement a scandir() replacement for sysctl. This was quite complex
as sysctl does not return nodes as unique items and does a depth first
traversal.
- Adjust some paths in umad.h.
- Other minor porting, #ifdef HAVE_CONFIG_H wrapping, and missing includes,
etc.
Sponsored by: Isilon Systems, iX Systems, and Panasas.
Modified:
projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibaddr.c
projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibdiag_common.c
projects/ofed/head/contrib/ofed/management/libibcommon/include/infiniband/common.h
projects/ofed/head/contrib/ofed/management/libibcommon/src/libibcommon.map
projects/ofed/head/contrib/ofed/management/libibcommon/src/sysfs.c
projects/ofed/head/contrib/ofed/management/libibumad/include/infiniband/umad.h
projects/ofed/head/contrib/ofed/management/libibumad/src/umad.c
Modified: projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibaddr.c
==============================================================================
--- projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibaddr.c Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibaddr.c Wed Aug 11 22:44:10 2010 (r211195)
@@ -46,6 +46,8 @@
#include <infiniband/umad.h>
#include <infiniband/mad.h>
+#include <sys/socket.h>
+
#include "ibdiag_common.h"
char *argv0 = "ibaddr";
Modified: projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibdiag_common.c
==============================================================================
--- projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibdiag_common.c Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/infiniband-diags/src/ibdiag_common.c Wed Aug 11 22:44:10 2010 (r211195)
@@ -45,7 +45,9 @@
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
#include "ibdiag_common.h"
Modified: projects/ofed/head/contrib/ofed/management/libibcommon/include/infiniband/common.h
==============================================================================
--- projects/ofed/head/contrib/ofed/management/libibcommon/include/infiniband/common.h Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/libibcommon/include/infiniband/common.h Wed Aug 11 22:44:10 2010 (r211195)
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <sys/select.h>
#include <sys/types.h>
+#include <dirent.h>
#include <stdint.h>
#include <byteswap.h>
@@ -127,6 +128,9 @@ int sys_read_guid(char *dir_name, char *
int sys_read_gid(char *dir_name, char *file_name, uint8_t *gid);
int sys_read_uint64(char *dir_name, char *file_name, uint64_t *u);
int sys_read_uint(char *dir_name, char *file_name, unsigned *u);
+int sys_scandir(const char *dirname, struct dirent ***namelist,
+ int (*select)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **));
/* stack.c */
void stack_dump(void);
Modified: projects/ofed/head/contrib/ofed/management/libibcommon/src/libibcommon.map
==============================================================================
--- projects/ofed/head/contrib/ofed/management/libibcommon/src/libibcommon.map Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/libibcommon/src/libibcommon.map Wed Aug 11 22:44:10 2010 (r211195)
@@ -7,6 +7,7 @@ IBCOMMON_1.0 {
sys_read_string;
sys_read_uint;
sys_read_uint64;
+ sys_scandir;
getcurrenttime;
fhash;
logmsg;
Modified: projects/ofed/head/contrib/ofed/management/libibcommon/src/sysfs.c
==============================================================================
--- projects/ofed/head/contrib/ofed/management/libibcommon/src/sysfs.c Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/libibcommon/src/sysfs.c Wed Aug 11 22:44:10 2010 (r211195)
@@ -57,6 +57,9 @@
#include <netinet/in.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
#include "common.h"
static int
@@ -73,26 +76,23 @@ int
sys_read_string(char *dir_name, char *file_name, char *str, int max_len)
{
char path[256], *s;
- int fd, r;
+ size_t len;
snprintf(path, sizeof(path), "%s/%s", dir_name, file_name);
- if ((fd = open(path, O_RDONLY)) < 0)
- return ret_code();
+ for (s = &path[0]; *s != '\0'; s++)
+ if (*s == '/')
+ *s = '.';
- if ((r = read(fd, str, max_len)) < 0) {
- int e = errno;
- close(fd);
- errno = e;
+ len = max_len;
+ if (sysctlbyname(&path[1], str, &len, NULL, 0) == -1)
return ret_code();
- }
- str[(r < max_len) ? r : max_len - 1] = 0;
+ str[(len < max_len) ? len : max_len - 1] = 0;
if ((s = strrchr(str, '\n')))
*s = 0;
- close(fd);
return 0;
}
@@ -130,7 +130,7 @@ sys_read_gid(char *dir_name, char *file_
return r;
for (s = buf, i = 0 ; i < 8; i++) {
- if (!(str = strsep(&s, ": \t\n")))
+ if (!(str = strsep(&s, ": \t\n")))
return -EINVAL;
ugid[i] = htons(strtoul(str, 0, 16) & 0xffff);
}
@@ -165,3 +165,130 @@ sys_read_uint(char *dir_name, char *file
return 0;
}
+
+#define DIRECTSIZ(namlen) \
+ (((uintptr_t)&((struct dirent *)0)->d_name + \
+ ((namlen)+1)*sizeof(((struct dirent *)0)->d_name[0]) + 3) & ~3)
+
+int
+sys_scandir(const char *dirname, struct dirent ***namelist,
+ int (*select)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **))
+{
+ struct dirent **names;
+ struct dirent **names2;
+ struct dirent *dp;
+ char name[1024];
+ int lsname[22];
+ int chname[22];
+ int name2[22];
+ int oid[22];
+ char *s;
+ size_t n1, n2;
+ size_t len, oidlen, namlen;
+ int cnt, max;
+ int err;
+ int i;
+
+ *namelist = NULL;
+ /* Skip the leading / */
+ strncpy(name, &dirname[1], sizeof(name));
+ for (s = &name[0]; *s != '\0'; s++)
+ if (*s == '/')
+ *s = '.';
+ /*
+ * Resolve the path.
+ */
+ len = sizeof(oid) / sizeof(int);
+ namlen = strlen(name) + 1;
+ if (sysctlnametomib(name, oid, &len) != 0)
+ return (-errno);
+ lsname[0] = 0; /* Root */
+ lsname[1] = 2; /* Get next */
+ memcpy(lsname+2, oid, len * sizeof(int));
+ n1 = 2 + len;
+ oidlen = len;
+ /*
+ * Setup the return list of dirents.
+ */
+ cnt = 0;
+ max = 64;
+ names = malloc(max * sizeof(void *));
+ if (names == NULL)
+ return (-ENOMEM);
+
+ for (;;) {
+ n2 = sizeof(name2);
+ if (sysctl(lsname, n1, name2, &n2, 0, 0) < 0) {
+ if (errno == ENOENT)
+ break;
+ goto errout;
+ }
+ n2 /= sizeof(int);
+ if (n2 < oidlen)
+ break;
+ for (i = 0; i < oidlen; i++)
+ if (name2[i] != oid[i])
+ goto out;
+ chname[0] = 0; /* root */
+ chname[1] = 1; /* oid name */
+ memcpy(chname + 2, name2, n2 * sizeof(int));
+ memcpy(lsname + 2, name2, n2 * sizeof(int));
+ n1 = 2 + n2;
+ /*
+ * scandir() is not supposed to go deeper than the requested
+ * directory but sysctl also doesn't return a node for
+ * 'subdirectories' so we have to find a file in the subdir
+ * and then truncate the name to report it.
+ */
+ if (n2 > oidlen + 1) {
+ /* Skip to the next name after this one. */
+ n1 = 2 + oidlen + 1;
+ lsname[n1 - 1]++;
+ }
+ len = sizeof(name);
+ if (sysctl(chname, n2 + 2, name, &len, 0, 0) < 0)
+ goto errout;
+ if (len <= 0 || len < namlen)
+ goto out;
+ s = name + namlen;
+ /* Just keep the first level name. */
+ if (strchr(s, '.'))
+ *strchr(s, '.') = '\0';
+ len = strlen(s) + 1;
+ dp = malloc(DIRECTSIZ(len));
+ dp->d_reclen = DIRECTSIZ(len);
+ dp->d_namlen = len;
+ memcpy(&dp->d_name, s, len);
+ if (select && !select(dp)) {
+ free(dp);
+ continue;
+ }
+ if (cnt == max) {
+ max *= 2;
+ names2 = realloc(names, max * sizeof(void *));
+ if (names2 == NULL) {
+ errno = ENOMEM;
+ free(dp);
+ goto errout;
+ }
+ names = names2;
+ }
+ names[cnt++] = dp;
+ }
+out:
+ if (cnt && compar)
+ qsort(names, cnt, sizeof(struct dirent *),
+ (int (*)(const void *, const void *))compar);
+
+ *namelist = names;
+
+ return (cnt);
+
+errout:
+ err = errno;
+ for (i = 0; i < cnt; i++)
+ free(names[i]);
+ free(names);
+ return (-err);
+}
Modified: projects/ofed/head/contrib/ofed/management/libibumad/include/infiniband/umad.h
==============================================================================
--- projects/ofed/head/contrib/ofed/management/libibumad/include/infiniband/umad.h Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/libibumad/include/infiniband/umad.h Wed Aug 11 22:44:10 2010 (r211195)
@@ -81,9 +81,8 @@ typedef struct ib_user_mad {
#define IB_IOCTL_MAGIC 0x1b
-#define IB_USER_MAD_REGISTER_AGENT _IOWR(IB_IOCTL_MAGIC, 1, \
- struct ib_user_mad_reg_req)
-#define IB_USER_MAD_UNREGISTER_AGENT _IOW(IB_IOCTL_MAGIC, 2, uint32_t)
+#define IB_USER_MAD_REGISTER_AGENT _IO(IB_IOCTL_MAGIC, 1)
+#define IB_USER_MAD_UNREGISTER_AGENT _IO(IB_IOCTL_MAGIC, 2)
#define IB_USER_MAD_ENABLE_PKEY _IO(IB_IOCTL_MAGIC, 3)
#define UMAD_CA_NAME_LEN 20
@@ -98,7 +97,7 @@ typedef struct ib_user_mad {
#define UMAD_MAX_PORTS 64
-#define UMAD_DEV_DIR "/dev/infiniband"
+#define UMAD_DEV_DIR "/dev"
#define SYS_CA_PORTS_DIR "ports"
Modified: projects/ofed/head/contrib/ofed/management/libibumad/src/umad.c
==============================================================================
--- projects/ofed/head/contrib/ofed/management/libibumad/src/umad.c Wed Aug 11 22:10:37 2010 (r211194)
+++ projects/ofed/head/contrib/ofed/management/libibumad/src/umad.c Wed Aug 11 22:44:10 2010 (r211195)
@@ -79,7 +79,7 @@ typedef struct ib_user_mad_reg_req {
#define TRACE if (umaddebug) IBWARN
#define DEBUG if (umaddebug) IBWARN
-int umaddebug = 0;
+int umaddebug = 1;
#define UMAD_DEV_FILE_SZ 256
@@ -163,7 +163,7 @@ get_port(char *ca_name, char *dir, int p
memcpy(&port->port_guid, gid + 8, sizeof port->port_guid);
snprintf(port_dir + len, sizeof(port_dir) - len, "/pkeys");
- ret = scandir(port_dir, &namelist, check_for_digit_name, NULL);
+ ret = sys_scandir(port_dir, &namelist, check_for_digit_name, NULL);
if (ret <= 0) {
IBWARN("no pkeys found for %s:%u (at dir %s)...",
port->ca_name, port->portnum, port_dir);
@@ -346,7 +346,9 @@ resolve_ca_name(char *ca_name, int *best
static int
get_ca(char *ca_name, umad_ca_t *ca)
{
+#ifdef __linux__
DIR *dir;
+#endif
char dir_name[256];
struct dirent **namelist;
int r, i, ret;
@@ -376,10 +378,12 @@ get_ca(char *ca_name, umad_ca_t *ca)
snprintf(dir_name, sizeof(dir_name), "%s/%s/%s",
SYS_INFINIBAND, ca->ca_name, SYS_CA_PORTS_DIR);
+#ifdef __linux__
if (!(dir = opendir(dir_name)))
return -ENOENT;
+#endif
- if ((r = scandir(dir_name, &namelist, 0, alphasort)) < 0) {
+ if ((r = sys_scandir(dir_name, &namelist, 0, alphasort)) < 0) {
ret = errno < 0 ? errno : -EIO;
goto error;
}
@@ -416,7 +420,9 @@ get_ca(char *ca_name, umad_ca_t *ca)
free(namelist[i]);
free(namelist);
+#ifdef __linux__
closedir(dir);
+#endif
put_ca(ca);
return 0;
@@ -425,7 +431,9 @@ clean:
free(namelist[i]);
free(namelist);
error:
+#ifdef __linux__
closedir(dir);
+#endif
release_ca(ca);
return ret;
@@ -437,7 +445,7 @@ umad_id_to_dev(int umad_id, char *dev, u
char path[256];
int r;
- snprintf(path, sizeof(path), SYS_INFINIBAND_MAD "/umad%d/", umad_id);
+ snprintf(path, sizeof(path), SYS_INFINIBAND_MAD "/umad%d", umad_id);
if ((r = sys_read_string(path, SYS_IB_MAD_DEV, dev, UMAD_CA_NAME_LEN)) < 0)
return r;
@@ -520,7 +528,7 @@ umad_get_cas_names(char cas[][UMAD_CA_NA
TRACE("max %d", max);
- n = scandir(SYS_INFINIBAND, &namelist, 0, alphasort);
+ n = sys_scandir(SYS_INFINIBAND, &namelist, NULL, alphasort);
if (n > 0) {
for (i = 0; i < n; i++) {
if (strcmp(namelist[i]->d_name, ".") &&
More information about the svn-src-projects
mailing list