diff --git a/contrib/ofed/libsdp/src/linux/sdp_inet.h b/contrib/ofed/libsdp/src/linux/sdp_inet.h index fde347f073d6..02d37ddda4a3 100644 --- a/contrib/ofed/libsdp/src/linux/sdp_inet.h +++ b/contrib/ofed/libsdp/src/linux/sdp_inet.h @@ -1,52 +1,56 @@ /* 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 at , or the OpenIB.org BSD license, available in the LICENSE.TXT file accompanying this software. These details are also available at . 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. Copyright (c) 2004 Topspin Communications. All rights reserved. $Id$ */ #ifndef _SDP_INET_H #define _SDP_INET_H /* * constants shared between user and kernel space. */ #ifndef SOLARIS_BUILD +#ifdef __FreeBSD__ +#include +#else #define AF_INET_SDP 27 /* SDP socket protocol family */ #define AF_INET6_SDP 28 /* SDP socket protocol family */ +#endif #else #define AF_INET_SDP 31 /* This is an invalid family on native solaris * and will only work using QuickTransit */ //TODO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXx #define AF_INET6_SDP 32 /* SDP socket protocol family */ #endif #define AF_INET_STR "AF_INET_SDP" /* SDP enabled environment variable */ #define AF_INET6_STR "AF_INET6_SDP" /* SDP enabled environment variable */ #ifndef SDP_ZCOPY_THRESH #define SDP_ZCOPY_THRESH 80 #endif #ifndef SDP_LAST_BIND_ERR #define SDP_LAST_BIND_ERR 81 #endif #endif /* _SDP_INET_H */ diff --git a/contrib/ofed/management/infiniband-diags/src/sminfo.c b/contrib/ofed/management/infiniband-diags/src/sminfo.c index c8110577414d..a8144ac168cf 100644 --- a/contrib/ofed/management/infiniband-diags/src/sminfo.c +++ b/contrib/ofed/management/infiniband-diags/src/sminfo.c @@ -1,206 +1,206 @@ /* * Copyright (c) 2004-2008 Voltaire Inc. 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. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include "ibdiag_common.h" static uint8_t sminfo[1024]; char *argv0 = "sminfo"; static void usage(void) { fprintf(stderr, "Usage: %s [-d(ebug) -e(rr_show) -s state -p prio -a activity -D(irect) -G(uid) -V(ersion) -C ca_name -P ca_port " "-t(imeout) timeout_ms] [modifier]\n", argv0); exit(-1); } int strdata, xdata=1, bindata; enum { SMINFO_NOTACT, SMINFO_DISCOVER, SMINFO_STANDBY, SMINFO_MASTER, SMINFO_STATE_LAST, }; char *statestr[] = { - [SMINFO_NOTACT] "SMINFO_NOTACT", - [SMINFO_DISCOVER] "SMINFO_DISCOVER", - [SMINFO_STANDBY] "SMINFO_STANDBY", - [SMINFO_MASTER] "SMINFO_MASTER", + [SMINFO_NOTACT] = "SMINFO_NOTACT", + [SMINFO_DISCOVER] = "SMINFO_DISCOVER", + [SMINFO_STANDBY] = "SMINFO_STANDBY", + [SMINFO_MASTER] = "SMINFO_MASTER", }; #define STATESTR(s) (((unsigned)(s)) < SMINFO_STATE_LAST ? statestr[s] : "???") int main(int argc, char **argv) { int mgmt_classes[3] = {IB_SMI_CLASS, IB_SMI_DIRECT_CLASS, IB_SA_CLASS}; int mod = 0; ib_portid_t portid = {0}; int timeout = 0; /* use default */ uint8_t *p; unsigned act = 0; int prio = 0, state = SMINFO_STANDBY; uint64_t guid = 0, key = 0; extern int ibdebug; int dest_type = IB_DEST_LID; int udebug = 0; char *ca = 0; int ca_port = 0; static char const str_opts[] = "C:P:t:s:p:a:deDGVhu"; static const struct option long_opts[] = { { "C", 1, 0, 'C'}, { "P", 1, 0, 'P'}, { "debug", 0, 0, 'd'}, { "err_show", 0, 0, 'e'}, { "s", 1, 0, 's'}, { "p", 1, 0, 'p'}, { "a", 1, 0, 'a'}, { "Direct", 0, 0, 'D'}, { "Guid", 0, 0, 'G'}, { "Version", 0, 0, 'V'}, { "timeout", 1, 0, 't'}, { "help", 0, 0, 'h'}, { "usage", 0, 0, 'u'}, { } }; argv0 = argv[0]; while (1) { int ch = getopt_long(argc, argv, str_opts, long_opts, NULL); if ( ch == -1 ) break; switch(ch) { case 'C': ca = optarg; break; case 'P': ca_port = strtoul(optarg, 0, 0); break; case 'd': ibdebug++; madrpc_show_errors(1); umad_debug(udebug); udebug++; break; case 'e': madrpc_show_errors(1); break; case 'D': dest_type = IB_DEST_DRPATH; break; case 'G': dest_type = IB_DEST_GUID; break; case 't': timeout = strtoul(optarg, 0, 0); madrpc_set_timeout(timeout); break; case 'a': act = strtoul(optarg, 0, 0); break; case 's': state = strtoul(optarg, 0, 0); break; case 'p': prio = strtoul(optarg, 0, 0); break; case 'V': fprintf(stderr, "%s %s\n", argv0, get_build_version() ); exit(-1); default: usage(); break; } } argc -= optind; argv += optind; if (argc > 1) mod = atoi(argv[1]); madrpc_init(ca, ca_port, mgmt_classes, 3); if (argc) { if (ib_resolve_portid_str(&portid, argv[0], dest_type, 0) < 0) IBERROR("can't resolve destination port %s", argv[0]); } else { if (ib_resolve_smlid(&portid, timeout) < 0) IBERROR("can't resolve sm port %s", argv[0]); } mad_encode_field(sminfo, IB_SMINFO_GUID_F, &guid); mad_encode_field(sminfo, IB_SMINFO_ACT_F, &act); mad_encode_field(sminfo, IB_SMINFO_KEY_F, &key); mad_encode_field(sminfo, IB_SMINFO_PRIO_F, &prio); mad_encode_field(sminfo, IB_SMINFO_STATE_F, &state); if (mod) { if (!(p = smp_set(sminfo, &portid, IB_ATTR_SMINFO, mod, timeout))) IBERROR("query"); } else if (!(p = smp_query(sminfo, &portid, IB_ATTR_SMINFO, 0, timeout))) IBERROR("query"); mad_decode_field(sminfo, IB_SMINFO_GUID_F, &guid); mad_decode_field(sminfo, IB_SMINFO_ACT_F, &act); mad_decode_field(sminfo, IB_SMINFO_KEY_F, &key); mad_decode_field(sminfo, IB_SMINFO_PRIO_F, &prio); mad_decode_field(sminfo, IB_SMINFO_STATE_F, &state); printf("sminfo: sm lid %d sm guid 0x%" PRIx64 ", activity count %u priority %d state %d %s\n", portid.lid, guid, act, prio, state, STATESTR(state)); exit(0); } diff --git a/contrib/ofed/management/opensm/opensm/osm_console.c b/contrib/ofed/management/opensm/opensm/osm_console.c index c6e8e597be0e..5c494a8f9188 100644 --- a/contrib/ofed/management/opensm/opensm/osm_console.c +++ b/contrib/ofed/management/opensm/opensm/osm_console.c @@ -1,1327 +1,1330 @@ /* * Copyright (c) 2005-2008 Voltaire, Inc. 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. * */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #define _GNU_SOURCE /* for getline */ #include #include #include #include #include #include #ifdef ENABLE_OSM_CONSOLE_SOCKET #include #endif #include #include #include #include #include #include #include #include struct command { char *name; void (*help_function) (FILE * out, int detail); void (*parse_function) (char **p_last, osm_opensm_t * p_osm, FILE * out); }; static struct { int on; int delay_s; time_t previous; void (*loop_function) (osm_opensm_t * p_osm, FILE * out); } loop_command = { -on: 0, delay_s: 2, loop_function:NULL}; + .on = 0, + .delay_s = 2, + .loop_function = NULL, +}; static const struct command console_cmds[]; static inline char *next_token(char **p_last) { return strtok_r(NULL, " \t\n\r", p_last); } static void help_command(FILE * out, int detail) { int i; fprintf(out, "Supported commands and syntax:\n"); fprintf(out, "help []\n"); /* skip help command */ for (i = 1; console_cmds[i].name; i++) console_cmds[i].help_function(out, 0); } static void help_quit(FILE * out, int detail) { fprintf(out, "quit (not valid in local mode; use ctl-c)\n"); } static void help_loglevel(FILE * out, int detail) { fprintf(out, "loglevel []\n"); if (detail) { fprintf(out, " log-level is OR'ed from the following\n"); fprintf(out, " OSM_LOG_NONE 0x%02X\n", OSM_LOG_NONE); fprintf(out, " OSM_LOG_ERROR 0x%02X\n", OSM_LOG_ERROR); fprintf(out, " OSM_LOG_INFO 0x%02X\n", OSM_LOG_INFO); fprintf(out, " OSM_LOG_VERBOSE 0x%02X\n", OSM_LOG_VERBOSE); fprintf(out, " OSM_LOG_DEBUG 0x%02X\n", OSM_LOG_DEBUG); fprintf(out, " OSM_LOG_FUNCS 0x%02X\n", OSM_LOG_FUNCS); fprintf(out, " OSM_LOG_FRAMES 0x%02X\n", OSM_LOG_FRAMES); fprintf(out, " OSM_LOG_ROUTING 0x%02X\n", OSM_LOG_ROUTING); fprintf(out, " OSM_LOG_SYS 0x%02X\n", OSM_LOG_SYS); fprintf(out, "\n"); fprintf(out, " OSM_LOG_DEFAULT_LEVEL 0x%02X\n", OSM_LOG_DEFAULT_LEVEL); } } static void help_priority(FILE * out, int detail) { fprintf(out, "priority []\n"); } static void help_resweep(FILE * out, int detail) { fprintf(out, "resweep [heavy|light]\n"); } static void help_reroute(FILE * out, int detail) { fprintf(out, "reroute\n"); if (detail) { fprintf(out, "reroute the fabric\n"); } } static void help_status(FILE * out, int detail) { fprintf(out, "status [loop]\n"); if (detail) { fprintf(out, " loop -- type \"q\" to quit\n"); } } static void help_logflush(FILE * out, int detail) { fprintf(out, "logflush -- flush the opensm.log file\n"); } static void help_querylid(FILE * out, int detail) { fprintf(out, "querylid lid -- print internal information about the lid specified\n"); } static void help_portstatus(FILE * out, int detail) { fprintf(out, "portstatus [ca|switch|router]\n"); if (detail) { fprintf(out, "summarize port status\n"); fprintf(out, " [ca|switch|router] -- limit the results to the node type specified\n"); } } static void help_switchbalance(FILE * out, int detail) { fprintf(out, "switchbalance [verbose] [guid]\n"); if (detail) { fprintf(out, "output switch balancing information\n"); fprintf(out, " [verbose] -- verbose output\n" " [guid] -- limit results to specified guid\n"); } } static void help_lidbalance(FILE * out, int detail) { fprintf(out, "lidbalance [switchguid]\n"); if (detail) { fprintf(out, "output lid balanced forwarding information\n"); fprintf(out, " [switchguid] -- limit results to specified switch guid\n"); } } static void help_dump_conf(FILE *out, int detail) { fprintf(out, "dump_conf\n"); if (detail) { fprintf(out, "dump current opensm configuration\n"); } } #ifdef ENABLE_OSM_PERF_MGR static void help_perfmgr(FILE * out, int detail) { fprintf(out, "perfmgr [enable|disable|clear_counters|dump_counters|sweep_time[seconds]]\n"); if (detail) { fprintf(out, "perfmgr -- print the performance manager state\n"); fprintf(out, " [enable|disable] -- change the perfmgr state\n"); fprintf(out, " [sweep_time] -- change the perfmgr sweep time (requires [seconds] option)\n"); fprintf(out, " [clear_counters] -- clear the counters stored\n"); fprintf(out, " [dump_counters [mach]] -- dump the counters (optionally in [mach]ine readable format)\n"); fprintf(out, " [print_counters ] -- print the counters for the specified node\n"); } } #endif /* ENABLE_OSM_PERF_MGR */ /* more help routines go here */ static void help_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; int i, found = 0; p_cmd = next_token(p_last); if (!p_cmd) help_command(out, 0); else { for (i = 1; console_cmds[i].name; i++) { if (!strcmp(p_cmd, console_cmds[i].name)) { found = 1; console_cmds[i].help_function(out, 1); break; } } if (!found) { fprintf(out, "%s : Command not found\n\n", p_cmd); help_command(out, 0); } } } static void loglevel_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; int level; p_cmd = next_token(p_last); if (!p_cmd) fprintf(out, "Current log level is 0x%x\n", osm_log_get_level(&p_osm->log)); else { /* Handle x, 0x, and decimal specification of log level */ if (!strncmp(p_cmd, "x", 1)) { p_cmd++; level = strtoul(p_cmd, NULL, 16); } else { if (!strncmp(p_cmd, "0x", 2)) { p_cmd += 2; level = strtoul(p_cmd, NULL, 16); } else level = strtol(p_cmd, NULL, 10); } if ((level >= 0) && (level < 256)) { fprintf(out, "Setting log level to 0x%x\n", level); osm_log_set_level(&p_osm->log, level); } else fprintf(out, "Invalid log level 0x%x\n", level); } } static void priority_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; int priority; p_cmd = next_token(p_last); if (!p_cmd) fprintf(out, "Current sm-priority is %d\n", p_osm->subn.opt.sm_priority); else { priority = strtol(p_cmd, NULL, 0); if (0 > priority || 15 < priority) fprintf(out, "Invalid sm-priority %d; must be between 0 and 15\n", priority); else { fprintf(out, "Setting sm-priority to %d\n", priority); osm_set_sm_priority(&p_osm->sm, (uint8_t)priority); } } } static char *sm_state_str(int state) { switch (state) { case IB_SMINFO_STATE_DISCOVERING: return ("Discovering"); case IB_SMINFO_STATE_STANDBY: return ("Standby"); case IB_SMINFO_STATE_NOTACTIVE: return ("Not Active"); case IB_SMINFO_STATE_MASTER: return ("Master"); } return ("UNKNOWN"); } static char *sa_state_str(osm_sa_state_t state) { switch (state) { case OSM_SA_STATE_INIT: return ("Init"); case OSM_SA_STATE_READY: return ("Ready"); } return ("UNKNOWN"); } static void print_status(osm_opensm_t * p_osm, FILE * out) { cl_list_item_t *item; if (out) { cl_plock_acquire(&p_osm->lock); fprintf(out, " OpenSM Version : %s\n", p_osm->osm_version); fprintf(out, " SM State : %s\n", sm_state_str(p_osm->subn.sm_state)); fprintf(out, " SA State : %s\n", sa_state_str(p_osm->sa.state)); fprintf(out, " Routing Engine : %s\n", osm_routing_engine_type_str(p_osm-> routing_engine_used)); fprintf(out, " Loaded event plugins :"); if (cl_qlist_head(&p_osm->plugin_list) == cl_qlist_end(&p_osm->plugin_list)) { fprintf(out, " "); } for (item = cl_qlist_head(&p_osm->plugin_list); item != cl_qlist_end(&p_osm->plugin_list); item = cl_qlist_next(item)) fprintf(out, " %s", ((osm_epi_plugin_t *)item)->plugin_name); fprintf(out, "\n"); #ifdef ENABLE_OSM_PERF_MGR fprintf(out, "\n PerfMgr state/sweep state : %s/%s\n", osm_perfmgr_get_state_str(&(p_osm->perfmgr)), osm_perfmgr_get_sweep_state_str(&(p_osm->perfmgr))); #endif fprintf(out, "\n MAD stats\n" " ---------\n" " QP0 MADs outstanding : %d\n" " QP0 MADs outstanding (on wire) : %d\n" " QP0 MADs rcvd : %d\n" " QP0 MADs sent : %d\n" " QP0 unicasts sent : %d\n" " QP0 unknown MADs rcvd : %d\n" " SA MADs outstanding : %d\n" " SA MADs rcvd : %d\n" " SA MADs sent : %d\n" " SA unknown MADs rcvd : %d\n" " SA MADs ignored : %d\n", p_osm->stats.qp0_mads_outstanding, p_osm->stats.qp0_mads_outstanding_on_wire, p_osm->stats.qp0_mads_rcvd, p_osm->stats.qp0_mads_sent, p_osm->stats.qp0_unicasts_sent, p_osm->stats.qp0_mads_rcvd_unknown, p_osm->stats.sa_mads_outstanding, p_osm->stats.sa_mads_rcvd, p_osm->stats.sa_mads_sent, p_osm->stats.sa_mads_rcvd_unknown, p_osm->stats.sa_mads_ignored); fprintf(out, "\n Subnet flags\n" " ------------\n" " Ignore existing lfts : %d\n" " Subnet Init errors : %d\n" " In sweep hop 0 : %d\n" " First time master sweep : %d\n" " Coming out of standby : %d\n", p_osm->subn.ignore_existing_lfts, p_osm->subn.subnet_initialization_error, p_osm->subn.in_sweep_hop_0, p_osm->subn.first_time_master_sweep, p_osm->subn.coming_out_of_standby); fprintf(out, "\n"); cl_plock_release(&p_osm->lock); } } static int loop_command_check_time(void) { time_t cur = time(NULL); if ((loop_command.previous + loop_command.delay_s) < cur) { loop_command.previous = cur; return (1); } return (0); } static void status_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; p_cmd = next_token(p_last); if (p_cmd) { if (strcmp(p_cmd, "loop") == 0) { fprintf(out, "Looping on status command...\n"); fflush(out); loop_command.on = 1; loop_command.previous = time(NULL); loop_command.loop_function = print_status; } else { help_status(out, 1); return; } } print_status(p_osm, out); } static void resweep_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; p_cmd = next_token(p_last); if (!p_cmd || (strcmp(p_cmd, "heavy") != 0 && strcmp(p_cmd, "light") != 0)) { fprintf(out, "Invalid resweep command\n"); help_resweep(out, 1); } else { if (strcmp(p_cmd, "heavy") == 0) p_osm->subn.force_heavy_sweep = TRUE; osm_opensm_sweep(p_osm); } } static void reroute_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { p_osm->subn.force_reroute = TRUE; osm_opensm_sweep(p_osm); } static void logflush_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { fflush(p_osm->log.out_port); } static void querylid_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { int p = 0; uint16_t lid = 0; osm_port_t *p_port = NULL; char *p_cmd = next_token(p_last); if (!p_cmd) { fprintf(out, "no LID specified\n"); help_querylid(out, 1); return; } lid = (uint16_t) strtoul(p_cmd, NULL, 0); cl_plock_acquire(&p_osm->lock); if (lid > cl_ptr_vector_get_capacity(&(p_osm->subn.port_lid_tbl))) goto invalid_lid; p_port = cl_ptr_vector_get(&(p_osm->subn.port_lid_tbl), lid); if (!p_port) goto invalid_lid; fprintf(out, "Query results for LID %u\n", lid); fprintf(out, " GUID : 0x%016" PRIx64 "\n" " Node Desc : %s\n" " Node Type : %s\n" " Num Ports : %d\n", cl_ntoh64(p_port->guid), p_port->p_node->print_desc, ib_get_node_type_str(osm_node_get_type(p_port->p_node)), p_port->p_node->node_info.num_ports); if (p_port->p_node->sw) p = 0; else p = 1; for ( /* see above */ ; p < p_port->p_node->physp_tbl_size; p++) { fprintf(out, " Port %d health : %s\n", p, p_port->p_node->physp_table[p]. healthy ? "OK" : "ERROR"); } cl_plock_release(&p_osm->lock); return; invalid_lid: cl_plock_release(&p_osm->lock); fprintf(out, "Invalid lid %d\n", lid); return; } /** * Data structures for the portstatus command */ typedef struct _port_report { struct _port_report *next; uint64_t node_guid; uint8_t port_num; char print_desc[IB_NODE_DESCRIPTION_SIZE + 1]; } port_report_t; static void __tag_port_report(port_report_t ** head, uint64_t node_guid, uint8_t port_num, char *print_desc) { port_report_t *rep = malloc(sizeof(*rep)); if (!rep) return; rep->node_guid = node_guid; rep->port_num = port_num; memcpy(rep->print_desc, print_desc, IB_NODE_DESCRIPTION_SIZE + 1); rep->next = NULL; if (*head) { rep->next = *head; *head = rep; } else *head = rep; } static void __print_port_report(FILE * out, port_report_t * head) { port_report_t *item = head; while (item != NULL) { fprintf(out, " 0x%016" PRIx64 " %d (%s)\n", item->node_guid, item->port_num, item->print_desc); port_report_t *next = item->next; free(item); item = next; } } typedef struct { uint8_t node_type_lim; /* limit the results; 0 == ALL */ uint64_t total_nodes; uint64_t total_ports; uint64_t ports_down; uint64_t ports_active; uint64_t ports_disabled; port_report_t *disabled_ports; uint64_t ports_1X; uint64_t ports_4X; uint64_t ports_8X; uint64_t ports_12X; uint64_t ports_unknown_width; uint64_t ports_reduced_width; port_report_t *reduced_width_ports; uint64_t ports_sdr; uint64_t ports_ddr; uint64_t ports_qdr; uint64_t ports_unknown_speed; uint64_t ports_reduced_speed; port_report_t *reduced_speed_ports; } fabric_stats_t; /** * iterator function to get portstatus on each node */ static void __get_stats(cl_map_item_t * const p_map_item, void *context) { fabric_stats_t *fs = (fabric_stats_t *) context; osm_node_t *node = (osm_node_t *) p_map_item; uint8_t num_ports = osm_node_get_num_physp(node); uint8_t port = 0; /* Skip nodes we are not interested in */ if (fs->node_type_lim != 0 && fs->node_type_lim != node->node_info.node_type) return; fs->total_nodes++; for (port = 1; port < num_ports; port++) { osm_physp_t *phys = osm_node_get_physp_ptr(node, port); ib_port_info_t *pi = NULL; uint8_t active_speed = 0; uint8_t enabled_speed = 0; uint8_t active_width = 0; uint8_t enabled_width = 0; uint8_t port_state = 0; uint8_t port_phys_state = 0; if (!phys) continue; pi = &(phys->port_info); active_speed = ib_port_info_get_link_speed_active(pi); enabled_speed = ib_port_info_get_link_speed_enabled(pi); active_width = pi->link_width_active; enabled_width = pi->link_width_enabled; port_state = ib_port_info_get_port_state(pi); port_phys_state = ib_port_info_get_port_phys_state(pi); if ((enabled_width ^ active_width) > active_width) { __tag_port_report(&(fs->reduced_width_ports), cl_ntoh64(node->node_info.node_guid), port, node->print_desc); fs->ports_reduced_width++; } if ((enabled_speed ^ active_speed) > active_speed) { __tag_port_report(&(fs->reduced_speed_ports), cl_ntoh64(node->node_info.node_guid), port, node->print_desc); fs->ports_reduced_speed++; } switch (active_speed) { case IB_LINK_SPEED_ACTIVE_2_5: fs->ports_sdr++; break; case IB_LINK_SPEED_ACTIVE_5: fs->ports_ddr++; break; case IB_LINK_SPEED_ACTIVE_10: fs->ports_qdr++; break; default: fs->ports_unknown_speed++; break; } switch (active_width) { case IB_LINK_WIDTH_ACTIVE_1X: fs->ports_1X++; break; case IB_LINK_WIDTH_ACTIVE_4X: fs->ports_4X++; break; case IB_LINK_WIDTH_ACTIVE_8X: fs->ports_8X++; break; case IB_LINK_WIDTH_ACTIVE_12X: fs->ports_12X++; break; default: fs->ports_unknown_width++; break; } if (port_state == IB_LINK_DOWN) fs->ports_down++; else if (port_state == IB_LINK_ACTIVE) fs->ports_active++; if (port_phys_state == IB_PORT_PHYS_STATE_DISABLED) { __tag_port_report(&(fs->disabled_ports), cl_ntoh64(node->node_info.node_guid), port, node->print_desc); fs->ports_disabled++; } fs->total_ports++; } } static void portstatus_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { fabric_stats_t fs; struct timeval before, after; char *p_cmd; memset(&fs, 0, sizeof(fs)); p_cmd = next_token(p_last); if (p_cmd) { if (strcmp(p_cmd, "ca") == 0) { fs.node_type_lim = IB_NODE_TYPE_CA; } else if (strcmp(p_cmd, "switch") == 0) { fs.node_type_lim = IB_NODE_TYPE_SWITCH; } else if (strcmp(p_cmd, "router") == 0) { fs.node_type_lim = IB_NODE_TYPE_ROUTER; } else { fprintf(out, "Node type not understood\n"); help_portstatus(out, 1); return; } } gettimeofday(&before, NULL); /* for each node in the system gather the stats */ cl_plock_acquire(&p_osm->lock); cl_qmap_apply_func(&(p_osm->subn.node_guid_tbl), __get_stats, (void *)&fs); cl_plock_release(&p_osm->lock); gettimeofday(&after, NULL); /* report the stats */ fprintf(out, "\"%s\" port status:\n", fs.node_type_lim ? ib_get_node_type_str(fs. node_type_lim) : "ALL"); fprintf(out, " %" PRIu64 " port(s) scanned on %" PRIu64 " nodes in %lu us\n", fs.total_ports, fs.total_nodes, after.tv_usec - before.tv_usec); if (fs.ports_down) fprintf(out, " %" PRIu64 " down\n", fs.ports_down); if (fs.ports_active) fprintf(out, " %" PRIu64 " active\n", fs.ports_active); if (fs.ports_1X) fprintf(out, " %" PRIu64 " at 1X\n", fs.ports_1X); if (fs.ports_4X) fprintf(out, " %" PRIu64 " at 4X\n", fs.ports_4X); if (fs.ports_8X) fprintf(out, " %" PRIu64 " at 8X\n", fs.ports_8X); if (fs.ports_12X) fprintf(out, " %" PRIu64 " at 12X\n", fs.ports_12X); if (fs.ports_sdr) fprintf(out, " %" PRIu64 " at 2.5 Gbps\n", fs.ports_sdr); if (fs.ports_ddr) fprintf(out, " %" PRIu64 " at 5.0 Gbps\n", fs.ports_ddr); if (fs.ports_qdr) fprintf(out, " %" PRIu64 " at 10.0 Gbps\n", fs.ports_qdr); if (fs.ports_disabled + fs.ports_reduced_speed + fs.ports_reduced_width > 0) { fprintf(out, "\nPossible issues:\n"); } if (fs.ports_disabled) { fprintf(out, " %" PRIu64 " disabled\n", fs.ports_disabled); __print_port_report(out, fs.disabled_ports); } if (fs.ports_reduced_speed) { fprintf(out, " %" PRIu64 " with reduced speed\n", fs.ports_reduced_speed); __print_port_report(out, fs.reduced_speed_ports); } if (fs.ports_reduced_width) { fprintf(out, " %" PRIu64 " with reduced width\n", fs.ports_reduced_width); __print_port_report(out, fs.reduced_width_ports); } fprintf(out, "\n"); } static void switchbalance_check(osm_opensm_t * p_osm, osm_switch_t * p_sw, FILE * out, int verbose) { uint8_t port_num; uint8_t num_ports; const cl_qmap_t *p_port_tbl; osm_port_t *p_port; osm_physp_t *p_physp; osm_physp_t *p_rem_physp; osm_node_t *p_rem_node; uint32_t count[255]; /* max ports is a uint8_t */ uint8_t output_ports[255]; uint8_t output_ports_count = 0; uint32_t min_count = 0xFFFFFFFF; uint32_t max_count = 0; unsigned int i; memset(count, '\0', sizeof(uint32_t) * 255); /* Count port usage */ p_port_tbl = &p_osm->subn.port_guid_tbl; for (p_port = (osm_port_t *) cl_qmap_head(p_port_tbl); p_port != (osm_port_t *) cl_qmap_end(p_port_tbl); p_port = (osm_port_t *) cl_qmap_next(&p_port->map_item)) { uint16_t min_lid_ho; uint16_t max_lid_ho; uint16_t lid_ho; /* Don't count switches in port usage */ if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_SWITCH) continue; osm_port_get_lid_range_ho(p_port, &min_lid_ho, &max_lid_ho); if (min_lid_ho == 0 || max_lid_ho == 0) continue; for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) { port_num = osm_switch_get_port_by_lid(p_sw, lid_ho); if (port_num == OSM_NO_PATH) continue; count[port_num]++; } } num_ports = p_sw->num_ports; for (port_num = 1; port_num < num_ports; port_num++) { p_physp = osm_node_get_physp_ptr(p_sw->p_node, port_num); /* if port is down/unhealthy, don't consider it in * min/max calculations */ if (!p_physp || !osm_physp_is_healthy(p_physp) || !osm_physp_get_remote(p_physp)) continue; p_rem_physp = osm_physp_get_remote(p_physp); p_rem_node = osm_physp_get_node_ptr(p_rem_physp); /* If we are directly connected to a CA/router, its not really * up for balancing consideration. */ if (osm_node_get_type(p_rem_node) != IB_NODE_TYPE_SWITCH) continue; output_ports[output_ports_count] = port_num; output_ports_count++; if (count[port_num] < min_count) min_count = count[port_num]; if (count[port_num] > max_count) max_count = count[port_num]; } if (verbose || ((max_count - min_count) > 1)) { if ((max_count - min_count) > 1) fprintf(out, "Unbalanced Switch: 0x%016" PRIx64 " (%s)\n", cl_ntoh64(p_sw->p_node->node_info.node_guid), p_sw->p_node->print_desc); else fprintf(out, "Switch: 0x%016" PRIx64 " (%s)\n", cl_ntoh64(p_sw->p_node->node_info.node_guid), p_sw->p_node->print_desc); for (i = 0; i < output_ports_count; i++) { fprintf(out, "Port %d: %d\n", output_ports[i], count[output_ports[i]]); } } } static void switchbalance_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; uint64_t guid = 0; osm_switch_t *p_sw; int verbose = 0; p_cmd = next_token(p_last); if (p_cmd) { char *p_end; if (strcmp(p_cmd, "verbose") == 0) { verbose++; p_cmd = next_token(p_last); } if (p_cmd) { guid = strtoull(p_cmd, &p_end, 0); if (!guid || *p_end != '\0') { fprintf(out, "Invalid guid specified\n"); help_switchbalance(out, 1); return; } } } cl_plock_acquire(&p_osm->lock); if (guid) { p_sw = osm_get_switch_by_guid(&p_osm->subn, cl_hton64(guid)); if (!p_sw) { fprintf(out, "guid not found\n"); goto lock_exit; } switchbalance_check(p_osm, p_sw, out, verbose); } else { cl_qmap_t *p_sw_guid_tbl = &p_osm->subn.sw_guid_tbl; for (p_sw = (osm_switch_t *) cl_qmap_head(p_sw_guid_tbl); p_sw != (osm_switch_t *) cl_qmap_end(p_sw_guid_tbl); p_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item)) switchbalance_check(p_osm, p_sw, out, verbose); } lock_exit: cl_plock_release(&p_osm->lock); return; } static void lidbalance_check(osm_opensm_t * p_osm, osm_switch_t * p_sw, FILE * out) { uint8_t port_num; const cl_qmap_t *p_port_tbl; osm_port_t *p_port; p_port_tbl = &p_osm->subn.port_guid_tbl; for (p_port = (osm_port_t *) cl_qmap_head(p_port_tbl); p_port != (osm_port_t *) cl_qmap_end(p_port_tbl); p_port = (osm_port_t *) cl_qmap_next(&p_port->map_item)) { uint32_t port_count[255]; /* max ports is a uint8_t */ osm_node_t *rem_node[255]; uint32_t rem_node_count; uint32_t rem_count[255]; osm_physp_t *p_physp; osm_physp_t *p_rem_physp; osm_node_t *p_rem_node; uint32_t port_min_count = 0xFFFFFFFF; uint32_t port_max_count = 0; uint32_t rem_min_count = 0xFFFFFFFF; uint32_t rem_max_count = 0; uint16_t min_lid_ho; uint16_t max_lid_ho; uint16_t lid_ho; uint8_t num_ports; unsigned int i; /* we only care about non-switches */ if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_SWITCH) continue; osm_port_get_lid_range_ho(p_port, &min_lid_ho, &max_lid_ho); if (min_lid_ho == 0 || max_lid_ho == 0) continue; memset(port_count, '\0', sizeof(uint32_t) * 255); memset(rem_node, '\0', sizeof(osm_node_t *) * 255); rem_node_count = 0; memset(rem_count, '\0', sizeof(uint32_t) * 255); for (lid_ho = min_lid_ho; lid_ho <= max_lid_ho; lid_ho++) { boolean_t rem_node_found = FALSE; unsigned int indx = 0; port_num = osm_switch_get_port_by_lid(p_sw, lid_ho); if (port_num == OSM_NO_PATH) continue; p_physp = osm_node_get_physp_ptr(p_sw->p_node, port_num); /* if port is down/unhealthy, can't calculate */ if (!p_physp || !osm_physp_is_healthy(p_physp) || !osm_physp_get_remote(p_physp)) continue; p_rem_physp = osm_physp_get_remote(p_physp); p_rem_node = osm_physp_get_node_ptr(p_rem_physp); /* determine if we've seen this remote node before. * If not, store it. If yes, update the counter */ for (i = 0; i < rem_node_count; i++) { if (rem_node[i] == p_rem_node) { rem_node_found = TRUE; indx = i; break; } } if (!rem_node_found) { rem_node[rem_node_count] = p_rem_node; rem_count[rem_node_count]++; indx = rem_node_count; rem_node_count++; } else rem_count[indx]++; port_count[port_num]++; } if (!rem_node_count) continue; for (i = 0; i < rem_node_count; i++) { if (rem_count[i] < rem_min_count) rem_min_count = rem_count[i]; if (rem_count[i] > rem_max_count) rem_max_count = rem_count[i]; } num_ports = p_sw->num_ports; for (i = 0; i < num_ports; i++) { if (!port_count[i]) continue; if (port_count[i] < port_min_count) port_min_count = port_count[i]; if (port_count[i] > port_max_count) port_max_count = port_count[i]; } /* Output if this CA/router is being forwarded an unbalanced number of * times to a destination. */ if ((rem_max_count - rem_min_count) > 1) { fprintf(out, "Unbalanced Remote Forwarding: Switch 0x%016" PRIx64 " (%s): ", cl_ntoh64(p_sw->p_node->node_info.node_guid), p_sw->p_node->print_desc); if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_CA) fprintf(out, "CA"); else if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_ROUTER) fprintf(out, "Router"); fprintf(out, " 0x%016" PRIx64 " (%s): ", cl_ntoh64(p_port->p_node->node_info.node_guid), p_port->p_node->print_desc); for (i = 0; i < rem_node_count; i++) { fprintf(out, "Dest 0x%016" PRIx64 "(%s) - %u ", cl_ntoh64(rem_node[i]->node_info. node_guid), rem_node[i]->print_desc, rem_count[i]); } fprintf(out, "\n"); } /* Output if this CA/router is being forwarded through a port * an unbalanced number of times. */ if ((port_max_count - port_min_count) > 1) { fprintf(out, "Unbalanced Port Forwarding: Switch 0x%016" PRIx64 " (%s): ", cl_ntoh64(p_sw->p_node->node_info.node_guid), p_sw->p_node->print_desc); if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_CA) fprintf(out, "CA"); else if (osm_node_get_type(p_port->p_node) == IB_NODE_TYPE_ROUTER) fprintf(out, "Router"); fprintf(out, " 0x%016" PRIx64 " (%s): ", cl_ntoh64(p_port->p_node->node_info.node_guid), p_port->p_node->print_desc); for (i = 0; i < num_ports; i++) { if (!port_count[i]) continue; fprintf(out, "Port %u - %u: ", i, port_count[i]); } fprintf(out, "\n"); } } } static void lidbalance_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; uint64_t guid = 0; osm_switch_t *p_sw; p_cmd = next_token(p_last); if (p_cmd) { char *p_end; guid = strtoull(p_cmd, &p_end, 0); if (!guid || *p_end != '\0') { fprintf(out, "Invalid switchguid specified\n"); help_lidbalance(out, 1); return; } } cl_plock_acquire(&p_osm->lock); if (guid) { p_sw = osm_get_switch_by_guid(&p_osm->subn, cl_hton64(guid)); if (!p_sw) { fprintf(out, "switchguid not found\n"); goto lock_exit; } lidbalance_check(p_osm, p_sw, out); } else { cl_qmap_t *p_sw_guid_tbl = &p_osm->subn.sw_guid_tbl; for (p_sw = (osm_switch_t *) cl_qmap_head(p_sw_guid_tbl); p_sw != (osm_switch_t *) cl_qmap_end(p_sw_guid_tbl); p_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item)) lidbalance_check(p_osm, p_sw, out); } lock_exit: cl_plock_release(&p_osm->lock); return; } static void dump_conf_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { osm_subn_output_conf(out, &p_osm->subn.opt); } #ifdef ENABLE_OSM_PERF_MGR static void perfmgr_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { char *p_cmd; p_cmd = next_token(p_last); if (p_cmd) { if (strcmp(p_cmd, "enable") == 0) { osm_perfmgr_set_state(&(p_osm->perfmgr), PERFMGR_STATE_ENABLED); } else if (strcmp(p_cmd, "disable") == 0) { osm_perfmgr_set_state(&(p_osm->perfmgr), PERFMGR_STATE_DISABLE); } else if (strcmp(p_cmd, "clear_counters") == 0) { osm_perfmgr_clear_counters(&(p_osm->perfmgr)); } else if (strcmp(p_cmd, "dump_counters") == 0) { p_cmd = next_token(p_last); if (p_cmd && (strcmp(p_cmd, "mach") == 0)) { osm_perfmgr_dump_counters(&(p_osm->perfmgr), PERFMGR_EVENT_DB_DUMP_MR); } else { osm_perfmgr_dump_counters(&(p_osm->perfmgr), PERFMGR_EVENT_DB_DUMP_HR); } } else if (strcmp(p_cmd, "print_counters") == 0) { p_cmd = next_token(p_last); if (p_cmd) { osm_perfmgr_print_counters(&(p_osm->perfmgr), p_cmd, out); } else { fprintf(out, "print_counters requires a node name to be specified\n"); } } else if (strcmp(p_cmd, "sweep_time") == 0) { p_cmd = next_token(p_last); if (p_cmd) { uint16_t time_s = atoi(p_cmd); osm_perfmgr_set_sweep_time_s(&(p_osm->perfmgr), time_s); } else { fprintf(out, "sweep_time requires a time period (in seconds) to be specified\n"); } } else { fprintf(out, "\"%s\" option not found\n", p_cmd); } } else { fprintf(out, "Performance Manager status:\n" "state : %s\n" "sweep state : %s\n" "sweep time : %us\n" "outstanding queries/max : %d/%u\n", osm_perfmgr_get_state_str(&(p_osm->perfmgr)), osm_perfmgr_get_sweep_state_str(&(p_osm->perfmgr)), osm_perfmgr_get_sweep_time_s(&(p_osm->perfmgr)), p_osm->perfmgr.outstanding_queries, p_osm->perfmgr.max_outstanding_queries); } } #endif /* ENABLE_OSM_PERF_MGR */ static void quit_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { osm_console_exit(&p_osm->console, &p_osm->log); } static void help_version(FILE * out, int detail) { fprintf(out, "version -- print the OSM version\n"); } static void version_parse(char **p_last, osm_opensm_t * p_osm, FILE * out) { fprintf(out, "%s build %s %s\n", p_osm->osm_version, __DATE__, __TIME__); } /* more parse routines go here */ static const struct command console_cmds[] = { {"help", &help_command, &help_parse}, {"quit", &help_quit, &quit_parse}, {"loglevel", &help_loglevel, &loglevel_parse}, {"priority", &help_priority, &priority_parse}, {"resweep", &help_resweep, &resweep_parse}, {"reroute", &help_reroute, &reroute_parse}, {"status", &help_status, &status_parse}, {"logflush", &help_logflush, &logflush_parse}, {"querylid", &help_querylid, &querylid_parse}, {"portstatus", &help_portstatus, &portstatus_parse}, {"switchbalance", &help_switchbalance, &switchbalance_parse}, {"lidbalance", &help_lidbalance, &lidbalance_parse}, {"dump_conf", &help_dump_conf, &dump_conf_parse}, {"version", &help_version, &version_parse}, #ifdef ENABLE_OSM_PERF_MGR {"perfmgr", &help_perfmgr, &perfmgr_parse}, #endif /* ENABLE_OSM_PERF_MGR */ {NULL, NULL, NULL} /* end of array */ }; static void parse_cmd_line(char *line, osm_opensm_t * p_osm) { char *p_cmd, *p_last; int i, found = 0; FILE *out = p_osm->console.out; while (isspace(*line)) line++; if (!*line) return; /* find first token which is the command */ p_cmd = strtok_r(line, " \t\n\r", &p_last); if (p_cmd) { for (i = 0; console_cmds[i].name; i++) { if (loop_command.on) { if (!strcmp(p_cmd, "q")) { loop_command.on = 0; } found = 1; break; } if (!strcmp(p_cmd, console_cmds[i].name)) { found = 1; console_cmds[i].parse_function(&p_last, p_osm, out); break; } } if (!found) { fprintf(out, "%s : Command not found\n\n", p_cmd); help_command(out, 0); } } else { fprintf(out, "Error parsing command line: `%s'\n", line); } if (loop_command.on) { fprintf(out, "use \"q\" to quit loop\n"); fflush(out); } } void osm_console(osm_opensm_t * p_osm) { struct pollfd pollfd[2]; char *p_line; size_t len; ssize_t n; struct pollfd *fds; nfds_t nfds; osm_console_t *p_oct = &p_osm->console; osm_log_t *p_log = &p_osm->log; pollfd[0].fd = p_oct->socket; pollfd[0].events = POLLIN; pollfd[0].revents = 0; pollfd[1].fd = p_oct->in_fd; pollfd[1].events = POLLIN; pollfd[1].revents = 0; fds = p_oct->socket < 0 ? &pollfd[1] : pollfd; nfds = p_oct->socket < 0 || pollfd[1].fd < 0 ? 1 : 2; if (loop_command.on && loop_command_check_time() && loop_command.loop_function) { if (p_oct->out) { loop_command.loop_function(p_osm, p_oct->out); fflush(p_oct->out); } else { loop_command.on = 0; } } if (poll(fds, nfds, 1000) <= 0) return; #ifdef ENABLE_OSM_CONSOLE_SOCKET if (pollfd[0].revents & POLLIN) { int new_fd = 0; struct sockaddr_in sin; socklen_t len = sizeof(sin); struct hostent *hent; if ((new_fd = accept(p_oct->socket, &sin, &len)) < 0) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4B04: Failed to accept console socket: %s\n", strerror(errno)); p_oct->in_fd = -1; return; } if (inet_ntop (AF_INET, &sin.sin_addr, p_oct->client_ip, sizeof(p_oct->client_ip)) == NULL) { snprintf(p_oct->client_ip, 64, "STRING_UNKNOWN"); } if ((hent = gethostbyaddr((const char *)&sin.sin_addr, sizeof(struct in_addr), AF_INET)) == NULL) { snprintf(p_oct->client_hn, 128, "STRING_UNKNOWN"); } else { snprintf(p_oct->client_hn, 128, "%s", hent->h_name); } if (is_authorized(p_oct)) { cio_open(p_oct, new_fd, p_log); } else { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 4B05: Console connection denied: %s (%s)\n", p_oct->client_hn, p_oct->client_ip); close(new_fd); } return; } #endif if (pollfd[1].revents & POLLIN) { p_line = NULL; /* Get input line */ n = getline(&p_line, &len, p_oct->in); if (n > 0) { /* Parse and act on input */ parse_cmd_line(p_line, p_osm); if (!loop_command.on) { osm_console_prompt(p_oct->out); } } else osm_console_exit(p_oct, p_log); if (p_line) free(p_line); } } diff --git a/contrib/ofed/management/opensm/opensm/osm_subnet.c b/contrib/ofed/management/opensm/opensm/osm_subnet.c index c41962d6c756..558027ce1bd1 100644 --- a/contrib/ofed/management/opensm/opensm/osm_subnet.c +++ b/contrib/ofed/management/opensm/opensm/osm_subnet.c @@ -1,1719 +1,1719 @@ /* * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. * Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved. * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. * Copyright (c) 2008 Xsigo Systems Inc. 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. * */ /* * Abstract: * Implementation of osm_subn_t. * This object represents an IBA subnet. * This object is part of the opensm family of objects. */ #if HAVE_CONFIG_H # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char null_str[] = "(null)"; /********************************************************************** **********************************************************************/ void osm_subn_construct(IN osm_subn_t * const p_subn) { memset(p_subn, 0, sizeof(*p_subn)); cl_ptr_vector_construct(&p_subn->port_lid_tbl); cl_qmap_init(&p_subn->sw_guid_tbl); cl_qmap_init(&p_subn->node_guid_tbl); cl_qmap_init(&p_subn->port_guid_tbl); cl_qmap_init(&p_subn->sm_guid_tbl); cl_qlist_init(&p_subn->sa_sr_list); cl_qlist_init(&p_subn->sa_infr_list); cl_qlist_init(&p_subn->prefix_routes_list); cl_qmap_init(&p_subn->rtr_guid_tbl); cl_qmap_init(&p_subn->prtn_pkey_tbl); } /********************************************************************** **********************************************************************/ void osm_subn_destroy(IN osm_subn_t * const p_subn) { int i; osm_node_t *p_node, *p_next_node; osm_port_t *p_port, *p_next_port; osm_switch_t *p_sw, *p_next_sw; osm_remote_sm_t *p_rsm, *p_next_rsm; osm_prtn_t *p_prtn, *p_next_prtn; osm_mgrp_t *p_mgrp; osm_infr_t *p_infr, *p_next_infr; /* it might be a good idea to de-allocate all known objects */ p_next_node = (osm_node_t *) cl_qmap_head(&p_subn->node_guid_tbl); while (p_next_node != (osm_node_t *) cl_qmap_end(&p_subn->node_guid_tbl)) { p_node = p_next_node; p_next_node = (osm_node_t *) cl_qmap_next(&p_node->map_item); osm_node_delete(&p_node); } p_next_port = (osm_port_t *) cl_qmap_head(&p_subn->port_guid_tbl); while (p_next_port != (osm_port_t *) cl_qmap_end(&p_subn->port_guid_tbl)) { p_port = p_next_port; p_next_port = (osm_port_t *) cl_qmap_next(&p_port->map_item); osm_port_delete(&p_port); } p_next_sw = (osm_switch_t *) cl_qmap_head(&p_subn->sw_guid_tbl); while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_subn->sw_guid_tbl)) { p_sw = p_next_sw; p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item); osm_switch_delete(&p_sw); } p_next_rsm = (osm_remote_sm_t *) cl_qmap_head(&p_subn->sm_guid_tbl); while (p_next_rsm != (osm_remote_sm_t *) cl_qmap_end(&p_subn->sm_guid_tbl)) { p_rsm = p_next_rsm; p_next_rsm = (osm_remote_sm_t *) cl_qmap_next(&p_rsm->map_item); free(p_rsm); } p_next_prtn = (osm_prtn_t *) cl_qmap_head(&p_subn->prtn_pkey_tbl); while (p_next_prtn != (osm_prtn_t *) cl_qmap_end(&p_subn->prtn_pkey_tbl)) { p_prtn = p_next_prtn; p_next_prtn = (osm_prtn_t *) cl_qmap_next(&p_prtn->map_item); osm_prtn_delete(&p_prtn); } for (i = 0; i <= p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO; i++) { p_mgrp = p_subn->mgroups[i]; p_subn->mgroups[i] = NULL; if (p_mgrp) osm_mgrp_delete(p_mgrp); } p_next_infr = (osm_infr_t *) cl_qlist_head(&p_subn->sa_infr_list); while (p_next_infr != (osm_infr_t *) cl_qlist_end(&p_subn->sa_infr_list)) { p_infr = p_next_infr; p_next_infr = (osm_infr_t *) cl_qlist_next(&p_infr->list_item); osm_infr_delete(p_infr); } cl_ptr_vector_destroy(&p_subn->port_lid_tbl); osm_qos_policy_destroy(p_subn->p_qos_policy); while (!cl_is_qlist_empty(&p_subn->prefix_routes_list)) { cl_list_item_t *item = cl_qlist_remove_head(&p_subn->prefix_routes_list); free(item); } } /********************************************************************** **********************************************************************/ ib_api_status_t osm_subn_init(IN osm_subn_t * const p_subn, IN osm_opensm_t * const p_osm, IN const osm_subn_opt_t * const p_opt) { cl_status_t status; p_subn->p_osm = p_osm; status = cl_ptr_vector_init(&p_subn->port_lid_tbl, OSM_SUBNET_VECTOR_MIN_SIZE, OSM_SUBNET_VECTOR_GROW_SIZE); if (status != CL_SUCCESS) return (status); status = cl_ptr_vector_set_capacity(&p_subn->port_lid_tbl, OSM_SUBNET_VECTOR_CAPACITY); if (status != CL_SUCCESS) return (status); /* LID zero is not valid. NULL out this entry for the convenience of other code. */ cl_ptr_vector_set(&p_subn->port_lid_tbl, 0, NULL); p_subn->opt = *p_opt; p_subn->max_ucast_lid_ho = IB_LID_UCAST_END_HO; p_subn->max_mcast_lid_ho = IB_LID_MCAST_END_HO; p_subn->min_ca_mtu = IB_MAX_MTU; p_subn->min_ca_rate = IB_MAX_RATE; p_subn->ignore_existing_lfts = TRUE; /* we assume master by default - so we only need to set it true if STANDBY */ p_subn->coming_out_of_standby = FALSE; return (IB_SUCCESS); } /********************************************************************** **********************************************************************/ ib_api_status_t osm_get_gid_by_mad_addr(IN osm_log_t * p_log, IN const osm_subn_t * p_subn, IN const osm_mad_addr_t * p_mad_addr, OUT ib_gid_t * p_gid) { const cl_ptr_vector_t *p_tbl; const osm_port_t *p_port = NULL; if (p_gid == NULL) { OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7505: " "Provided output GID is NULL\n"); return (IB_INVALID_PARAMETER); } /* Find the port gid of the request in the subnet */ p_tbl = &p_subn->port_lid_tbl; CL_ASSERT(cl_ptr_vector_get_size(p_tbl) < 0x10000); if ((uint16_t) cl_ptr_vector_get_size(p_tbl) > cl_ntoh16(p_mad_addr->dest_lid)) { p_port = cl_ptr_vector_get(p_tbl, cl_ntoh16(p_mad_addr->dest_lid)); if (p_port == NULL) { OSM_LOG(p_log, OSM_LOG_DEBUG, "Did not find any port with LID: %u\n", cl_ntoh16(p_mad_addr->dest_lid)); return (IB_INVALID_PARAMETER); } p_gid->unicast.interface_id = p_port->p_physp->port_guid; p_gid->unicast.prefix = p_subn->opt.subnet_prefix; } else { /* The dest_lid is not in the subnet table - this is an error */ OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7501: " "LID is out of range: %u\n", cl_ntoh16(p_mad_addr->dest_lid)); return (IB_INVALID_PARAMETER); } return (IB_SUCCESS); } /********************************************************************** **********************************************************************/ osm_physp_t *osm_get_physp_by_mad_addr(IN osm_log_t * p_log, IN const osm_subn_t * p_subn, IN osm_mad_addr_t * p_mad_addr) { const cl_ptr_vector_t *p_port_lid_tbl; osm_port_t *p_port = NULL; osm_physp_t *p_physp = NULL; /* Find the port gid of the request in the subnet */ p_port_lid_tbl = &p_subn->port_lid_tbl; CL_ASSERT(cl_ptr_vector_get_size(p_port_lid_tbl) < 0x10000); if ((uint16_t) cl_ptr_vector_get_size(p_port_lid_tbl) > cl_ntoh16(p_mad_addr->dest_lid)) { p_port = cl_ptr_vector_get(p_port_lid_tbl, cl_ntoh16(p_mad_addr->dest_lid)); if (p_port == NULL) { /* The port is not in the port_lid table - this is an error */ OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7502: " "Cannot locate port object by lid: %u\n", cl_ntoh16(p_mad_addr->dest_lid)); goto Exit; } p_physp = p_port->p_physp; } else { /* The dest_lid is not in the subnet table - this is an error */ OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7503: " "Lid is out of range: %u\n", cl_ntoh16(p_mad_addr->dest_lid)); } Exit: return p_physp; } /********************************************************************** **********************************************************************/ osm_port_t *osm_get_port_by_mad_addr(IN osm_log_t * p_log, IN const osm_subn_t * p_subn, IN osm_mad_addr_t * p_mad_addr) { const cl_ptr_vector_t *p_port_lid_tbl; osm_port_t *p_port = NULL; /* Find the port gid of the request in the subnet */ p_port_lid_tbl = &p_subn->port_lid_tbl; CL_ASSERT(cl_ptr_vector_get_size(p_port_lid_tbl) < 0x10000); if ((uint16_t) cl_ptr_vector_get_size(p_port_lid_tbl) > cl_ntoh16(p_mad_addr->dest_lid)) { p_port = cl_ptr_vector_get(p_port_lid_tbl, cl_ntoh16(p_mad_addr->dest_lid)); } else { /* The dest_lid is not in the subnet table - this is an error */ OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7504: " "Lid is out of range: %u\n", cl_ntoh16(p_mad_addr->dest_lid)); } return p_port; } /********************************************************************** **********************************************************************/ osm_switch_t *osm_get_switch_by_guid(IN const osm_subn_t * p_subn, IN uint64_t guid) { osm_switch_t *p_switch; p_switch = (osm_switch_t *) cl_qmap_get(&(p_subn->sw_guid_tbl), guid); if (p_switch == (osm_switch_t *) cl_qmap_end(&(p_subn->sw_guid_tbl))) p_switch = NULL; return p_switch; } /********************************************************************** **********************************************************************/ osm_node_t *osm_get_node_by_guid(IN osm_subn_t const *p_subn, IN uint64_t guid) { osm_node_t *p_node; p_node = (osm_node_t *) cl_qmap_get(&(p_subn->node_guid_tbl), guid); if (p_node == (osm_node_t *) cl_qmap_end(&(p_subn->node_guid_tbl))) p_node = NULL; return p_node; } /********************************************************************** **********************************************************************/ osm_port_t *osm_get_port_by_guid(IN osm_subn_t const *p_subn, IN ib_net64_t guid) { osm_port_t *p_port; p_port = (osm_port_t *) cl_qmap_get(&(p_subn->port_guid_tbl), guid); if (p_port == (osm_port_t *) cl_qmap_end(&(p_subn->port_guid_tbl))) p_port = NULL; return p_port; } /********************************************************************** **********************************************************************/ static void subn_set_default_qos_options(IN osm_qos_options_t * opt) { opt->max_vls = OSM_DEFAULT_QOS_MAX_VLS; opt->high_limit = OSM_DEFAULT_QOS_HIGH_LIMIT; opt->vlarb_high = OSM_DEFAULT_QOS_VLARB_HIGH; opt->vlarb_low = OSM_DEFAULT_QOS_VLARB_LOW; opt->sl2vl = OSM_DEFAULT_QOS_SL2VL; } static void subn_init_qos_options(IN osm_qos_options_t * opt) { opt->max_vls = 0; opt->high_limit = -1; opt->vlarb_high = NULL; opt->vlarb_low = NULL; opt->sl2vl = NULL; } /********************************************************************** **********************************************************************/ void osm_subn_set_default_opt(IN osm_subn_opt_t * const p_opt) { memset(p_opt, 0, sizeof(osm_subn_opt_t)); p_opt->guid = 0; p_opt->m_key = OSM_DEFAULT_M_KEY; p_opt->sm_key = OSM_DEFAULT_SM_KEY; p_opt->sa_key = OSM_DEFAULT_SA_KEY; p_opt->subnet_prefix = IB_DEFAULT_SUBNET_PREFIX; p_opt->m_key_lease_period = 0; p_opt->sweep_interval = OSM_DEFAULT_SWEEP_INTERVAL_SECS; p_opt->max_wire_smps = OSM_DEFAULT_SMP_MAX_ON_WIRE; p_opt->console = OSM_DEFAULT_CONSOLE; p_opt->console_port = OSM_DEFAULT_CONSOLE_PORT; p_opt->transaction_timeout = OSM_DEFAULT_TRANS_TIMEOUT_MILLISEC; /* by default we will consider waiting for 50x transaction timeout normal */ p_opt->max_msg_fifo_timeout = 50 * OSM_DEFAULT_TRANS_TIMEOUT_MILLISEC; p_opt->sm_priority = OSM_DEFAULT_SM_PRIORITY; p_opt->lmc = OSM_DEFAULT_LMC; p_opt->lmc_esp0 = FALSE; p_opt->max_op_vls = OSM_DEFAULT_MAX_OP_VLS; p_opt->force_link_speed = 15; p_opt->reassign_lids = FALSE; p_opt->ignore_other_sm = FALSE; p_opt->single_thread = FALSE; p_opt->disable_multicast = FALSE; p_opt->force_log_flush = FALSE; p_opt->subnet_timeout = OSM_DEFAULT_SUBNET_TIMEOUT; p_opt->packet_life_time = OSM_DEFAULT_SWITCH_PACKET_LIFE; p_opt->vl_stall_count = OSM_DEFAULT_VL_STALL_COUNT; p_opt->leaf_vl_stall_count = OSM_DEFAULT_LEAF_VL_STALL_COUNT; p_opt->head_of_queue_lifetime = OSM_DEFAULT_HEAD_OF_QUEUE_LIFE; p_opt->leaf_head_of_queue_lifetime = OSM_DEFAULT_LEAF_HEAD_OF_QUEUE_LIFE; p_opt->local_phy_errors_threshold = OSM_DEFAULT_ERROR_THRESHOLD; p_opt->overrun_errors_threshold = OSM_DEFAULT_ERROR_THRESHOLD; p_opt->sminfo_polling_timeout = OSM_SM_DEFAULT_POLLING_TIMEOUT_MILLISECS; p_opt->polling_retry_number = OSM_SM_DEFAULT_POLLING_RETRY_NUMBER; p_opt->force_heavy_sweep = FALSE; p_opt->log_flags = OSM_LOG_DEFAULT_LEVEL; p_opt->honor_guid2lid_file = FALSE; p_opt->daemon = FALSE; p_opt->sm_inactive = FALSE; p_opt->babbling_port_policy = FALSE; #ifdef ENABLE_OSM_PERF_MGR p_opt->perfmgr = FALSE; p_opt->perfmgr_redir = TRUE; p_opt->perfmgr_sweep_time_s = OSM_PERFMGR_DEFAULT_SWEEP_TIME_S; p_opt->perfmgr_max_outstanding_queries = OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES; p_opt->event_db_dump_file = NULL; /* use default */ #endif /* ENABLE_OSM_PERF_MGR */ p_opt->event_plugin_name = NULL; p_opt->node_name_map_name = NULL; p_opt->dump_files_dir = getenv("OSM_TMP_DIR"); if (!p_opt->dump_files_dir || !(*p_opt->dump_files_dir)) p_opt->dump_files_dir = OSM_DEFAULT_TMP_DIR; p_opt->log_file = OSM_DEFAULT_LOG_FILE; p_opt->log_max_size = 0; p_opt->partition_config_file = OSM_DEFAULT_PARTITION_CONFIG_FILE; p_opt->no_partition_enforcement = FALSE; p_opt->qos = FALSE; p_opt->qos_policy_file = OSM_DEFAULT_QOS_POLICY_FILE; p_opt->accum_log_file = TRUE; p_opt->port_prof_ignore_file = NULL; p_opt->port_profile_switch_nodes = FALSE; p_opt->sweep_on_trap = TRUE; p_opt->use_ucast_cache = FALSE; p_opt->routing_engine_names = NULL; p_opt->connect_roots = FALSE; p_opt->lid_matrix_dump_file = NULL; p_opt->lfts_file = NULL; p_opt->root_guid_file = NULL; p_opt->cn_guid_file = NULL; p_opt->ids_guid_file = NULL; p_opt->guid_routing_order_file = NULL; p_opt->sa_db_file = NULL; p_opt->exit_on_fatal = TRUE; p_opt->enable_quirks = FALSE; p_opt->no_clients_rereg = FALSE; p_opt->prefix_routes_file = OSM_DEFAULT_PREFIX_ROUTES_FILE; p_opt->consolidate_ipv6_snm_req = FALSE; subn_init_qos_options(&p_opt->qos_options); subn_init_qos_options(&p_opt->qos_ca_options); subn_init_qos_options(&p_opt->qos_sw0_options); subn_init_qos_options(&p_opt->qos_swe_options); subn_init_qos_options(&p_opt->qos_rtr_options); } /********************************************************************** **********************************************************************/ static void log_report(const char *fmt, ...) { char buf[128]; va_list args; va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); - printf(buf); + printf("%s", buf); cl_log_event("OpenSM", CL_LOG_INFO, buf, NULL, 0); } static void log_config_value(char *name, const char *fmt, ...) { char buf[128]; va_list args; unsigned n; va_start(args, fmt); n = snprintf(buf, sizeof(buf), " Loading Cached Option:%s = ", name); if (n > sizeof(buf)) n = sizeof(buf); n += vsnprintf(buf + n, sizeof(buf) - n, fmt, args); if (n > sizeof(buf)) n = sizeof(buf); snprintf(buf + n, sizeof(buf) - n, "\n"); va_end(args); - printf(buf); + printf("%s", buf); cl_log_event("OpenSM", CL_LOG_INFO, buf, NULL, 0); } static void opts_unpack_net64(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN uint64_t * p_val) { if (!strcmp(p_req_key, p_key)) { uint64_t val = strtoull(p_val_str, NULL, 0); if (cl_hton64(val) != *p_val) { log_config_value(p_key, "0x%016" PRIx64, val); *p_val = cl_ntoh64(val); } } } /********************************************************************** **********************************************************************/ static void opts_unpack_uint32(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN uint32_t * p_val) { if (!strcmp(p_req_key, p_key)) { uint32_t val = strtoul(p_val_str, NULL, 0); if (val != *p_val) { log_config_value(p_key, "%u", val); *p_val = val; } } } /********************************************************************** **********************************************************************/ static void opts_unpack_int32(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN int32_t * p_val) { if (!strcmp(p_req_key, p_key)) { int32_t val = strtol(p_val_str, NULL, 0); if (val != *p_val) { log_config_value(p_key, "%d", val); *p_val = val; } } } /********************************************************************** **********************************************************************/ static void opts_unpack_uint16(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN uint16_t * p_val) { if (!strcmp(p_req_key, p_key)) { uint16_t val = (uint16_t) strtoul(p_val_str, NULL, 0); if (val != *p_val) { log_config_value(p_key, "%u", val); *p_val = val; } } } /********************************************************************** **********************************************************************/ static void opts_unpack_net16(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN uint16_t * p_val) { if (!strcmp(p_req_key, p_key)) { uint32_t val; val = strtoul(p_val_str, NULL, 0); CL_ASSERT(val < 0x10000); if (cl_hton32(val) != *p_val) { log_config_value(p_key, "0x%04x", val); *p_val = cl_hton16((uint16_t) val); } } } /********************************************************************** **********************************************************************/ static void opts_unpack_uint8(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN uint8_t * p_val) { if (!strcmp(p_req_key, p_key)) { uint32_t val; val = strtoul(p_val_str, NULL, 0); CL_ASSERT(val < 0x100); if (val != *p_val) { log_config_value(p_key, "%u", val); *p_val = (uint8_t) val; } } } /********************************************************************** **********************************************************************/ static void opts_unpack_boolean(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN boolean_t * p_val) { if (!strcmp(p_req_key, p_key) && p_val_str) { boolean_t val; if (strcmp("TRUE", p_val_str)) val = FALSE; else val = TRUE; if (val != *p_val) { log_config_value(p_key, "%s", p_val_str); *p_val = val; } } } /********************************************************************** **********************************************************************/ static void opts_unpack_charp(IN char *p_req_key, IN char *p_key, IN char *p_val_str, IN char **p_val) { if (!strcmp(p_req_key, p_key) && p_val_str) { const char *current_str = *p_val ? *p_val : null_str ; if (strcmp(p_val_str, current_str)) { log_config_value(p_key, "%s", p_val_str); /* special case the "(null)" string */ if (strcmp(null_str, p_val_str) == 0) { *p_val = NULL; } else { /* Ignore the possible memory leak here; the pointer may be to a static default. */ *p_val = strdup(p_val_str); } } } } /********************************************************************** **********************************************************************/ static char *clean_val(char *val) { char *p = val; /* clean leading spaces */ while (isspace(*p)) p++; val = p; if (!*val) return val; /* clean trailing spaces */ p = val + strlen(val) - 1; while (p > val && isspace(*p)) p--; p[1] = '\0'; /* clean quotas */ if ((*val == '\"' && *p == '\"') || (*val == '\'' && *p == '\'')) { val++; p--; } return val; } /********************************************************************** **********************************************************************/ static void subn_parse_qos_options(IN const char *prefix, IN char *p_key, IN char *p_val_str, IN osm_qos_options_t * opt) { char name[256]; snprintf(name, sizeof(name), "%s_max_vls", prefix); opts_unpack_uint32(name, p_key, p_val_str, &opt->max_vls); snprintf(name, sizeof(name), "%s_high_limit", prefix); opts_unpack_int32(name, p_key, p_val_str, &opt->high_limit); snprintf(name, sizeof(name), "%s_vlarb_high", prefix); opts_unpack_charp(name, p_key, p_val_str, &opt->vlarb_high); snprintf(name, sizeof(name), "%s_vlarb_low", prefix); opts_unpack_charp(name, p_key, p_val_str, &opt->vlarb_low); snprintf(name, sizeof(name), "%s_sl2vl", prefix); opts_unpack_charp(name, p_key, p_val_str, &opt->sl2vl); } static int subn_dump_qos_options(FILE * file, const char *set_name, const char *prefix, osm_qos_options_t * opt) { return fprintf(file, "# %s\n" "%s_max_vls %u\n" "%s_high_limit %d\n" "%s_vlarb_high %s\n" "%s_vlarb_low %s\n" "%s_sl2vl %s\n", set_name, prefix, opt->max_vls, prefix, opt->high_limit, prefix, opt->vlarb_high, prefix, opt->vlarb_low, prefix, opt->sl2vl); } /********************************************************************** **********************************************************************/ static ib_api_status_t append_prefix_route(IN osm_subn_t * const p_subn, uint64_t prefix, uint64_t guid) { osm_prefix_route_t *route; route = malloc(sizeof *route); if (! route) { OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "out of memory"); return IB_ERROR; } route->prefix = cl_hton64(prefix); route->guid = cl_hton64(guid); cl_qlist_insert_tail(&p_subn->prefix_routes_list, &route->list_item); return IB_SUCCESS; } static ib_api_status_t osm_parse_prefix_routes_file(IN osm_subn_t * const p_subn) { osm_log_t *log = &p_subn->p_osm->log; FILE *fp; char buf[1024]; int line = 0; int errors = 0; while (!cl_is_qlist_empty(&p_subn->prefix_routes_list)) { cl_list_item_t *item = cl_qlist_remove_head(&p_subn->prefix_routes_list); free(item); } fp = fopen(p_subn->opt.prefix_routes_file, "r"); if (! fp) { if (errno == ENOENT) return IB_SUCCESS; OSM_LOG(log, OSM_LOG_ERROR, "fopen(%s) failed: %s", p_subn->opt.prefix_routes_file, strerror(errno)); return IB_ERROR; } while (fgets(buf, sizeof buf, fp) != NULL) { char *p_prefix, *p_guid, *p_extra, *p_last, *p_end; uint64_t prefix, guid; line++; if (errors > 10) break; p_prefix = strtok_r(buf, " \t\n", &p_last); if (! p_prefix) continue; /* ignore blank lines */ if (*p_prefix == '#') continue; /* ignore comment lines */ p_guid = strtok_r(NULL, " \t\n", &p_last); if (! p_guid) { OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: missing GUID\n", p_subn->opt.prefix_routes_file, line); errors++; continue; } p_extra = strtok_r(NULL, " \t\n", &p_last); if (p_extra && *p_extra != '#') { OSM_LOG(log, OSM_LOG_INFO, "%s:%d: extra tokens ignored\n", p_subn->opt.prefix_routes_file, line); } if (strcmp(p_prefix, "*") == 0) prefix = 0; else { prefix = strtoull(p_prefix, &p_end, 16); if (*p_end != '\0') { OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: illegal prefix: %s\n", p_subn->opt.prefix_routes_file, line, p_prefix); errors++; continue; } } if (strcmp(p_guid, "*") == 0) guid = 0; else { guid = strtoull(p_guid, &p_end, 16); if (*p_end != '\0' && *p_end != '#') { OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: illegal GUID: %s\n", p_subn->opt.prefix_routes_file, line, p_guid); errors++; continue; } } if (append_prefix_route(p_subn, prefix, guid) != IB_SUCCESS) { errors++; break; } } fclose(fp); return (errors == 0) ? IB_SUCCESS : IB_ERROR; } /********************************************************************** **********************************************************************/ static void subn_verify_max_vls(unsigned *max_vls, const char *prefix, unsigned dflt) { if (!(*max_vls) || *max_vls > 15) { log_report(" Invalid Cached Option: %s_max_vls=%u: " "Using Default = %u\n", prefix, *max_vls, dflt); *max_vls = dflt; } } static void subn_verify_high_limit(int *high_limit, const char *prefix, int dflt) { if (*high_limit < 0 || *high_limit > 255) { log_report(" Invalid Cached Option: %s_high_limit=%d: " "Using Default: %d\n", prefix, *high_limit, dflt); *high_limit = dflt; } } static void subn_verify_vlarb(char **vlarb, const char *prefix, const char *suffix, char *dflt) { char *str, *tok, *end, *ptr; int count = 0; if (*vlarb == NULL) { log_report(" Invalid Cached Option: %s_vlarb_%s: " "Using Default\n", prefix, suffix); *vlarb = dflt; return; } str = strdup(*vlarb); tok = strtok_r(str, ",\n", &ptr); while (tok) { char *vl_str, *weight_str; vl_str = tok; weight_str = strchr(tok, ':'); if (weight_str) { long vl, weight; *weight_str = '\0'; weight_str++; vl = strtol(vl_str, &end, 0); if (*end) log_report(" Warning: Cached Option " "%s_vlarb_%s:vl=%s" " improperly formatted\n", prefix, suffix, vl_str); else if (vl < 0 || vl > 14) log_report(" Warning: Cached Option " "%s_vlarb_%s:vl=%ld out of range\n", prefix, suffix, vl); weight = strtol(weight_str, &end, 0); if (*end) log_report(" Warning: Cached Option " "%s_vlarb_%s:weight=%s " "improperly formatted\n", prefix, suffix, weight_str); else if (weight < 0 || weight > 255) log_report(" Warning: Cached Option " "%s_vlarb_%s:weight=%ld " "out of range\n", prefix, suffix, weight); } else log_report(" Warning: Cached Option " "%s_vlarb_%s:vl:weight=%s " "improperly formatted\n", prefix, suffix, tok); count++; tok = strtok_r(NULL, ",\n", &ptr); } if (count > 64) log_report(" Warning: Cached Option %s_vlarb_%s: > 64 listed:" " excess vl:weight pairs will be dropped\n", prefix, suffix); free(str); } static void subn_verify_sl2vl(char **sl2vl, const char *prefix, char *dflt) { char *str, *tok, *end, *ptr; int count = 0; if (*sl2vl == NULL) { log_report(" Invalid Cached Option: %s_sl2vl: Using Default\n", prefix); *sl2vl = dflt; return; } str = strdup(*sl2vl); tok = strtok_r(str, ",\n", &ptr); while (tok) { long vl = strtol(tok, &end, 0); if (*end) log_report(" Warning: Cached Option %s_sl2vl:vl=%s " "improperly formatted\n", prefix, tok); else if (vl < 0 || vl > 15) log_report(" Warning: Cached Option %s_sl2vl:vl=%ld " "out of range\n", prefix, vl); count++; tok = strtok_r(NULL, ",\n", &ptr); } if (count < 16) log_report(" Warning: Cached Option %s_sl2vl: < 16 VLs " "listed\n", prefix); if (count > 16) log_report(" Warning: Cached Option %s_sl2vl: > 16 listed: " "excess VLs will be dropped\n", prefix); free(str); } static void subn_verify_qos_set(osm_qos_options_t *set, const char *prefix, osm_qos_options_t *dflt) { subn_verify_max_vls(&set->max_vls, prefix, dflt->max_vls); subn_verify_high_limit(&set->high_limit, prefix, dflt->high_limit); subn_verify_vlarb(&set->vlarb_low, prefix, "low", dflt->vlarb_low); subn_verify_vlarb(&set->vlarb_high, prefix, "high", dflt->vlarb_high); subn_verify_sl2vl(&set->sl2vl, prefix, dflt->sl2vl); } int osm_subn_verify_config(IN osm_subn_opt_t * const p_opts) { if (p_opts->lmc > 7) { log_report(" Invalid Cached Option Value:lmc = %u:" "Using Default:%u\n", p_opts->lmc, OSM_DEFAULT_LMC); p_opts->lmc = OSM_DEFAULT_LMC; } if (15 < p_opts->sm_priority) { log_report(" Invalid Cached Option Value:sm_priority = %u:" "Using Default:%u\n", p_opts->sm_priority, OSM_DEFAULT_SM_PRIORITY); p_opts->sm_priority = OSM_DEFAULT_SM_PRIORITY; } if ((15 < p_opts->force_link_speed) || (p_opts->force_link_speed > 7 && p_opts->force_link_speed < 15)) { log_report(" Invalid Cached Option Value:force_link_speed = %u:" "Using Default:%u\n", p_opts->force_link_speed, IB_PORT_LINK_SPEED_ENABLED_MASK); p_opts->force_link_speed = IB_PORT_LINK_SPEED_ENABLED_MASK; } if (strcmp(p_opts->console, OSM_DISABLE_CONSOLE) && strcmp(p_opts->console, OSM_LOCAL_CONSOLE) #ifdef ENABLE_OSM_CONSOLE_SOCKET && strcmp(p_opts->console, OSM_LOOPBACK_CONSOLE) && strcmp(p_opts->console, OSM_REMOTE_CONSOLE) #endif ) { log_report(" Invalid Cached Option Value:console = %s" ", Using Default:%s\n", p_opts->console, OSM_DEFAULT_CONSOLE); p_opts->console = OSM_DEFAULT_CONSOLE; } if (p_opts->qos) { osm_qos_options_t dflt; /* the default options in qos_options must be correct. * every other one need not be, b/c those will default * back to whatever is in qos_options. */ subn_set_default_qos_options(&dflt); subn_verify_qos_set(&p_opts->qos_options, "qos", &dflt); subn_verify_qos_set(&p_opts->qos_ca_options, "qos_ca", &p_opts->qos_options); subn_verify_qos_set(&p_opts->qos_sw0_options, "qos_sw0", &p_opts->qos_options); subn_verify_qos_set(&p_opts->qos_swe_options, "qos_swe", &p_opts->qos_options); subn_verify_qos_set(&p_opts->qos_rtr_options, "qos_rtr", &p_opts->qos_options); } #ifdef ENABLE_OSM_PERF_MGR if (p_opts->perfmgr_sweep_time_s < 1) { log_report(" Invalid Cached Option Value:perfmgr_sweep_time_s " "= %u Using Default:%u\n", p_opts->perfmgr_sweep_time_s, OSM_PERFMGR_DEFAULT_SWEEP_TIME_S); p_opts->perfmgr_sweep_time_s = OSM_PERFMGR_DEFAULT_SWEEP_TIME_S; } if (p_opts->perfmgr_max_outstanding_queries < 1) { log_report(" Invalid Cached Option Value:" "perfmgr_max_outstanding_queries = %u" " Using Default:%u\n", p_opts->perfmgr_max_outstanding_queries, OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES); p_opts->perfmgr_max_outstanding_queries = OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES; } #endif return 0; } /********************************************************************** **********************************************************************/ int osm_subn_parse_conf_file(char *file_name, osm_subn_opt_t * const p_opts) { char line[1024]; FILE *opts_file; char *p_key, *p_val; opts_file = fopen(file_name, "r"); if (!opts_file) { if (errno == ENOENT) return 1; printf("cannot open file \'%s\': %s\n", file_name, strerror(errno)); return -1; } printf(" Reading Cached Option File: %s\n", file_name); cl_log_event("OpenSM", CL_LOG_INFO, line, NULL, 0); p_opts->config_file = file_name; while (fgets(line, 1023, opts_file) != NULL) { /* get the first token */ p_key = strtok_r(line, " \t\n", &p_val); if (!p_key) continue; p_val = clean_val(p_val); opts_unpack_net64("guid", p_key, p_val, &p_opts->guid); opts_unpack_net64("m_key", p_key, p_val, &p_opts->m_key); opts_unpack_net64("sm_key", p_key, p_val, &p_opts->sm_key); opts_unpack_net64("sa_key", p_key, p_val, &p_opts->sa_key); opts_unpack_net64("subnet_prefix", p_key, p_val, &p_opts->subnet_prefix); opts_unpack_net16("m_key_lease_period", p_key, p_val, &p_opts->m_key_lease_period); opts_unpack_uint32("sweep_interval", p_key, p_val, &p_opts->sweep_interval); opts_unpack_uint32("max_wire_smps", p_key, p_val, &p_opts->max_wire_smps); opts_unpack_charp("console", p_key, p_val, &p_opts->console); opts_unpack_uint16("console_port", p_key, p_val, &p_opts->console_port); opts_unpack_uint32("transaction_timeout", p_key, p_val, &p_opts->transaction_timeout); opts_unpack_uint32("max_msg_fifo_timeout", p_key, p_val, &p_opts->max_msg_fifo_timeout); opts_unpack_uint8("sm_priority", p_key, p_val, &p_opts->sm_priority); opts_unpack_uint8("lmc", p_key, p_val, &p_opts->lmc); opts_unpack_boolean("lmc_esp0", p_key, p_val, &p_opts->lmc_esp0); opts_unpack_uint8("max_op_vls", p_key, p_val, &p_opts->max_op_vls); opts_unpack_uint8("force_link_speed", p_key, p_val, &p_opts->force_link_speed); opts_unpack_boolean("reassign_lids", p_key, p_val, &p_opts->reassign_lids); opts_unpack_boolean("ignore_other_sm", p_key, p_val, &p_opts->ignore_other_sm); opts_unpack_boolean("single_thread", p_key, p_val, &p_opts->single_thread); opts_unpack_boolean("disable_multicast", p_key, p_val, &p_opts->disable_multicast); opts_unpack_boolean("force_log_flush", p_key, p_val, &p_opts->force_log_flush); opts_unpack_uint8("subnet_timeout", p_key, p_val, &p_opts->subnet_timeout); opts_unpack_uint8("packet_life_time", p_key, p_val, &p_opts->packet_life_time); opts_unpack_uint8("vl_stall_count", p_key, p_val, &p_opts->vl_stall_count); opts_unpack_uint8("leaf_vl_stall_count", p_key, p_val, &p_opts->leaf_vl_stall_count); opts_unpack_uint8("head_of_queue_lifetime", p_key, p_val, &p_opts->head_of_queue_lifetime); opts_unpack_uint8("leaf_head_of_queue_lifetime", p_key, p_val, &p_opts->leaf_head_of_queue_lifetime); opts_unpack_uint8("local_phy_errors_threshold", p_key, p_val, &p_opts->local_phy_errors_threshold); opts_unpack_uint8("overrun_errors_threshold", p_key, p_val, &p_opts->overrun_errors_threshold); opts_unpack_uint32("sminfo_polling_timeout", p_key, p_val, &p_opts->sminfo_polling_timeout); opts_unpack_uint32("polling_retry_number", p_key, p_val, &p_opts->polling_retry_number); opts_unpack_boolean("force_heavy_sweep", p_key, p_val, &p_opts->force_heavy_sweep); opts_unpack_uint8("log_flags", p_key, p_val, &p_opts->log_flags); opts_unpack_charp("port_prof_ignore_file", p_key, p_val, &p_opts->port_prof_ignore_file); opts_unpack_boolean("port_profile_switch_nodes", p_key, p_val, &p_opts->port_profile_switch_nodes); opts_unpack_boolean("sweep_on_trap", p_key, p_val, &p_opts->sweep_on_trap); opts_unpack_charp("routing_engine", p_key, p_val, &p_opts->routing_engine_names); opts_unpack_boolean("connect_roots", p_key, p_val, &p_opts->connect_roots); opts_unpack_boolean("use_ucast_cache", p_key, p_val, &p_opts->use_ucast_cache); opts_unpack_charp("log_file", p_key, p_val, &p_opts->log_file); opts_unpack_uint32("log_max_size", p_key, p_val, (void *) & p_opts->log_max_size); p_opts->log_max_size *= 1024 * 1024; /* convert to MB */ opts_unpack_charp("partition_config_file", p_key, p_val, &p_opts->partition_config_file); opts_unpack_boolean("no_partition_enforcement", p_key, p_val, &p_opts->no_partition_enforcement); opts_unpack_boolean("qos", p_key, p_val, &p_opts->qos); opts_unpack_charp("qos_policy_file", p_key, p_val, &p_opts->qos_policy_file); opts_unpack_boolean("accum_log_file", p_key, p_val, &p_opts->accum_log_file); opts_unpack_charp("dump_files_dir", p_key, p_val, &p_opts->dump_files_dir); opts_unpack_charp("lid_matrix_dump_file", p_key, p_val, &p_opts->lid_matrix_dump_file); opts_unpack_charp("lfts_file", p_key, p_val, &p_opts->lfts_file); opts_unpack_charp("root_guid_file", p_key, p_val, &p_opts->root_guid_file); opts_unpack_charp("cn_guid_file", p_key, p_val, &p_opts->cn_guid_file); opts_unpack_charp("ids_guid_file", p_key, p_val, &p_opts->ids_guid_file); opts_unpack_charp("guid_routing_order_file", p_key, p_val, &p_opts->guid_routing_order_file); opts_unpack_charp("sa_db_file", p_key, p_val, &p_opts->sa_db_file); opts_unpack_boolean("exit_on_fatal", p_key, p_val, &p_opts->exit_on_fatal); opts_unpack_boolean("honor_guid2lid_file", p_key, p_val, &p_opts->honor_guid2lid_file); opts_unpack_boolean("daemon", p_key, p_val, &p_opts->daemon); opts_unpack_boolean("sm_inactive", p_key, p_val, &p_opts->sm_inactive); opts_unpack_boolean("babbling_port_policy", p_key, p_val, &p_opts->babbling_port_policy); #ifdef ENABLE_OSM_PERF_MGR opts_unpack_boolean("perfmgr", p_key, p_val, &p_opts->perfmgr); opts_unpack_boolean("perfmgr_redir", p_key, p_val, &p_opts->perfmgr_redir); opts_unpack_uint16("perfmgr_sweep_time_s", p_key, p_val, &p_opts->perfmgr_sweep_time_s); opts_unpack_uint32("perfmgr_max_outstanding_queries", p_key, p_val, &p_opts->perfmgr_max_outstanding_queries); opts_unpack_charp("event_db_dump_file", p_key, p_val, &p_opts->event_db_dump_file); #endif /* ENABLE_OSM_PERF_MGR */ opts_unpack_charp("event_plugin_name", p_key, p_val, &p_opts->event_plugin_name); opts_unpack_charp("node_name_map_name", p_key, p_val, &p_opts->node_name_map_name); subn_parse_qos_options("qos", p_key, p_val, &p_opts->qos_options); subn_parse_qos_options("qos_ca", p_key, p_val, &p_opts->qos_ca_options); subn_parse_qos_options("qos_sw0", p_key, p_val, &p_opts->qos_sw0_options); subn_parse_qos_options("qos_swe", p_key, p_val, &p_opts->qos_swe_options); subn_parse_qos_options("qos_rtr", p_key, p_val, &p_opts->qos_rtr_options); opts_unpack_boolean("enable_quirks", p_key, p_val, &p_opts->enable_quirks); opts_unpack_boolean("no_clients_rereg", p_key, p_val, &p_opts->no_clients_rereg); opts_unpack_charp("prefix_routes_file", p_key, p_val, &p_opts->prefix_routes_file); opts_unpack_boolean("consolidate_ipv6_snm_req", p_key, p_val, &p_opts->consolidate_ipv6_snm_req); } fclose(opts_file); osm_subn_verify_config(p_opts); return 0; } int osm_subn_rescan_conf_files(IN osm_subn_t * const p_subn) { FILE *opts_file; char line[1024]; char *p_key, *p_val, *p_last; if (!p_subn->opt.config_file) return 0; opts_file = fopen(p_subn->opt.config_file, "r"); if (!opts_file) { if (errno == ENOENT) return 1; OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "cannot open file \'%s\': %s\n", p_subn->opt.config_file, strerror(errno)); return -1; } subn_init_qos_options(&p_subn->opt.qos_options); subn_init_qos_options(&p_subn->opt.qos_ca_options); subn_init_qos_options(&p_subn->opt.qos_sw0_options); subn_init_qos_options(&p_subn->opt.qos_swe_options); subn_init_qos_options(&p_subn->opt.qos_rtr_options); while (fgets(line, 1023, opts_file) != NULL) { /* get the first token */ p_key = strtok_r(line, " \t\n", &p_last); if (p_key) { p_val = strtok_r(NULL, " \t\n", &p_last); subn_parse_qos_options("qos", p_key, p_val, &p_subn->opt.qos_options); subn_parse_qos_options("qos_ca", p_key, p_val, &p_subn->opt.qos_ca_options); subn_parse_qos_options("qos_sw0", p_key, p_val, &p_subn->opt.qos_sw0_options); subn_parse_qos_options("qos_swe", p_key, p_val, &p_subn->opt.qos_swe_options); subn_parse_qos_options("qos_rtr", p_key, p_val, &p_subn->opt.qos_rtr_options); } } fclose(opts_file); osm_subn_verify_config(&p_subn->opt); osm_parse_prefix_routes_file(p_subn); return 0; } /********************************************************************** **********************************************************************/ int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t *const p_opts) { fprintf(out, "#\n# DEVICE ATTRIBUTES OPTIONS\n#\n" "# The port GUID on which the OpenSM is running\n" "guid 0x%016" PRIx64 "\n\n" "# M_Key value sent to all ports qualifying all Set(PortInfo)\n" "m_key 0x%016" PRIx64 "\n\n" "# The lease period used for the M_Key on this subnet in [sec]\n" "m_key_lease_period %u\n\n" "# SM_Key value of the SM used for SM authentication\n" "sm_key 0x%016" PRIx64 "\n\n" "# SM_Key value to qualify rcv SA queries as 'trusted'\n" "sa_key 0x%016" PRIx64 "\n\n" "# Note that for both values above (sm_key and sa_key)\n" "# OpenSM version 3.2.1 and below used the default value '1'\n" "# in a host byte order, it is fixed now but you may need to\n" "# change the values to interoperate with old OpenSM running\n" "# on a little endian machine.\n\n" "# Subnet prefix used on this subnet\n" "subnet_prefix 0x%016" PRIx64 "\n\n" "# The LMC value used on this subnet\n" "lmc %u\n\n" "# lmc_esp0 determines whether LMC value used on subnet is used for\n" "# enhanced switch port 0. If TRUE, LMC value for subnet is used for\n" "# ESP0. Otherwise, LMC value for ESP0s is 0.\n" "lmc_esp0 %s\n\n" "# The code of maximal time a packet can live in a switch\n" "# The actual time is 4.096usec * 2^\n" "# The value 0x14 disables this mechanism\n" "packet_life_time 0x%02x\n\n" "# The number of sequential packets dropped that cause the port\n" "# to enter the VLStalled state. The result of setting this value to\n" "# zero is undefined.\n" "vl_stall_count 0x%02x\n\n" "# The number of sequential packets dropped that cause the port\n" "# to enter the VLStalled state. This value is for switch ports\n" "# driving a CA or router port. The result of setting this value\n" "# to zero is undefined.\n" "leaf_vl_stall_count 0x%02x\n\n" "# The code of maximal time a packet can wait at the head of\n" "# transmission queue.\n" "# The actual time is 4.096usec * 2^\n" "# The value 0x14 disables this mechanism\n" "head_of_queue_lifetime 0x%02x\n\n" "# The maximal time a packet can wait at the head of queue on\n" "# switch port connected to a CA or router port\n" "leaf_head_of_queue_lifetime 0x%02x\n\n" "# Limit the maximal operational VLs\n" "max_op_vls %u\n\n" "# Force PortInfo:LinkSpeedEnabled on switch ports\n" "# If 0, don't modify PortInfo:LinkSpeedEnabled on switch port\n" "# Otherwise, use value for PortInfo:LinkSpeedEnabled on switch port\n" "# Values are (IB Spec 1.2.1, 14.2.5.6 Table 146 \"PortInfo\")\n" "# 1: 2.5 Gbps\n" "# 3: 2.5 or 5.0 Gbps\n" "# 5: 2.5 or 10.0 Gbps\n" "# 7: 2.5 or 5.0 or 10.0 Gbps\n" "# 2,4,6,8-14 Reserved\n" "# Default 15: set to PortInfo:LinkSpeedSupported\n" "force_link_speed %u\n\n" "# The subnet_timeout code that will be set for all the ports\n" "# The actual timeout is 4.096usec * 2^\n" "subnet_timeout %u\n\n" "# Threshold of local phy errors for sending Trap 129\n" "local_phy_errors_threshold 0x%02x\n\n" "# Threshold of credit overrun errors for sending Trap 130\n" "overrun_errors_threshold 0x%02x\n\n", cl_ntoh64(p_opts->guid), cl_ntoh64(p_opts->m_key), cl_ntoh16(p_opts->m_key_lease_period), cl_ntoh64(p_opts->sm_key), cl_ntoh64(p_opts->sa_key), cl_ntoh64(p_opts->subnet_prefix), p_opts->lmc, p_opts->lmc_esp0 ? "TRUE" : "FALSE", p_opts->packet_life_time, p_opts->vl_stall_count, p_opts->leaf_vl_stall_count, p_opts->head_of_queue_lifetime, p_opts->leaf_head_of_queue_lifetime, p_opts->max_op_vls, p_opts->force_link_speed, p_opts->subnet_timeout, p_opts->local_phy_errors_threshold, p_opts->overrun_errors_threshold); fprintf(out, "#\n# PARTITIONING OPTIONS\n#\n" "# Partition configuration file to be used\n" "partition_config_file %s\n\n" "# Disable partition enforcement by switches\n" "no_partition_enforcement %s\n\n", p_opts->partition_config_file, p_opts->no_partition_enforcement ? "TRUE" : "FALSE"); fprintf(out, "#\n# SWEEP OPTIONS\n#\n" "# The number of seconds between subnet sweeps (0 disables it)\n" "sweep_interval %u\n\n" "# If TRUE cause all lids to be reassigned\n" "reassign_lids %s\n\n" "# If TRUE forces every sweep to be a heavy sweep\n" "force_heavy_sweep %s\n\n" "# If TRUE every trap will cause a heavy sweep.\n" "# NOTE: successive identical traps (>10) are suppressed\n" "sweep_on_trap %s\n\n", p_opts->sweep_interval, p_opts->reassign_lids ? "TRUE" : "FALSE", p_opts->force_heavy_sweep ? "TRUE" : "FALSE", p_opts->sweep_on_trap ? "TRUE" : "FALSE"); fprintf(out, "#\n# ROUTING OPTIONS\n#\n" "# If TRUE count switches as link subscriptions\n" "port_profile_switch_nodes %s\n\n", p_opts->port_profile_switch_nodes ? "TRUE" : "FALSE"); fprintf(out, "# Name of file with port guids to be ignored by port profiling\n" "port_prof_ignore_file %s\n\n", p_opts->port_prof_ignore_file ? p_opts->port_prof_ignore_file : null_str); fprintf(out, "# Routing engine\n" "# Multiple routing engines can be specified separated by\n" "# commas so that specific ordering of routing algorithms will\n" "# be tried if earlier routing engines fail.\n" "# Supported engines: minhop, updn, file, ftree, lash, dor\n" "routing_engine %s\n\n", p_opts->routing_engine_names ? p_opts->routing_engine_names : null_str); fprintf(out, "# Connect roots (use FALSE if unsure)\n" "connect_roots %s\n\n", p_opts->connect_roots ? "TRUE" : "FALSE"); fprintf(out, "# Use unicast routing cache (use FALSE if unsure)\n" "use_ucast_cache %s\n\n", p_opts->use_ucast_cache ? "TRUE" : "FALSE"); fprintf(out, "# Lid matrix dump file name\n" "lid_matrix_dump_file %s\n\n", p_opts->lid_matrix_dump_file ? p_opts->lid_matrix_dump_file : null_str); fprintf(out, "# LFTs file name\nlfts_file %s\n\n", p_opts->lfts_file ? p_opts->lfts_file : null_str); fprintf(out, "# The file holding the root node guids (for fat-tree or Up/Down)\n" "# One guid in each line\nroot_guid_file %s\n\n", p_opts->root_guid_file ? p_opts->root_guid_file : null_str); fprintf(out, "# The file holding the fat-tree compute node guids\n" "# One guid in each line\ncn_guid_file %s\n\n", p_opts->cn_guid_file ? p_opts->cn_guid_file : null_str); fprintf(out, "# The file holding the node ids which will be used by" " Up/Down algorithm instead\n# of GUIDs (one guid and" " id in each line)\nids_guid_file %s\n\n", p_opts->ids_guid_file ? p_opts->ids_guid_file : null_str); fprintf(out, "# The file holding guid routing order guids (for MinHop and Up/Down)\n" "guid_routing_order_file %s\n\n", p_opts->guid_routing_order_file ? p_opts->guid_routing_order_file : null_str); fprintf(out, "# SA database file name\nsa_db_file %s\n\n", p_opts->sa_db_file ? p_opts->sa_db_file : null_str); fprintf(out, "#\n# HANDOVER - MULTIPLE SMs OPTIONS\n#\n" "# SM priority used for deciding who is the master\n" "# Range goes from 0 (lowest priority) to 15 (highest).\n" "sm_priority %u\n\n" "# If TRUE other SMs on the subnet should be ignored\n" "ignore_other_sm %s\n\n" "# Timeout in [msec] between two polls of active master SM\n" "sminfo_polling_timeout %u\n\n" "# Number of failing polls of remote SM that declares it dead\n" "polling_retry_number %u\n\n" "# If TRUE honor the guid2lid file when coming out of standby\n" "# state, if such file exists and is valid\n" "honor_guid2lid_file %s\n\n", p_opts->sm_priority, p_opts->ignore_other_sm ? "TRUE" : "FALSE", p_opts->sminfo_polling_timeout, p_opts->polling_retry_number, p_opts->honor_guid2lid_file ? "TRUE" : "FALSE"); fprintf(out, "#\n# TIMING AND THREADING OPTIONS\n#\n" "# Maximum number of SMPs sent in parallel\n" "max_wire_smps %u\n\n" "# The maximum time in [msec] allowed for a transaction to complete\n" "transaction_timeout %u\n\n" "# Maximal time in [msec] a message can stay in the incoming message queue.\n" "# If there is more than one message in the queue and the last message\n" "# stayed in the queue more than this value, any SA request will be\n" "# immediately returned with a BUSY status.\n" "max_msg_fifo_timeout %u\n\n" "# Use a single thread for handling SA queries\n" "single_thread %s\n\n", p_opts->max_wire_smps, p_opts->transaction_timeout, p_opts->max_msg_fifo_timeout, p_opts->single_thread ? "TRUE" : "FALSE"); fprintf(out, "#\n# MISC OPTIONS\n#\n" "# Daemon mode\n" "daemon %s\n\n" "# SM Inactive\n" "sm_inactive %s\n\n" "# Babbling Port Policy\n" "babbling_port_policy %s\n\n", p_opts->daemon ? "TRUE" : "FALSE", p_opts->sm_inactive ? "TRUE" : "FALSE", p_opts->babbling_port_policy ? "TRUE" : "FALSE"); #ifdef ENABLE_OSM_PERF_MGR fprintf(out, "#\n# Performance Manager Options\n#\n" "# perfmgr enable\n" "perfmgr %s\n\n" "# perfmgr redirection enable\n" "perfmgr_redir %s\n\n" "# sweep time in seconds\n" "perfmgr_sweep_time_s %u\n\n" "# Max outstanding queries\n" "perfmgr_max_outstanding_queries %u\n\n", p_opts->perfmgr ? "TRUE" : "FALSE", p_opts->perfmgr_redir ? "TRUE" : "FALSE", p_opts->perfmgr_sweep_time_s, p_opts->perfmgr_max_outstanding_queries); fprintf(out, "#\n# Event DB Options\n#\n" "# Dump file to dump the events to\n" "event_db_dump_file %s\n\n", p_opts->event_db_dump_file ? p_opts->event_db_dump_file : null_str); #endif /* ENABLE_OSM_PERF_MGR */ fprintf(out, "#\n# Event Plugin Options\n#\n" "event_plugin_name %s\n\n", p_opts->event_plugin_name ? p_opts->event_plugin_name : null_str); fprintf(out, "#\n# Node name map for mapping node's to more descriptive node descriptions\n" "# (man ibnetdiscover for more information)\n#\n" "node_name_map_name %s\n\n", p_opts->node_name_map_name ? p_opts->node_name_map_name : null_str); fprintf(out, "#\n# DEBUG FEATURES\n#\n" "# The log flags used\n" "log_flags 0x%02x\n\n" "# Force flush of the log file after each log message\n" "force_log_flush %s\n\n" "# Log file to be used\n" "log_file %s\n\n" "# Limit the size of the log file in MB. If overrun, log is restarted\n" "log_max_size %lu\n\n" "# If TRUE will accumulate the log over multiple OpenSM sessions\n" "accum_log_file %s\n\n" "# The directory to hold the file OpenSM dumps\n" "dump_files_dir %s\n\n" "# If TRUE enables new high risk options and hardware specific quirks\n" "enable_quirks %s\n\n" "# If TRUE disables client reregistration\n" "no_clients_rereg %s\n\n" "# If TRUE OpenSM should disable multicast support and\n" "# no multicast routing is performed if TRUE\n" "disable_multicast %s\n\n" "# If TRUE opensm will exit on fatal initialization issues\n" "exit_on_fatal %s\n\n" "# console [off|local" #ifdef ENABLE_OSM_CONSOLE_SOCKET "|loopback|socket]\n" #else "]\n" #endif "console %s\n\n" "# Telnet port for console (default %d)\n" "console_port %d\n\n", p_opts->log_flags, p_opts->force_log_flush ? "TRUE" : "FALSE", p_opts->log_file, p_opts->log_max_size/1024/1024, p_opts->accum_log_file ? "TRUE" : "FALSE", p_opts->dump_files_dir, p_opts->enable_quirks ? "TRUE" : "FALSE", p_opts->no_clients_rereg ? "TRUE" : "FALSE", p_opts->disable_multicast ? "TRUE" : "FALSE", p_opts->exit_on_fatal ? "TRUE" : "FALSE", p_opts->console, OSM_DEFAULT_CONSOLE_PORT, p_opts->console_port); fprintf(out, "#\n# QoS OPTIONS\n#\n" "# Enable QoS setup\n" "qos %s\n\n" "# QoS policy file to be used\n" "qos_policy_file %s\n\n", p_opts->qos ? "TRUE" : "FALSE", p_opts->qos_policy_file); subn_dump_qos_options(out, "QoS default options", "qos", &p_opts->qos_options); fprintf(out, "\n"); subn_dump_qos_options(out, "QoS CA options", "qos_ca", &p_opts->qos_ca_options); fprintf(out, "\n"); subn_dump_qos_options(out, "QoS Switch Port 0 options", "qos_sw0", &p_opts->qos_sw0_options); fprintf(out, "\n"); subn_dump_qos_options(out, "QoS Switch external ports options", "qos_swe", &p_opts->qos_swe_options); fprintf(out, "\n"); subn_dump_qos_options(out, "QoS Router ports options", "qos_rtr", &p_opts->qos_rtr_options); fprintf(out, "\n"); fprintf(out, "# Prefix routes file name\n" "prefix_routes_file %s\n\n", p_opts->prefix_routes_file); fprintf(out, "#\n# IPv6 Solicited Node Multicast (SNM) Options\n#\n" "consolidate_ipv6_snm_req %s\n\n", p_opts->consolidate_ipv6_snm_req ? "TRUE" : "FALSE"); /* optional string attributes ... */ return 0; } int osm_subn_write_conf_file(char *file_name, IN osm_subn_opt_t *const p_opts) { FILE *opts_file; opts_file = fopen(file_name, "w"); if (!opts_file) { printf("cannot open file \'%s\' for writing: %s\n", file_name, strerror(errno)); return -1; } if (osm_subn_output_conf(opts_file, p_opts) < 0) return -1; fclose(opts_file); return 0; }