--- a/components/open-fabrics/infiniband-diags/solaris_set_nodedesc.c Fri Apr 01 16:38:52 2016 -0700
+++ b/components/open-fabrics/infiniband-diags/solaris_set_nodedesc.c Fri Apr 01 16:51:43 2016 -0700
@@ -37,53 +37,56 @@
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/queue.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <getopt.h>
-#include <libdevinfo.h>
#include <sys/utsname.h>
#include <infiniband/verbs.h>
#include <infiniband/arch.h>
#include <infiniband/umad.h>
#include "ibdiag_common.h"
-
-#include <sys/ib/adapters/hermon/hermon_ioctl.h>
+#include <sys/ib/clients/of/sol_uverbs/sol_uverbs_ioctl.h>
/*
- * Local defines for HCA driver IOCTLs, used while
+ * Local defines for sol_uverbs IOCTLs, used while
* building on build system without the change in
* header files.
*/
-#ifdef HERMON_NODEDESC_UPDATE_STR
-#define HERMON_NODEDESC_UPDATE_STRING 0x00000001
-#endif
-#ifndef HERMON_NODEDESC_UPDATE_HCA_STRING
-#define HERMON_NODEDESC_UPDATE_HCA_STRING 0x00000002
-#undef HERMON_NODEDESC_UPDATE_HCA_MAP
-#endif
-#ifndef HERMON_IOCTL_GET_NODEDESC
-#define HERMON_IOCTL_GET_NODEDESC (('t' << 8) | 0x31)
+#ifndef UVERBS_IOCTL_GET_NODEDESC
+#define UVERBS_IOCTL_GET_NODEDESC ('v' << 8) | 0x04
+#define UVERBS_IOCTL_SET_NODEDESC ('v' << 8) | 0x05
+#define UVERBS_NODEDESC_UPDATE_STRING 0x00000001
+#define UVERBS_NODEDESC_UPDATE_HCA_STRING 0x00000002
+
+typedef struct sol_uverbs_nodedesc_s {
+ int32_t uverbs_solaris_abi_version;
+ char node_desc_str[64];
+ uint32_t node_desc_update_flag;
+} sol_uverbs_nodedesc_t;
#endif
-#define NODEDESC_UPDATE_STRING 0x00000001
-#define NODEDESC_UPDATE_HCA_STRING 0x00000002
+/*
+ * Override verbs abi version.
+ * If the build system doesn't have the intended
+ * header file then override with the intended abi version.
+ * These changes can be deleted once the build system has
+ * the correct header file.
+ */
+#if (IB_USER_VERBS_SOLARIS_ABI_VERSION == 3)
+#undef IB_USER_VERBS_SOLARIS_ABI_VERSION
+#define IB_USER_VERBS_SOLARIS_ABI_VERSION 4
+#endif
+
#define NODEDESC_READ 0x80000000
-static char *devpath_prefix = "/devices";
-static char *devpath_suffix = ":devctl";
-static char *ib_hca_driver_list[] = {
- "hermon", NULL
-};
-static di_node_t di_rootnode;
char *argv0 = "solaris_set_nodedesc";
static struct nodedesc_read_info_s {
@@ -93,7 +96,14 @@
boolean_t ofuv_name_valid;
char ofuv_name[64];
} nd_read_info_arr[MAX_HCAS];
-int nd_read_info_cnt;
+int nd_read_info_cnt = 0;
+
+static int
+read_nodedesc_ioctl(struct ibv_context *context,
+ sol_uverbs_nodedesc_t *nodedesc);
+static int
+write_nodedesc_ioctl(struct ibv_context *context,
+ sol_uverbs_nodedesc_t *nodedesc);
static void
print_read_info()
@@ -111,24 +121,18 @@
}
static void
-update_read_info_hwnames()
+update_read_info_hwnames(struct ibv_device **dev_list, int num_devices)
{
- struct ibv_device **dev_list;
- int num_devices, i;
+ int i;
uint64_t dev_guid;
char *dev_name;
size_t dev_name_len;
- dev_list = ibv_get_device_list(&num_devices);
- if (!dev_list) {
- fprintf(stderr, "No IB devices found\n");
- return;
- }
-
- for (i = 0; i < num_devices; ++i) {
+ for (i = 0; dev_list[i] != 0 && i < num_devices; ++i) {
int j;
- dev_guid = (uint64_t)ntohll(ibv_get_device_guid(dev_list[i]));
+ dev_guid = (uint64_t)ntohll(
+ ibv_get_device_guid(dev_list[i]));
dev_name = (char *)ibv_get_device_name(dev_list[i]);
dev_name_len = strlen(dev_name) + 1;
for (j = 0; j < nd_read_info_cnt; j++) {
@@ -136,13 +140,12 @@
nd_read_info_arr[j].guid == dev_guid) {
memcpy(nd_read_info_arr[j].ofuv_name,
dev_name, dev_name_len);
- nd_read_info_arr[j].ofuv_name_valid = B_TRUE;
+ nd_read_info_arr[j].ofuv_name_valid =
+ B_TRUE;
break;
}
}
}
-
- ibv_free_device_list(dev_list);
}
static void
@@ -153,195 +156,233 @@
nd_len = strlen(nd_str) + 1;
nd_read_info_arr[nd_read_info_cnt].info_valid = B_TRUE;
nd_read_info_arr[nd_read_info_cnt].guid = guid;
- memcpy(nd_read_info_arr[nd_read_info_cnt].nd_string, nd_str, nd_len);
+ memcpy(nd_read_info_arr[nd_read_info_cnt].nd_string,
+ nd_str, nd_len);
nd_read_info_cnt++;
}
static void
-do_driver_read_ioctl(char *drivername)
+do_driver_read_ioctl(struct ibv_device *device)
{
- di_node_t hcanode, childnode;
- char *devpath;
- char *access_devname;
- int devlength, devfd, rc = -1;
- uint64_t *hca_guid;
+ int rc;
+ uint64_t hca_guid;
+ struct ibv_context *context;
+ sol_uverbs_nodedesc_t *nodedescp;
+
+ /* Get the context for the device */
+ context = ibv_open_device(device);
+ if (!context) {
+ IBEXIT("Unable to open the device.\n");
+ /* NOTREACHED */
+ }
- if ((hcanode = di_drv_first_node(drivername, di_rootnode))
- == DI_NODE_NIL) {
- return;
+ if (context->device != device) {
+ IBEXIT("Device not set.\n");
+ /* NOTREACHED */
+ }
+
+ /* Allocate the memory for node descriptor */
+ nodedescp = (sol_uverbs_nodedesc_t *)malloc(
+ sizeof (sol_uverbs_nodedesc_t));
+ if (nodedescp == NULL) {
+ IBEXIT("Memory allocation failed.\n");
+ /* NOTREACHED */
}
- while (hcanode != DI_NODE_NIL) {
- childnode = di_child_node(hcanode);
- while (childnode != DI_NODE_NIL) {
- if (di_prop_lookup_int64(DDI_DEV_T_ANY,
- childnode, "hca-guid",
- (int64_t **)&hca_guid) != 1) {
- childnode = di_sibling_node(childnode);
- continue;
- } else {
- break;
- }
- }
- if (childnode == DI_NODE_NIL) {
- hcanode = di_drv_next_node(hcanode);
- continue;
- }
+ nodedescp->uverbs_solaris_abi_version =
+ IB_USER_VERBS_SOLARIS_ABI_VERSION;
- devpath = di_devfs_path(hcanode);
- devlength = strlen(devpath_prefix) + strlen(devpath) +
- strlen(devpath_suffix) + 2;
- access_devname = malloc(devlength);
- (void) snprintf(access_devname, devlength, "%s%s%s",
- devpath_prefix, devpath, devpath_suffix);
- if ((devfd = open(access_devname, O_RDONLY)) < 0) {
- IBEXIT("open device file %s failed", access_devname);
- free(access_devname);
- hcanode = di_drv_next_node(hcanode);
- continue;
- }
- if (strcmp(drivername, "hermon") == 0) {
- hermon_nodedesc_ioctl_t nodedesc_ioctl;
-
- if ((rc = ioctl(devfd, HERMON_IOCTL_GET_NODEDESC,
- (void *)&nodedesc_ioctl)) != 0) {
- IBEXIT("hermon ioctl failure");
- free(access_devname);
- close(devfd);
- hcanode = di_drv_next_node(hcanode);
- continue;
- }
- add_read_info_arr((char *)nodedesc_ioctl.node_desc_str,
- *hca_guid);
- } else {
- IBEXIT("drivername != hermon: %s", drivername);
- }
-
- free(access_devname);
- close(devfd);
- hcanode = di_drv_next_node(hcanode);
+ /* Get the guid for the device */
+ hca_guid = (uint64_t)ntohll(ibv_get_device_guid(device));
+ if (!hca_guid) {
+ IBEXIT("ibv_get_device_guid failed.\n");
+ /* NOTREACHED */
}
+ /* Read node descriptor */
+ rc = read_nodedesc_ioctl(context, nodedescp);
+ if (rc != 0) {
+ IBEXIT("Failed to read node descriptor.\n");
+ /* NOTREACHED */
+ }
+
+ add_read_info_arr((char *)nodedescp->node_desc_str,
+ hca_guid);
+
+read_nodedesc_exit_1:
+ /* release the allocated memory */
+ free(nodedescp);
+read_nodedesc_exit_2:
+ /* Close the device */
+ ibv_close_device(context);
}
static int
-do_driver_update_ioctl(char *drivername, char *node_desc, char *hca_desc,
- uint64_t inp_hca_guid, uint32_t update_flag)
+do_driver_update_ioctl(struct ibv_device *device, char *node_desc,
+ char *hca_desc, uint32_t update_flag)
{
- di_node_t hcanode, childnode;
- char *devpath;
- char *access_devname;
- int devlength, devfd, rc = -1;
- uint64_t *hca_guid;
- char *desc_str = (node_desc ? node_desc : hca_desc);
+ int rc;
+ struct ibv_context *context;
+ sol_uverbs_nodedesc_t *nodedescp;
+ char *desc_str;
- if ((hcanode = di_drv_first_node(drivername, di_rootnode))
- == DI_NODE_NIL) {
- return (-1);
+ desc_str = (node_desc ? node_desc : hca_desc);
+
+ /* Get context for the device */
+ context = ibv_open_device(device);
+ if (!context) {
+ IBEXIT("Unable to open the device.\n");
+ /* NOTREACHED */
}
- while (hca_desc && hcanode != DI_NODE_NIL) {
- childnode = di_child_node(hcanode);
- while (childnode != DI_NODE_NIL) {
- if (di_prop_lookup_int64(DDI_DEV_T_ANY,
- childnode, "hca-guid",
- (int64_t **)&hca_guid) != 1) {
- childnode = di_sibling_node(childnode);
- continue;
- } else {
- break;
- }
- }
- if (*hca_guid == inp_hca_guid)
- break;
- hcanode = di_drv_next_node(hcanode);
+ if (context->device != device) {
+ IBEXIT("Device not set.\n");
+ /* NOTREACHED */
}
- if ((hca_desc && childnode == DI_NODE_NIL) ||
- hcanode == DI_NODE_NIL) {
- IBEXIT("matching GUID not found");
- return (-1);
+ /* Allocate the memory for node descriptor */
+ nodedescp = (sol_uverbs_nodedesc_t *)malloc(
+ sizeof (sol_uverbs_nodedesc_t));
+ if (nodedescp == NULL) {
+ IBEXIT("Memory allocation failed.\n");
+ /* NOTREACHED */
}
- devpath = di_devfs_path(hcanode);
- devlength = strlen(devpath_prefix) + strlen(devpath) +
- strlen(devpath_suffix) + 2;
- access_devname = malloc(devlength);
- (void) snprintf(access_devname, devlength, "%s%s%s",
- devpath_prefix, devpath, devpath_suffix);
- if ((devfd = open(access_devname, O_RDONLY)) < 0) {
- IBEXIT("open device file %s failed", access_devname);
- free(access_devname);
- return (rc);
- }
- if (strcmp(drivername, "hermon") == 0) {
- hermon_nodedesc_ioctl_t nodedesc_ioctl;
+ strncpy(nodedescp->node_desc_str, desc_str, 64);
+ nodedescp->node_desc_update_flag = update_flag;
+ nodedescp->uverbs_solaris_abi_version =
+ IB_USER_VERBS_SOLARIS_ABI_VERSION;
- strncpy(nodedesc_ioctl.node_desc_str, desc_str, 64);
- if (update_flag & NODEDESC_UPDATE_STRING)
- nodedesc_ioctl.node_desc_update_flag =
- HERMON_NODEDESC_UPDATE_STRING;
- else if (update_flag & NODEDESC_UPDATE_HCA_STRING)
- nodedesc_ioctl.node_desc_update_flag =
- HERMON_NODEDESC_UPDATE_HCA_STRING;
- else {
- IBEXIT("Invalid option");
- exit(-1);
- }
- if ((rc = ioctl(devfd, HERMON_IOCTL_SET_NODEDESC,
- (void *)&nodedesc_ioctl)) != 0) {
- IBEXIT("hermon ioctl failure");
- }
- } else {
- IBEXIT("drivername != hermon: %s", drivername);
- }
+ rc = write_nodedesc_ioctl(context, nodedescp);
+ if (rc != 0)
+ IBEXIT("Failed to set node descriptor.\n");
- free(access_devname);
- close(devfd);
+ free(nodedescp);
+
+write_nodedesc_exit:
+ ibv_close_device(context);
return (rc);
}
static void
-read_nodedesc()
+read_nodedesc(struct ibv_device **device_list, int num_devices)
{
- int i;
+ int i;
- if ((di_rootnode = di_init("/", DINFOCPYALL | DINFOFORCE))
- == DI_NODE_NIL) {
- IBEXIT("read_nodedesc di_init failure");
- return;
- }
- for (i = 0; ib_hca_driver_list[i]; i++)
- do_driver_read_ioctl(ib_hca_driver_list[i]);
- di_fini(di_rootnode);
+ for (i = 0; device_list[i] != 0 && i < num_devices; i++)
+ do_driver_read_ioctl(device_list[i]);
}
static int
-update_nodedesc(char *cmn_nodedesc, char *hca_nodedesc, uint64_t guid,
+update_nodedesc(struct ibv_device **device_list, int num_devices,
+ char *cmn_nodedesc, char *hca_nodedesc, uint64_t guid,
uint32_t update_flag)
{
- int i, rc = 0;
+ int i, rc = -1;
+ uint64_t dev_guid;
+ boolean_t matched = B_FALSE;
+
+ if (cmn_nodedesc && hca_nodedesc == NULL) {
+ for (i = 0; i < num_devices; i++) {
+ rc = do_driver_update_ioctl(device_list[i],
+ cmn_nodedesc, hca_nodedesc, update_flag);
+ if (rc != 0)
+ continue;
+ else
+ break;
+ }
+
+ if (rc != 0 && i == num_devices)
+ IBEXIT("Failed to set the node descriptor.\n");
+
+ return (rc);
+ }
- if ((di_rootnode = di_init("/", DINFOCPYALL | DINFOFORCE))
- == DI_NODE_NIL) {
- IBEXIT("di_init failure");
+ if (hca_nodedesc && guid) {
+ for (i = 0; i < num_devices; i++) {
+ dev_guid = (uint64_t)ntohll(ibv_get_device_guid(
+ device_list[i]));
+ if (!dev_guid) {
+ continue;
+ }
+ if (dev_guid == guid) {
+ matched = B_TRUE;
+ rc = do_driver_update_ioctl(device_list[i],
+ cmn_nodedesc, hca_nodedesc, update_flag);
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ if (matched == B_FALSE) {
+ IBEXIT("No guid matched.\n");
+ /* NOTREACHED */
+ }
+
+ if (rc != 0) {
+ IBEXIT("Failed to set the node descriptor.\n");
+ /* NOTREACHED */
+ }
+ }
+
+ return (rc);
+}
+
+static int
+read_nodedesc_ioctl(struct ibv_context *context,
+ sol_uverbs_nodedesc_t *nodedesc)
+{
+
+ int ret;
+
+ /*
+ * Use ioctl call to sol_uverbs module.
+ */
+ if (!context || !nodedesc) {
return (-1);
}
- for (i = 0; ib_hca_driver_list[i]; i++) {
- rc = do_driver_update_ioctl(ib_hca_driver_list[i],
- cmn_nodedesc, hca_nodedesc, guid,
- update_flag);
- if (!rc)
- break;
+
+ ret = ioctl(context->cmd_fd, UVERBS_IOCTL_GET_NODEDESC, nodedesc);
+ if (ret != 0) {
+ if (ret == EINVAL)
+ IBEXIT("ABI version check failed.\n");
+ else
+ IBEXIT("UVERBS_IOCTL_GET_NODEDESC ioctl failed.\n");
+
+ /* NOTREACHED */
}
- if (rc)
- IBEXIT("Updated failed for all HCA drivers");
+
+ return (0);
+}
+
+static int
+write_nodedesc_ioctl(struct ibv_context *context,
+ sol_uverbs_nodedesc_t *nodedesc)
+{
+ int ret;
- di_fini(di_rootnode);
- return (rc);
+ /*
+ * Use ioctl call to sol_uverbs module.
+ */
+ if (!context || !nodedesc)
+ return (-1);
+
+ ret = ioctl(context->cmd_fd, UVERBS_IOCTL_SET_NODEDESC, nodedesc);
+ if (ret != 0) {
+ if (ret == EINVAL)
+ IBEXIT("ABI version check failed.\n");
+ else
+ IBEXIT("UVERBS_IOCTL_SET_NODEDESC ioctl failed.\n");
+
+ /* NOTREACHED */
+ }
+
+ return (0);
}
+
static void
usage(void)
{
@@ -427,14 +468,17 @@
int
main(int argc, char **argv)
{
- int rc;
- char *nodedesc = NULL, *hcadesc = NULL;
- uint32_t update_flag = 0;
- struct utsname uts_name;
- uint64_t hca_guid;
- boolean_t guid_inited = B_FALSE;
- extern int ibdebug;
- char nodename[64];
+ int rc;
+ char *nodedesc = NULL;
+ char *hcadesc = NULL;
+ uint32_t update_flag = 0;
+ struct utsname uts_name;
+ uint64_t hca_guid;
+ boolean_t guid_inited = B_FALSE;
+ extern int ibdebug;
+ char nodename[64];
+ struct ibv_device **device_list = NULL;
+ int num_devices = 0;
static char const str_opts[] = "N:H:G:vd";
static const struct option long_opts[] = {
@@ -458,18 +502,18 @@
if (!nodedesc) {
usage();
rc = -1;
- goto free_and_ret;
+ goto free_and_ret_2;
}
- update_flag |= NODEDESC_UPDATE_STRING;
+ update_flag |= UVERBS_NODEDESC_UPDATE_STRING;
break;
case 'H':
hcadesc = nodedesc_substr_cat(argv, argc, B_FALSE);
if (!hcadesc) {
usage();
rc = -1;
- goto free_and_ret;
+ goto free_and_ret_2;
}
- update_flag |= NODEDESC_UPDATE_HCA_STRING;
+ update_flag |= UVERBS_NODEDESC_UPDATE_HCA_STRING;
break;
case 'G':
guid_inited = B_TRUE;
@@ -484,7 +528,7 @@
default:
usage();
rc = -1;
- goto free_and_ret;
+ goto free_and_ret_2;
}
}
@@ -492,42 +536,53 @@
if (nodedesc || hcadesc || guid_inited == B_TRUE) {
usage();
rc = -1;
- goto free_and_ret;
+ goto free_and_ret_2;
}
- read_nodedesc();
- update_read_info_hwnames();
+ device_list = ibv_get_device_list(&num_devices);
+ if (!device_list) {
+ IBEXIT("ibv_get_device_list failed.\n");
+ /* NOTREACHED */
+ }
+
+ read_nodedesc(device_list, num_devices);
+ update_read_info_hwnames(device_list, num_devices);
print_read_info();
- return (0);
+ rc = 0;
+ goto free_and_ret_1;
}
if (hcadesc && guid_inited == B_FALSE) {
IBEXIT("No GUID specified for HCA Node descriptor");
- usage();
- rc = -1;
- goto free_and_ret;
+ /* NOTREACHED */
+ }
+
+ device_list = ibv_get_device_list(&num_devices);
+ if (!device_list) {
+ IBEXIT("ibv_get_device_list failed.\n");
+ /* NOTREACHED */
}
if (nodedesc) {
- rc = update_nodedesc(nodedesc, NULL, 0,
- NODEDESC_UPDATE_STRING);
+ rc = update_nodedesc(device_list, num_devices,
+ nodedesc, NULL, 0, UVERBS_NODEDESC_UPDATE_STRING);
if (rc) {
IBEXIT("write common node descriptor "
"failed");
- rc = -1;
- goto free_and_ret;
+ /* NOTREACHED */
}
}
if (hcadesc) {
- rc = update_nodedesc(NULL, hcadesc, hca_guid,
- NODEDESC_UPDATE_HCA_STRING);
+ rc = update_nodedesc(device_list, num_devices,
+ NULL, hcadesc, hca_guid,
+ UVERBS_NODEDESC_UPDATE_HCA_STRING);
if (rc) {
IBEXIT("update_hca_noddesc failed");
- rc = -1;
- goto free_and_ret;
+ /* NOTREACHED */
}
- return (0);
+ rc = 0;
+ goto free_and_ret_1;
}
@@ -535,8 +590,7 @@
if (uname(&uts_name) < 0) {
IBEXIT("Node descriptor unspecified"
"& uts_name failed");
- rc = -1;
- goto free_and_ret;
+ /* NOTREACHED */
}
/*
@@ -548,15 +602,19 @@
if (nodename[strlen(nodename)] != ' ')
(void) strncat(nodename, " ", 1);
- rc = update_nodedesc(nodename, NULL, 0,
- NODEDESC_UPDATE_STRING);
+ rc = update_nodedesc(device_list, num_devices,
+ nodename, NULL, 0,
+ UVERBS_NODEDESC_UPDATE_STRING);
if (rc) {
IBEXIT("write common node descriptor failed");
- rc = -1;
+ /* NOTREACHED */
}
}
-free_and_ret:
+free_and_ret_1:
+ ibv_free_device_list(device_list);
+
+free_and_ret_2:
if (nodedesc)
free(nodedesc);
if (hcadesc)