aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gunthorpe <jgunthorpe@obsidianresearch.com>2009-10-28 17:42:21 -0600
committerRoland Dreier <rolandd@cisco.com>2009-10-29 13:27:28 -0700
commit1250be6e4ae4988a9602521be7718b727b77fcbe (patch)
tree832eba278429380087e7b242f28f58a35069c14c
parentbdf2299e0c0b41f193955eb5bf10485848effa89 (diff)
downloadlibibverbs-1250be6e4ae4988a9602521be7718b727b77fcbe.tar.gz
Return errors from ibv_get_device_list() via errno
Get rid of the output to stderr on various failure cases from ibv_get_device_list() such as no device driver found, so that applications can control how to present errors. Fix up the examples and the man page to match. Code expecting this behavior linking to old libibverbs will get the old fprint and errno set to garbage (probably ESPIPE). Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r--examples/asyncwatch.c2
-rw-r--r--examples/device_list.c2
-rw-r--r--examples/devinfo.c4
-rw-r--r--examples/rc_pingpong.c2
-rw-r--r--examples/srq_pingpong.c2
-rw-r--r--examples/uc_pingpong.c2
-rw-r--r--examples/ud_pingpong.c2
-rw-r--r--man/ibv_get_device_list.316
-rw-r--r--src/device.c21
-rw-r--r--src/init.c39
10 files changed, 58 insertions, 34 deletions
diff --git a/examples/asyncwatch.c b/examples/asyncwatch.c
index 16aee2c..e56b4dc 100644
--- a/examples/asyncwatch.c
+++ b/examples/asyncwatch.c
@@ -82,7 +82,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/examples/device_list.c b/examples/device_list.c
index 3ce8cbd..70c3af5 100644
--- a/examples/device_list.c
+++ b/examples/device_list.c
@@ -49,7 +49,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(&num_devices);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/examples/devinfo.c b/examples/devinfo.c
index 2f6b488..4a3fb7a 100644
--- a/examples/devinfo.c
+++ b/examples/devinfo.c
@@ -372,7 +372,7 @@ int main(int argc, char *argv[])
case 'l':
dev_list = orig_dev_list = ibv_get_device_list(&num_of_hcas);
if (!dev_list) {
- fprintf(stderr, "Failed to get IB devices list");
+ perror("Failed to get IB devices list");
return -1;
}
@@ -398,7 +398,7 @@ int main(int argc, char *argv[])
dev_list = orig_dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "Failed to get IB device list\n");
+ perror("Failed to get IB devices list");
return -1;
}
diff --git a/examples/rc_pingpong.c b/examples/rc_pingpong.c
index d4115e4..fa969e0 100644
--- a/examples/rc_pingpong.c
+++ b/examples/rc_pingpong.c
@@ -593,7 +593,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/examples/srq_pingpong.c b/examples/srq_pingpong.c
index e47bae6..1e36c57 100644
--- a/examples/srq_pingpong.c
+++ b/examples/srq_pingpong.c
@@ -682,7 +682,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/examples/uc_pingpong.c b/examples/uc_pingpong.c
index 404b059..6f31247 100644
--- a/examples/uc_pingpong.c
+++ b/examples/uc_pingpong.c
@@ -581,7 +581,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/examples/ud_pingpong.c b/examples/ud_pingpong.c
index 8f3d50b..6f10212 100644
--- a/examples/ud_pingpong.c
+++ b/examples/ud_pingpong.c
@@ -580,7 +580,7 @@ int main(int argc, char *argv[])
dev_list = ibv_get_device_list(NULL);
if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
+ perror("Failed to get IB devices list");
return 1;
}
diff --git a/man/ibv_get_device_list.3 b/man/ibv_get_device_list.3
index 003fffb..16cc1a0 100644
--- a/man/ibv_get_device_list.3
+++ b/man/ibv_get_device_list.3
@@ -25,10 +25,24 @@ returned by
.B ibv_get_device_list()\fR.
.SH "RETURN VALUE"
.B ibv_get_device_list()
-returns the array of available RDMA devices, or NULL if the request fails.
+returns the array of available RDMA devices, or sets
+.I errno
+and returns NULL if the request fails. If no devices are found then
+.I num_devices
+is set to 0, and non-NULL is returned.
.PP
.B ibv_free_device_list()
returns no value.
+.SH "ERRORS"
+.TP
+.B EPERM
+Permission denied.
+.TP
+.B ENOSYS
+No kernel support for RDMA.
+.TP
+.B ENOMEM
+Insufficient memory to complete the operation.
.SH "NOTES"
Client code should open all the devices it intends to use with
.B ibv_open_device()\fR before calling
diff --git a/src/device.c b/src/device.c
index 3abc1eb..185f4a6 100644
--- a/src/device.c
+++ b/src/device.c
@@ -43,6 +43,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <alloca.h>
+#include <errno.h>
#include <infiniband/arch.h>
@@ -54,27 +55,35 @@ static struct ibv_device **device_list;
struct ibv_device **__ibv_get_device_list(int *num)
{
- struct ibv_device **l;
+ struct ibv_device **l = 0;
int i;
+ if (num)
+ *num = 0;
+
pthread_mutex_lock(&device_list_lock);
if (!num_devices)
num_devices = ibverbs_init(&device_list);
+ if (num_devices < 0) {
+ errno = -num_devices;
+ goto out;
+ }
+
l = calloc(num_devices + 1, sizeof (struct ibv_device *));
- if (!l)
+ if (!l) {
+ errno = ENOMEM;
goto out;
+ }
for (i = 0; i < num_devices; ++i)
l[i] = device_list[i];
+ if (num)
+ *num = num_devices;
out:
pthread_mutex_unlock(&device_list_lock);
-
- if (num)
- *num = l ? num_devices : 0;
-
return l;
}
default_symver(__ibv_get_device_list, ibv_get_device_list);
diff --git a/src/init.c b/src/init.c
index fae53be..4f0130e 100644
--- a/src/init.c
+++ b/src/init.c
@@ -46,6 +46,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <dirent.h>
+#include <errno.h>
#include "ibverbs.h"
@@ -76,23 +77,21 @@ static struct ibv_sysfs_dev *sysfs_dev_list;
static struct ibv_driver_name *driver_name_list;
static struct ibv_driver *head_driver, *tail_driver;
-static void find_sysfs_devs(void)
+static int find_sysfs_devs(void)
{
char class_path[IBV_SYSFS_PATH_MAX];
DIR *class_dir;
struct dirent *dent;
struct ibv_sysfs_dev *sysfs_dev = NULL;
char value[8];
+ int ret = 0;
snprintf(class_path, sizeof class_path, "%s/class/infiniband_verbs",
ibv_get_sysfs_path());
class_dir = opendir(class_path);
- if (!class_dir) {
- fprintf(stderr, PFX "Fatal: couldn't open sysfs class "
- "directory '%s'.\n", class_path);
- return;
- }
+ if (!class_dir)
+ return ENOSYS;
while ((dent = readdir(class_dir))) {
struct stat buf;
@@ -103,9 +102,8 @@ static void find_sysfs_devs(void)
if (!sysfs_dev)
sysfs_dev = malloc(sizeof *sysfs_dev);
if (!sysfs_dev) {
- fprintf(stderr, PFX "Warning: couldn't allocate sysfs dev "
- "for '%s'.\n", dent->d_name);
- continue;
+ ret = ENOMEM;
+ goto out;
}
snprintf(sysfs_dev->sysfs_path, sizeof sysfs_dev->sysfs_path,
@@ -147,10 +145,12 @@ static void find_sysfs_devs(void)
sysfs_dev = NULL;
}
+ out:
if (sysfs_dev)
free(sysfs_dev);
closedir(class_dir);
+ return ret;
}
void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
@@ -391,8 +391,7 @@ static int check_abi_version(const char *path)
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");
- return -1;
+ return ENOSYS;
}
abi_ver = strtol(value, NULL, 10);
@@ -402,7 +401,7 @@ static int check_abi_version(const char *path)
fprintf(stderr, PFX "Fatal: kernel ABI version %d "
"doesn't match library version %d.\n",
abi_ver, IB_USER_VERBS_MAX_ABI_VERSION);
- return -1;
+ return ENOSYS;
}
return 0;
@@ -453,6 +452,7 @@ HIDDEN int ibverbs_init(struct ibv_device ***list)
int list_size = 0;
int statically_linked = 0;
int no_driver = 0;
+ int ret;
*list = NULL;
@@ -462,19 +462,20 @@ HIDDEN int ibverbs_init(struct ibv_device ***list)
"but init failed\n");
sysfs_path = ibv_get_sysfs_path();
- if (!sysfs_path) {
- fprintf(stderr, PFX "Fatal: couldn't find sysfs mount.\n");
- return 0;
- }
+ if (!sysfs_path)
+ return -ENOSYS;
- if (check_abi_version(sysfs_path))
- return 0;
+ ret = check_abi_version(sysfs_path);
+ if (ret)
+ return -ret;
check_memlock_limit();
read_config();
- find_sysfs_devs();
+ ret = find_sysfs_devs();
+ if (ret)
+ return -ret;
for (sysfs_dev = sysfs_dev_list; sysfs_dev; sysfs_dev = sysfs_dev->next) {
device = try_drivers(sysfs_dev);