Skip to content

Commit a63bcf1

Browse files
committed
ibstat: ignore non-RDMA endpoint devices when umad_get_ca() fails
When umad_get_ca() fails, ibstat currently propagates the error even for devices that are not usable RDMA endpoints. Add lightweight sysfs checks to detect non-endpoint devices by verifying either the presence of port GID 0 (ports/<n>/gids/0) or the Connection Manager capability bit (port cap_mask bit 16). If neither is present, treat the device as non-RDMA and return 0 instead of failing. This improves behavior on systems exposing non-endpoint IB-class devices under /sys/class/infiniband/. Signed-off-by: Nagappan Ramasamy Palaniappan <nagappan.ramasamy.palaniappan@oracle.com>
1 parent cc0e95c commit a63bcf1

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

infiniband-diags/ibstat.c

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,17 @@
4343
#include <sys/stat.h>
4444
#include <fcntl.h>
4545
#include <errno.h>
46+
#include <dirent.h>
4647
#include <linux/types.h> /* __be64 */
4748

4849
#include <infiniband/umad.h>
4950

5051
#include <ibdiag_common.h>
5152

53+
/* IB spec: Port supports Connection Manager (cap_mask bit 16) */
54+
#define IB_PORT_CAP_CM (0x10000)
55+
#define SYS_PORT_GID "gids/0"
56+
5257
static const char * const node_type_str[] = {
5358
"???",
5459
"CA",
@@ -193,13 +198,55 @@ static int port_dump(umad_port_t * port, int alone)
193198
return 0;
194199
}
195200

201+
static bool port_has_gid(const char *ca_name, int portnum)
202+
{
203+
char path[256];
204+
FILE *f;
205+
206+
snprintf(path, sizeof(path),
207+
SYS_INFINIBAND "/%s/ports/%d/" SYS_PORT_GID, ca_name, portnum);
208+
209+
f = fopen(path, "r");
210+
if (!f)
211+
return false;
212+
213+
fclose(f);
214+
return true;
215+
}
216+
217+
static int port_has_cm_cap(const char *ca_name, int portnum)
218+
{
219+
char path[256], buf[32];
220+
uint32_t capmask;
221+
222+
snprintf(path, sizeof(path),
223+
SYS_INFINIBAND "/%s/ports/%d", ca_name, portnum);
224+
225+
if (sys_read_string(path, SYS_PORT_CAPMASK, buf, sizeof(buf)) < 0)
226+
return 0;
227+
228+
capmask = strtoul(buf, NULL, 0);
229+
return (capmask & IB_PORT_CAP_CM);
230+
}
231+
196232
static int ca_stat(const char *ca_name, int portnum, int no_ports)
197233
{
198234
umad_ca_t ca;
199-
int r;
200-
201-
if ((r = umad_get_ca(ca_name, &ca)) < 0)
235+
int r, check_port;
236+
237+
r = umad_get_ca(ca_name, &ca);
238+
if (r < 0) {
239+
if (portnum == -1)
240+
check_port = 1;
241+
else
242+
check_port = portnum;
243+
244+
if ((!port_has_gid(ca_name, check_port)) && (!port_has_cm_cap(ca_name, check_port))) {
245+
DEBUG("The device %s is not RDMA endpoint device", ca_name);
246+
return 0;
247+
}
202248
return r;
249+
}
203250

204251
if (!ca.node_type)
205252
return 0;

0 commit comments

Comments
 (0)