2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved.
7 * This software is available to you under a choice of one of two
8 * licenses. You may choose to be licensed under the terms of the GNU
9 * General Public License (GPL) Version 2, available from the file
10 * COPYING in the main directory of this source tree, or the
11 * OpenIB.org BSD license below:
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
17 * - Redistributions of source code must retain the above
18 * copyright notice, this list of conditions and the following
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials
24 * provided with the distribution.
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39 * Implementation of osm_subn_t.
40 * This object represents an IBA subnet.
41 * This object is part of the opensm family of objects.
46 #endif /* HAVE_CONFIG_H */
54 #include <complib/cl_debug.h>
55 #include <complib/cl_log.h>
56 #include <opensm/osm_subnet.h>
57 #include <opensm/osm_opensm.h>
58 #include <opensm/osm_log.h>
59 #include <opensm/osm_madw.h>
60 #include <opensm/osm_port.h>
61 #include <opensm/osm_switch.h>
62 #include <opensm/osm_remote_sm.h>
63 #include <opensm/osm_partition.h>
64 #include <opensm/osm_node.h>
65 #include <opensm/osm_multicast.h>
66 #include <opensm/osm_inform.h>
67 #include <opensm/osm_console.h>
68 #include <opensm/osm_perfmgr.h>
69 #include <opensm/osm_event_plugin.h>
70 #include <opensm/osm_qos_policy.h>
72 static const char null_str[] = "(null)";
74 /**********************************************************************
75 **********************************************************************/
76 void osm_subn_construct(IN osm_subn_t * const p_subn)
78 memset(p_subn, 0, sizeof(*p_subn));
79 cl_ptr_vector_construct(&p_subn->port_lid_tbl);
80 cl_qmap_init(&p_subn->sw_guid_tbl);
81 cl_qmap_init(&p_subn->node_guid_tbl);
82 cl_qmap_init(&p_subn->port_guid_tbl);
83 cl_qmap_init(&p_subn->sm_guid_tbl);
84 cl_qlist_init(&p_subn->sa_sr_list);
85 cl_qlist_init(&p_subn->sa_infr_list);
86 cl_qlist_init(&p_subn->prefix_routes_list);
87 cl_qmap_init(&p_subn->rtr_guid_tbl);
88 cl_qmap_init(&p_subn->prtn_pkey_tbl);
91 /**********************************************************************
92 **********************************************************************/
93 void osm_subn_destroy(IN osm_subn_t * const p_subn)
96 osm_node_t *p_node, *p_next_node;
97 osm_port_t *p_port, *p_next_port;
98 osm_switch_t *p_sw, *p_next_sw;
99 osm_remote_sm_t *p_rsm, *p_next_rsm;
100 osm_prtn_t *p_prtn, *p_next_prtn;
102 osm_infr_t *p_infr, *p_next_infr;
104 /* it might be a good idea to de-allocate all known objects */
105 p_next_node = (osm_node_t *) cl_qmap_head(&p_subn->node_guid_tbl);
106 while (p_next_node !=
107 (osm_node_t *) cl_qmap_end(&p_subn->node_guid_tbl)) {
108 p_node = p_next_node;
109 p_next_node = (osm_node_t *) cl_qmap_next(&p_node->map_item);
110 osm_node_delete(&p_node);
113 p_next_port = (osm_port_t *) cl_qmap_head(&p_subn->port_guid_tbl);
114 while (p_next_port !=
115 (osm_port_t *) cl_qmap_end(&p_subn->port_guid_tbl)) {
116 p_port = p_next_port;
117 p_next_port = (osm_port_t *) cl_qmap_next(&p_port->map_item);
118 osm_port_delete(&p_port);
121 p_next_sw = (osm_switch_t *) cl_qmap_head(&p_subn->sw_guid_tbl);
122 while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_subn->sw_guid_tbl)) {
124 p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item);
125 osm_switch_delete(&p_sw);
128 p_next_rsm = (osm_remote_sm_t *) cl_qmap_head(&p_subn->sm_guid_tbl);
130 (osm_remote_sm_t *) cl_qmap_end(&p_subn->sm_guid_tbl)) {
132 p_next_rsm = (osm_remote_sm_t *) cl_qmap_next(&p_rsm->map_item);
136 p_next_prtn = (osm_prtn_t *) cl_qmap_head(&p_subn->prtn_pkey_tbl);
137 while (p_next_prtn !=
138 (osm_prtn_t *) cl_qmap_end(&p_subn->prtn_pkey_tbl)) {
139 p_prtn = p_next_prtn;
140 p_next_prtn = (osm_prtn_t *) cl_qmap_next(&p_prtn->map_item);
141 osm_prtn_delete(&p_prtn);
144 for (i = 0; i <= p_subn->max_mcast_lid_ho - IB_LID_MCAST_START_HO;
146 p_mgrp = p_subn->mgroups[i];
147 p_subn->mgroups[i] = NULL;
149 osm_mgrp_delete(p_mgrp);
152 p_next_infr = (osm_infr_t *) cl_qlist_head(&p_subn->sa_infr_list);
153 while (p_next_infr !=
154 (osm_infr_t *) cl_qlist_end(&p_subn->sa_infr_list)) {
155 p_infr = p_next_infr;
156 p_next_infr = (osm_infr_t *) cl_qlist_next(&p_infr->list_item);
157 osm_infr_delete(p_infr);
160 cl_ptr_vector_destroy(&p_subn->port_lid_tbl);
162 osm_qos_policy_destroy(p_subn->p_qos_policy);
164 while (!cl_is_qlist_empty(&p_subn->prefix_routes_list)) {
165 cl_list_item_t *item = cl_qlist_remove_head(&p_subn->prefix_routes_list);
170 /**********************************************************************
171 **********************************************************************/
173 osm_subn_init(IN osm_subn_t * const p_subn,
174 IN osm_opensm_t * const p_osm,
175 IN const osm_subn_opt_t * const p_opt)
179 p_subn->p_osm = p_osm;
181 status = cl_ptr_vector_init(&p_subn->port_lid_tbl,
182 OSM_SUBNET_VECTOR_MIN_SIZE,
183 OSM_SUBNET_VECTOR_GROW_SIZE);
184 if (status != CL_SUCCESS)
187 status = cl_ptr_vector_set_capacity(&p_subn->port_lid_tbl,
188 OSM_SUBNET_VECTOR_CAPACITY);
189 if (status != CL_SUCCESS)
193 LID zero is not valid. NULL out this entry for the
194 convenience of other code.
196 cl_ptr_vector_set(&p_subn->port_lid_tbl, 0, NULL);
198 p_subn->opt = *p_opt;
199 p_subn->max_ucast_lid_ho = IB_LID_UCAST_END_HO;
200 p_subn->max_mcast_lid_ho = IB_LID_MCAST_END_HO;
201 p_subn->min_ca_mtu = IB_MAX_MTU;
202 p_subn->min_ca_rate = IB_MAX_RATE;
203 p_subn->ignore_existing_lfts = TRUE;
205 /* we assume master by default - so we only need to set it true if STANDBY */
206 p_subn->coming_out_of_standby = FALSE;
211 /**********************************************************************
212 **********************************************************************/
214 osm_get_gid_by_mad_addr(IN osm_log_t * p_log,
215 IN const osm_subn_t * p_subn,
216 IN const osm_mad_addr_t * p_mad_addr,
217 OUT ib_gid_t * p_gid)
219 const cl_ptr_vector_t *p_tbl;
220 const osm_port_t *p_port = NULL;
223 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7505: "
224 "Provided output GID is NULL\n");
225 return (IB_INVALID_PARAMETER);
228 /* Find the port gid of the request in the subnet */
229 p_tbl = &p_subn->port_lid_tbl;
231 CL_ASSERT(cl_ptr_vector_get_size(p_tbl) < 0x10000);
233 if ((uint16_t) cl_ptr_vector_get_size(p_tbl) >
234 cl_ntoh16(p_mad_addr->dest_lid)) {
236 cl_ptr_vector_get(p_tbl, cl_ntoh16(p_mad_addr->dest_lid));
237 if (p_port == NULL) {
238 OSM_LOG(p_log, OSM_LOG_DEBUG,
239 "Did not find any port with LID: %u\n",
240 cl_ntoh16(p_mad_addr->dest_lid));
241 return (IB_INVALID_PARAMETER);
243 p_gid->unicast.interface_id = p_port->p_physp->port_guid;
244 p_gid->unicast.prefix = p_subn->opt.subnet_prefix;
246 /* The dest_lid is not in the subnet table - this is an error */
247 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7501: "
248 "LID is out of range: %u\n",
249 cl_ntoh16(p_mad_addr->dest_lid));
250 return (IB_INVALID_PARAMETER);
256 /**********************************************************************
257 **********************************************************************/
258 osm_physp_t *osm_get_physp_by_mad_addr(IN osm_log_t * p_log,
259 IN const osm_subn_t * p_subn,
260 IN osm_mad_addr_t * p_mad_addr)
262 const cl_ptr_vector_t *p_port_lid_tbl;
263 osm_port_t *p_port = NULL;
264 osm_physp_t *p_physp = NULL;
266 /* Find the port gid of the request in the subnet */
267 p_port_lid_tbl = &p_subn->port_lid_tbl;
269 CL_ASSERT(cl_ptr_vector_get_size(p_port_lid_tbl) < 0x10000);
271 if ((uint16_t) cl_ptr_vector_get_size(p_port_lid_tbl) >
272 cl_ntoh16(p_mad_addr->dest_lid)) {
274 cl_ptr_vector_get(p_port_lid_tbl,
275 cl_ntoh16(p_mad_addr->dest_lid));
276 if (p_port == NULL) {
277 /* The port is not in the port_lid table - this is an error */
278 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7502: "
279 "Cannot locate port object by lid: %u\n",
280 cl_ntoh16(p_mad_addr->dest_lid));
284 p_physp = p_port->p_physp;
286 /* The dest_lid is not in the subnet table - this is an error */
287 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7503: "
288 "Lid is out of range: %u\n",
289 cl_ntoh16(p_mad_addr->dest_lid));
296 /**********************************************************************
297 **********************************************************************/
298 osm_port_t *osm_get_port_by_mad_addr(IN osm_log_t * p_log,
299 IN const osm_subn_t * p_subn,
300 IN osm_mad_addr_t * p_mad_addr)
302 const cl_ptr_vector_t *p_port_lid_tbl;
303 osm_port_t *p_port = NULL;
305 /* Find the port gid of the request in the subnet */
306 p_port_lid_tbl = &p_subn->port_lid_tbl;
308 CL_ASSERT(cl_ptr_vector_get_size(p_port_lid_tbl) < 0x10000);
310 if ((uint16_t) cl_ptr_vector_get_size(p_port_lid_tbl) >
311 cl_ntoh16(p_mad_addr->dest_lid)) {
313 cl_ptr_vector_get(p_port_lid_tbl,
314 cl_ntoh16(p_mad_addr->dest_lid));
316 /* The dest_lid is not in the subnet table - this is an error */
317 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 7504: "
318 "Lid is out of range: %u\n",
319 cl_ntoh16(p_mad_addr->dest_lid));
325 /**********************************************************************
326 **********************************************************************/
327 osm_switch_t *osm_get_switch_by_guid(IN const osm_subn_t * p_subn,
330 osm_switch_t *p_switch;
332 p_switch = (osm_switch_t *) cl_qmap_get(&(p_subn->sw_guid_tbl), guid);
333 if (p_switch == (osm_switch_t *) cl_qmap_end(&(p_subn->sw_guid_tbl)))
338 /**********************************************************************
339 **********************************************************************/
340 osm_node_t *osm_get_node_by_guid(IN osm_subn_t const *p_subn, IN uint64_t guid)
344 p_node = (osm_node_t *) cl_qmap_get(&(p_subn->node_guid_tbl), guid);
345 if (p_node == (osm_node_t *) cl_qmap_end(&(p_subn->node_guid_tbl)))
350 /**********************************************************************
351 **********************************************************************/
352 osm_port_t *osm_get_port_by_guid(IN osm_subn_t const *p_subn, IN ib_net64_t guid)
356 p_port = (osm_port_t *) cl_qmap_get(&(p_subn->port_guid_tbl), guid);
357 if (p_port == (osm_port_t *) cl_qmap_end(&(p_subn->port_guid_tbl)))
362 /**********************************************************************
363 **********************************************************************/
364 static void subn_set_default_qos_options(IN osm_qos_options_t * opt)
366 opt->max_vls = OSM_DEFAULT_QOS_MAX_VLS;
367 opt->high_limit = OSM_DEFAULT_QOS_HIGH_LIMIT;
368 opt->vlarb_high = OSM_DEFAULT_QOS_VLARB_HIGH;
369 opt->vlarb_low = OSM_DEFAULT_QOS_VLARB_LOW;
370 opt->sl2vl = OSM_DEFAULT_QOS_SL2VL;
373 static void subn_init_qos_options(IN osm_qos_options_t * opt)
376 opt->high_limit = -1;
377 opt->vlarb_high = NULL;
378 opt->vlarb_low = NULL;
382 /**********************************************************************
383 **********************************************************************/
384 void osm_subn_set_default_opt(IN osm_subn_opt_t * const p_opt)
386 memset(p_opt, 0, sizeof(osm_subn_opt_t));
388 p_opt->m_key = OSM_DEFAULT_M_KEY;
389 p_opt->sm_key = OSM_DEFAULT_SM_KEY;
390 p_opt->sa_key = OSM_DEFAULT_SA_KEY;
391 p_opt->subnet_prefix = IB_DEFAULT_SUBNET_PREFIX;
392 p_opt->m_key_lease_period = 0;
393 p_opt->sweep_interval = OSM_DEFAULT_SWEEP_INTERVAL_SECS;
394 p_opt->max_wire_smps = OSM_DEFAULT_SMP_MAX_ON_WIRE;
395 p_opt->console = OSM_DEFAULT_CONSOLE;
396 p_opt->console_port = OSM_DEFAULT_CONSOLE_PORT;
397 p_opt->transaction_timeout = OSM_DEFAULT_TRANS_TIMEOUT_MILLISEC;
398 /* by default we will consider waiting for 50x transaction timeout normal */
399 p_opt->max_msg_fifo_timeout = 50 * OSM_DEFAULT_TRANS_TIMEOUT_MILLISEC;
400 p_opt->sm_priority = OSM_DEFAULT_SM_PRIORITY;
401 p_opt->lmc = OSM_DEFAULT_LMC;
402 p_opt->lmc_esp0 = FALSE;
403 p_opt->max_op_vls = OSM_DEFAULT_MAX_OP_VLS;
404 p_opt->force_link_speed = 15;
405 p_opt->reassign_lids = FALSE;
406 p_opt->ignore_other_sm = FALSE;
407 p_opt->single_thread = FALSE;
408 p_opt->disable_multicast = FALSE;
409 p_opt->force_log_flush = FALSE;
410 p_opt->subnet_timeout = OSM_DEFAULT_SUBNET_TIMEOUT;
411 p_opt->packet_life_time = OSM_DEFAULT_SWITCH_PACKET_LIFE;
412 p_opt->vl_stall_count = OSM_DEFAULT_VL_STALL_COUNT;
413 p_opt->leaf_vl_stall_count = OSM_DEFAULT_LEAF_VL_STALL_COUNT;
414 p_opt->head_of_queue_lifetime = OSM_DEFAULT_HEAD_OF_QUEUE_LIFE;
415 p_opt->leaf_head_of_queue_lifetime =
416 OSM_DEFAULT_LEAF_HEAD_OF_QUEUE_LIFE;
417 p_opt->local_phy_errors_threshold = OSM_DEFAULT_ERROR_THRESHOLD;
418 p_opt->overrun_errors_threshold = OSM_DEFAULT_ERROR_THRESHOLD;
419 p_opt->sminfo_polling_timeout =
420 OSM_SM_DEFAULT_POLLING_TIMEOUT_MILLISECS;
421 p_opt->polling_retry_number = OSM_SM_DEFAULT_POLLING_RETRY_NUMBER;
422 p_opt->force_heavy_sweep = FALSE;
423 p_opt->log_flags = OSM_LOG_DEFAULT_LEVEL;
424 p_opt->honor_guid2lid_file = FALSE;
425 p_opt->daemon = FALSE;
426 p_opt->sm_inactive = FALSE;
427 p_opt->babbling_port_policy = FALSE;
428 #ifdef ENABLE_OSM_PERF_MGR
429 p_opt->perfmgr = FALSE;
430 p_opt->perfmgr_redir = TRUE;
431 p_opt->perfmgr_sweep_time_s = OSM_PERFMGR_DEFAULT_SWEEP_TIME_S;
432 p_opt->perfmgr_max_outstanding_queries =
433 OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES;
434 p_opt->event_db_dump_file = NULL; /* use default */
435 #endif /* ENABLE_OSM_PERF_MGR */
437 p_opt->event_plugin_name = NULL;
438 p_opt->node_name_map_name = NULL;
440 p_opt->dump_files_dir = getenv("OSM_TMP_DIR");
441 if (!p_opt->dump_files_dir || !(*p_opt->dump_files_dir))
442 p_opt->dump_files_dir = OSM_DEFAULT_TMP_DIR;
444 p_opt->log_file = OSM_DEFAULT_LOG_FILE;
445 p_opt->log_max_size = 0;
446 p_opt->partition_config_file = OSM_DEFAULT_PARTITION_CONFIG_FILE;
447 p_opt->no_partition_enforcement = FALSE;
449 p_opt->qos_policy_file = OSM_DEFAULT_QOS_POLICY_FILE;
450 p_opt->accum_log_file = TRUE;
451 p_opt->port_prof_ignore_file = NULL;
452 p_opt->port_profile_switch_nodes = FALSE;
453 p_opt->sweep_on_trap = TRUE;
454 p_opt->use_ucast_cache = FALSE;
455 p_opt->routing_engine_names = NULL;
456 p_opt->connect_roots = FALSE;
457 p_opt->lid_matrix_dump_file = NULL;
458 p_opt->lfts_file = NULL;
459 p_opt->root_guid_file = NULL;
460 p_opt->cn_guid_file = NULL;
461 p_opt->ids_guid_file = NULL;
462 p_opt->guid_routing_order_file = NULL;
463 p_opt->sa_db_file = NULL;
464 p_opt->exit_on_fatal = TRUE;
465 p_opt->enable_quirks = FALSE;
466 p_opt->no_clients_rereg = FALSE;
467 p_opt->prefix_routes_file = OSM_DEFAULT_PREFIX_ROUTES_FILE;
468 p_opt->consolidate_ipv6_snm_req = FALSE;
469 subn_init_qos_options(&p_opt->qos_options);
470 subn_init_qos_options(&p_opt->qos_ca_options);
471 subn_init_qos_options(&p_opt->qos_sw0_options);
472 subn_init_qos_options(&p_opt->qos_swe_options);
473 subn_init_qos_options(&p_opt->qos_rtr_options);
476 /**********************************************************************
477 **********************************************************************/
478 static void log_report(const char *fmt, ...)
483 vsnprintf(buf, sizeof(buf), fmt, args);
486 cl_log_event("OpenSM", CL_LOG_INFO, buf, NULL, 0);
489 static void log_config_value(char *name, const char *fmt, ...)
495 n = snprintf(buf, sizeof(buf), " Loading Cached Option:%s = ", name);
498 n += vsnprintf(buf + n, sizeof(buf) - n, fmt, args);
501 snprintf(buf + n, sizeof(buf) - n, "\n");
504 cl_log_event("OpenSM", CL_LOG_INFO, buf, NULL, 0);
508 opts_unpack_net64(IN char *p_req_key,
509 IN char *p_key, IN char *p_val_str, IN uint64_t * p_val)
511 if (!strcmp(p_req_key, p_key)) {
512 uint64_t val = strtoull(p_val_str, NULL, 0);
513 if (cl_hton64(val) != *p_val) {
514 log_config_value(p_key, "0x%016" PRIx64, val);
515 *p_val = cl_ntoh64(val);
520 /**********************************************************************
521 **********************************************************************/
523 opts_unpack_uint32(IN char *p_req_key,
524 IN char *p_key, IN char *p_val_str, IN uint32_t * p_val)
526 if (!strcmp(p_req_key, p_key)) {
527 uint32_t val = strtoul(p_val_str, NULL, 0);
529 log_config_value(p_key, "%u", val);
535 /**********************************************************************
536 **********************************************************************/
538 opts_unpack_int32(IN char *p_req_key,
539 IN char *p_key, IN char *p_val_str, IN int32_t * p_val)
541 if (!strcmp(p_req_key, p_key)) {
542 int32_t val = strtol(p_val_str, NULL, 0);
544 log_config_value(p_key, "%d", val);
550 /**********************************************************************
551 **********************************************************************/
553 opts_unpack_uint16(IN char *p_req_key,
554 IN char *p_key, IN char *p_val_str, IN uint16_t * p_val)
556 if (!strcmp(p_req_key, p_key)) {
557 uint16_t val = (uint16_t) strtoul(p_val_str, NULL, 0);
559 log_config_value(p_key, "%u", val);
565 /**********************************************************************
566 **********************************************************************/
568 opts_unpack_net16(IN char *p_req_key,
569 IN char *p_key, IN char *p_val_str, IN uint16_t * p_val)
571 if (!strcmp(p_req_key, p_key)) {
573 val = strtoul(p_val_str, NULL, 0);
574 CL_ASSERT(val < 0x10000);
575 if (cl_hton32(val) != *p_val) {
576 log_config_value(p_key, "0x%04x", val);
577 *p_val = cl_hton16((uint16_t) val);
582 /**********************************************************************
583 **********************************************************************/
585 opts_unpack_uint8(IN char *p_req_key,
586 IN char *p_key, IN char *p_val_str, IN uint8_t * p_val)
588 if (!strcmp(p_req_key, p_key)) {
590 val = strtoul(p_val_str, NULL, 0);
591 CL_ASSERT(val < 0x100);
593 log_config_value(p_key, "%u", val);
594 *p_val = (uint8_t) val;
599 /**********************************************************************
600 **********************************************************************/
602 opts_unpack_boolean(IN char *p_req_key,
603 IN char *p_key, IN char *p_val_str, IN boolean_t * p_val)
605 if (!strcmp(p_req_key, p_key) && p_val_str) {
607 if (strcmp("TRUE", p_val_str))
613 log_config_value(p_key, "%s", p_val_str);
619 /**********************************************************************
620 **********************************************************************/
622 opts_unpack_charp(IN char *p_req_key,
623 IN char *p_key, IN char *p_val_str, IN char **p_val)
625 if (!strcmp(p_req_key, p_key) && p_val_str) {
626 const char *current_str = *p_val ? *p_val : null_str ;
627 if (strcmp(p_val_str, current_str)) {
628 log_config_value(p_key, "%s", p_val_str);
629 /* special case the "(null)" string */
630 if (strcmp(null_str, p_val_str) == 0) {
634 Ignore the possible memory leak here;
635 the pointer may be to a static default.
637 *p_val = strdup(p_val_str);
643 /**********************************************************************
644 **********************************************************************/
645 static char *clean_val(char *val)
648 /* clean leading spaces */
654 /* clean trailing spaces */
655 p = val + strlen(val) - 1;
656 while (p > val && isspace(*p))
660 if ((*val == '\"' && *p == '\"') || (*val == '\'' && *p == '\'')) {
667 /**********************************************************************
668 **********************************************************************/
670 subn_parse_qos_options(IN const char *prefix,
672 IN char *p_val_str, IN osm_qos_options_t * opt)
676 snprintf(name, sizeof(name), "%s_max_vls", prefix);
677 opts_unpack_uint32(name, p_key, p_val_str, &opt->max_vls);
678 snprintf(name, sizeof(name), "%s_high_limit", prefix);
679 opts_unpack_int32(name, p_key, p_val_str, &opt->high_limit);
680 snprintf(name, sizeof(name), "%s_vlarb_high", prefix);
681 opts_unpack_charp(name, p_key, p_val_str, &opt->vlarb_high);
682 snprintf(name, sizeof(name), "%s_vlarb_low", prefix);
683 opts_unpack_charp(name, p_key, p_val_str, &opt->vlarb_low);
684 snprintf(name, sizeof(name), "%s_sl2vl", prefix);
685 opts_unpack_charp(name, p_key, p_val_str, &opt->sl2vl);
689 subn_dump_qos_options(FILE * file,
690 const char *set_name,
691 const char *prefix, osm_qos_options_t * opt)
693 return fprintf(file, "# %s\n"
700 prefix, opt->max_vls,
701 prefix, opt->high_limit,
702 prefix, opt->vlarb_high,
703 prefix, opt->vlarb_low, prefix, opt->sl2vl);
706 /**********************************************************************
707 **********************************************************************/
708 static ib_api_status_t
709 append_prefix_route(IN osm_subn_t * const p_subn, uint64_t prefix, uint64_t guid)
711 osm_prefix_route_t *route;
713 route = malloc(sizeof *route);
715 OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "out of memory");
719 route->prefix = cl_hton64(prefix);
720 route->guid = cl_hton64(guid);
721 cl_qlist_insert_tail(&p_subn->prefix_routes_list, &route->list_item);
725 static ib_api_status_t
726 osm_parse_prefix_routes_file(IN osm_subn_t * const p_subn)
728 osm_log_t *log = &p_subn->p_osm->log;
734 while (!cl_is_qlist_empty(&p_subn->prefix_routes_list)) {
735 cl_list_item_t *item = cl_qlist_remove_head(&p_subn->prefix_routes_list);
739 fp = fopen(p_subn->opt.prefix_routes_file, "r");
744 OSM_LOG(log, OSM_LOG_ERROR, "fopen(%s) failed: %s",
745 p_subn->opt.prefix_routes_file, strerror(errno));
749 while (fgets(buf, sizeof buf, fp) != NULL) {
750 char *p_prefix, *p_guid, *p_extra, *p_last, *p_end;
751 uint64_t prefix, guid;
757 p_prefix = strtok_r(buf, " \t\n", &p_last);
759 continue; /* ignore blank lines */
761 if (*p_prefix == '#')
762 continue; /* ignore comment lines */
764 p_guid = strtok_r(NULL, " \t\n", &p_last);
766 OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: missing GUID\n",
767 p_subn->opt.prefix_routes_file, line);
772 p_extra = strtok_r(NULL, " \t\n", &p_last);
773 if (p_extra && *p_extra != '#') {
774 OSM_LOG(log, OSM_LOG_INFO, "%s:%d: extra tokens ignored\n",
775 p_subn->opt.prefix_routes_file, line);
778 if (strcmp(p_prefix, "*") == 0)
781 prefix = strtoull(p_prefix, &p_end, 16);
782 if (*p_end != '\0') {
783 OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: illegal prefix: %s\n",
784 p_subn->opt.prefix_routes_file, line, p_prefix);
790 if (strcmp(p_guid, "*") == 0)
793 guid = strtoull(p_guid, &p_end, 16);
794 if (*p_end != '\0' && *p_end != '#') {
795 OSM_LOG(log, OSM_LOG_ERROR, "%s:%d: illegal GUID: %s\n",
796 p_subn->opt.prefix_routes_file, line, p_guid);
802 if (append_prefix_route(p_subn, prefix, guid) != IB_SUCCESS) {
809 return (errors == 0) ? IB_SUCCESS : IB_ERROR;
812 /**********************************************************************
813 **********************************************************************/
814 static void subn_verify_max_vls(unsigned *max_vls, const char *prefix, unsigned dflt)
816 if (!(*max_vls) || *max_vls > 15) {
817 log_report(" Invalid Cached Option: %s_max_vls=%u: "
818 "Using Default = %u\n", prefix, *max_vls, dflt);
823 static void subn_verify_high_limit(int *high_limit, const char *prefix, int dflt)
825 if (*high_limit < 0 || *high_limit > 255) {
826 log_report(" Invalid Cached Option: %s_high_limit=%d: "
827 "Using Default: %d\n", prefix, *high_limit, dflt);
832 static void subn_verify_vlarb(char **vlarb, const char *prefix,
833 const char *suffix, char *dflt)
835 char *str, *tok, *end, *ptr;
838 if (*vlarb == NULL) {
839 log_report(" Invalid Cached Option: %s_vlarb_%s: "
840 "Using Default\n", prefix, suffix);
845 str = strdup(*vlarb);
847 tok = strtok_r(str, ",\n", &ptr);
849 char *vl_str, *weight_str;
852 weight_str = strchr(tok, ':');
860 vl = strtol(vl_str, &end, 0);
863 log_report(" Warning: Cached Option "
865 " improperly formatted\n",
866 prefix, suffix, vl_str);
867 else if (vl < 0 || vl > 14)
868 log_report(" Warning: Cached Option "
869 "%s_vlarb_%s:vl=%ld out of range\n",
872 weight = strtol(weight_str, &end, 0);
875 log_report(" Warning: Cached Option "
876 "%s_vlarb_%s:weight=%s "
877 "improperly formatted\n",
878 prefix, suffix, weight_str);
879 else if (weight < 0 || weight > 255)
880 log_report(" Warning: Cached Option "
881 "%s_vlarb_%s:weight=%ld "
883 prefix, suffix, weight);
885 log_report(" Warning: Cached Option "
886 "%s_vlarb_%s:vl:weight=%s "
887 "improperly formatted\n",
888 prefix, suffix, tok);
891 tok = strtok_r(NULL, ",\n", &ptr);
895 log_report(" Warning: Cached Option %s_vlarb_%s: > 64 listed:"
896 " excess vl:weight pairs will be dropped\n",
902 static void subn_verify_sl2vl(char **sl2vl, const char *prefix, char *dflt)
904 char *str, *tok, *end, *ptr;
907 if (*sl2vl == NULL) {
908 log_report(" Invalid Cached Option: %s_sl2vl: Using Default\n",
914 str = strdup(*sl2vl);
916 tok = strtok_r(str, ",\n", &ptr);
918 long vl = strtol(tok, &end, 0);
921 log_report(" Warning: Cached Option %s_sl2vl:vl=%s "
922 "improperly formatted\n", prefix, tok);
923 else if (vl < 0 || vl > 15)
924 log_report(" Warning: Cached Option %s_sl2vl:vl=%ld "
925 "out of range\n", prefix, vl);
928 tok = strtok_r(NULL, ",\n", &ptr);
932 log_report(" Warning: Cached Option %s_sl2vl: < 16 VLs "
936 log_report(" Warning: Cached Option %s_sl2vl: > 16 listed: "
937 "excess VLs will be dropped\n", prefix);
942 static void subn_verify_qos_set(osm_qos_options_t *set, const char *prefix,
943 osm_qos_options_t *dflt)
945 subn_verify_max_vls(&set->max_vls, prefix, dflt->max_vls);
946 subn_verify_high_limit(&set->high_limit, prefix, dflt->high_limit);
947 subn_verify_vlarb(&set->vlarb_low, prefix, "low", dflt->vlarb_low);
948 subn_verify_vlarb(&set->vlarb_high, prefix, "high", dflt->vlarb_high);
949 subn_verify_sl2vl(&set->sl2vl, prefix, dflt->sl2vl);
952 int osm_subn_verify_config(IN osm_subn_opt_t * const p_opts)
954 if (p_opts->lmc > 7) {
955 log_report(" Invalid Cached Option Value:lmc = %u:"
956 "Using Default:%u\n", p_opts->lmc, OSM_DEFAULT_LMC);
957 p_opts->lmc = OSM_DEFAULT_LMC;
960 if (15 < p_opts->sm_priority) {
961 log_report(" Invalid Cached Option Value:sm_priority = %u:"
962 "Using Default:%u\n",
963 p_opts->sm_priority, OSM_DEFAULT_SM_PRIORITY);
964 p_opts->sm_priority = OSM_DEFAULT_SM_PRIORITY;
967 if ((15 < p_opts->force_link_speed) ||
968 (p_opts->force_link_speed > 7 && p_opts->force_link_speed < 15)) {
969 log_report(" Invalid Cached Option Value:force_link_speed = %u:"
970 "Using Default:%u\n", p_opts->force_link_speed,
971 IB_PORT_LINK_SPEED_ENABLED_MASK);
972 p_opts->force_link_speed = IB_PORT_LINK_SPEED_ENABLED_MASK;
975 if (strcmp(p_opts->console, OSM_DISABLE_CONSOLE)
976 && strcmp(p_opts->console, OSM_LOCAL_CONSOLE)
977 #ifdef ENABLE_OSM_CONSOLE_SOCKET
978 && strcmp(p_opts->console, OSM_LOOPBACK_CONSOLE)
979 && strcmp(p_opts->console, OSM_REMOTE_CONSOLE)
982 log_report(" Invalid Cached Option Value:console = %s"
983 ", Using Default:%s\n",
984 p_opts->console, OSM_DEFAULT_CONSOLE);
985 p_opts->console = OSM_DEFAULT_CONSOLE;
989 osm_qos_options_t dflt;
991 /* the default options in qos_options must be correct.
992 * every other one need not be, b/c those will default
993 * back to whatever is in qos_options.
996 subn_set_default_qos_options(&dflt);
998 subn_verify_qos_set(&p_opts->qos_options, "qos", &dflt);
999 subn_verify_qos_set(&p_opts->qos_ca_options, "qos_ca",
1000 &p_opts->qos_options);
1001 subn_verify_qos_set(&p_opts->qos_sw0_options, "qos_sw0",
1002 &p_opts->qos_options);
1003 subn_verify_qos_set(&p_opts->qos_swe_options, "qos_swe",
1004 &p_opts->qos_options);
1005 subn_verify_qos_set(&p_opts->qos_rtr_options, "qos_rtr",
1006 &p_opts->qos_options);
1009 #ifdef ENABLE_OSM_PERF_MGR
1010 if (p_opts->perfmgr_sweep_time_s < 1) {
1011 log_report(" Invalid Cached Option Value:perfmgr_sweep_time_s "
1012 "= %u Using Default:%u\n",
1013 p_opts->perfmgr_sweep_time_s,
1014 OSM_PERFMGR_DEFAULT_SWEEP_TIME_S);
1015 p_opts->perfmgr_sweep_time_s = OSM_PERFMGR_DEFAULT_SWEEP_TIME_S;
1017 if (p_opts->perfmgr_max_outstanding_queries < 1) {
1018 log_report(" Invalid Cached Option Value:"
1019 "perfmgr_max_outstanding_queries = %u"
1020 " Using Default:%u\n",
1021 p_opts->perfmgr_max_outstanding_queries,
1022 OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES);
1023 p_opts->perfmgr_max_outstanding_queries =
1024 OSM_PERFMGR_DEFAULT_MAX_OUTSTANDING_QUERIES;
1031 /**********************************************************************
1032 **********************************************************************/
1033 int osm_subn_parse_conf_file(char *file_name, osm_subn_opt_t * const p_opts)
1037 char *p_key, *p_val;
1039 opts_file = fopen(file_name, "r");
1041 if (errno == ENOENT)
1043 printf("cannot open file \'%s\': %s\n",
1044 file_name, strerror(errno));
1048 printf(" Reading Cached Option File: %s\n", file_name);
1049 cl_log_event("OpenSM", CL_LOG_INFO, line, NULL, 0);
1051 p_opts->config_file = file_name;
1053 while (fgets(line, 1023, opts_file) != NULL) {
1054 /* get the first token */
1055 p_key = strtok_r(line, " \t\n", &p_val);
1059 p_val = clean_val(p_val);
1061 opts_unpack_net64("guid", p_key, p_val, &p_opts->guid);
1063 opts_unpack_net64("m_key", p_key, p_val, &p_opts->m_key);
1065 opts_unpack_net64("sm_key", p_key, p_val, &p_opts->sm_key);
1067 opts_unpack_net64("sa_key", p_key, p_val, &p_opts->sa_key);
1069 opts_unpack_net64("subnet_prefix",
1070 p_key, p_val, &p_opts->subnet_prefix);
1072 opts_unpack_net16("m_key_lease_period",
1073 p_key, p_val, &p_opts->m_key_lease_period);
1075 opts_unpack_uint32("sweep_interval",
1076 p_key, p_val, &p_opts->sweep_interval);
1078 opts_unpack_uint32("max_wire_smps",
1079 p_key, p_val, &p_opts->max_wire_smps);
1081 opts_unpack_charp("console", p_key, p_val, &p_opts->console);
1083 opts_unpack_uint16("console_port",
1084 p_key, p_val, &p_opts->console_port);
1086 opts_unpack_uint32("transaction_timeout",
1087 p_key, p_val, &p_opts->transaction_timeout);
1089 opts_unpack_uint32("max_msg_fifo_timeout",
1090 p_key, p_val, &p_opts->max_msg_fifo_timeout);
1092 opts_unpack_uint8("sm_priority",
1093 p_key, p_val, &p_opts->sm_priority);
1095 opts_unpack_uint8("lmc", p_key, p_val, &p_opts->lmc);
1097 opts_unpack_boolean("lmc_esp0",
1098 p_key, p_val, &p_opts->lmc_esp0);
1100 opts_unpack_uint8("max_op_vls",
1101 p_key, p_val, &p_opts->max_op_vls);
1103 opts_unpack_uint8("force_link_speed",
1104 p_key, p_val, &p_opts->force_link_speed);
1106 opts_unpack_boolean("reassign_lids",
1107 p_key, p_val, &p_opts->reassign_lids);
1109 opts_unpack_boolean("ignore_other_sm",
1110 p_key, p_val, &p_opts->ignore_other_sm);
1112 opts_unpack_boolean("single_thread",
1113 p_key, p_val, &p_opts->single_thread);
1115 opts_unpack_boolean("disable_multicast",
1116 p_key, p_val, &p_opts->disable_multicast);
1118 opts_unpack_boolean("force_log_flush",
1119 p_key, p_val, &p_opts->force_log_flush);
1121 opts_unpack_uint8("subnet_timeout",
1122 p_key, p_val, &p_opts->subnet_timeout);
1124 opts_unpack_uint8("packet_life_time",
1125 p_key, p_val, &p_opts->packet_life_time);
1127 opts_unpack_uint8("vl_stall_count",
1128 p_key, p_val, &p_opts->vl_stall_count);
1130 opts_unpack_uint8("leaf_vl_stall_count",
1131 p_key, p_val, &p_opts->leaf_vl_stall_count);
1133 opts_unpack_uint8("head_of_queue_lifetime",
1135 &p_opts->head_of_queue_lifetime);
1137 opts_unpack_uint8("leaf_head_of_queue_lifetime", p_key, p_val,
1138 &p_opts->leaf_head_of_queue_lifetime);
1140 opts_unpack_uint8("local_phy_errors_threshold", p_key, p_val,
1141 &p_opts->local_phy_errors_threshold);
1143 opts_unpack_uint8("overrun_errors_threshold",
1145 &p_opts->overrun_errors_threshold);
1147 opts_unpack_uint32("sminfo_polling_timeout",
1149 &p_opts->sminfo_polling_timeout);
1151 opts_unpack_uint32("polling_retry_number",
1152 p_key, p_val, &p_opts->polling_retry_number);
1154 opts_unpack_boolean("force_heavy_sweep",
1155 p_key, p_val, &p_opts->force_heavy_sweep);
1157 opts_unpack_uint8("log_flags",
1158 p_key, p_val, &p_opts->log_flags);
1160 opts_unpack_charp("port_prof_ignore_file", p_key, p_val,
1161 &p_opts->port_prof_ignore_file);
1163 opts_unpack_boolean("port_profile_switch_nodes", p_key, p_val,
1164 &p_opts->port_profile_switch_nodes);
1166 opts_unpack_boolean("sweep_on_trap",
1167 p_key, p_val, &p_opts->sweep_on_trap);
1169 opts_unpack_charp("routing_engine",
1170 p_key, p_val, &p_opts->routing_engine_names);
1172 opts_unpack_boolean("connect_roots",
1173 p_key, p_val, &p_opts->connect_roots);
1175 opts_unpack_boolean("use_ucast_cache",
1176 p_key, p_val, &p_opts->use_ucast_cache);
1178 opts_unpack_charp("log_file", p_key, p_val, &p_opts->log_file);
1180 opts_unpack_uint32("log_max_size",
1182 (void *) & p_opts->log_max_size);
1183 p_opts->log_max_size *= 1024 * 1024; /* convert to MB */
1185 opts_unpack_charp("partition_config_file",
1186 p_key, p_val, &p_opts->partition_config_file);
1188 opts_unpack_boolean("no_partition_enforcement", p_key, p_val,
1189 &p_opts->no_partition_enforcement);
1191 opts_unpack_boolean("qos", p_key, p_val, &p_opts->qos);
1193 opts_unpack_charp("qos_policy_file",
1194 p_key, p_val, &p_opts->qos_policy_file);
1196 opts_unpack_boolean("accum_log_file",
1197 p_key, p_val, &p_opts->accum_log_file);
1199 opts_unpack_charp("dump_files_dir",
1200 p_key, p_val, &p_opts->dump_files_dir);
1202 opts_unpack_charp("lid_matrix_dump_file",
1203 p_key, p_val, &p_opts->lid_matrix_dump_file);
1205 opts_unpack_charp("lfts_file",
1206 p_key, p_val, &p_opts->lfts_file);
1208 opts_unpack_charp("root_guid_file",
1209 p_key, p_val, &p_opts->root_guid_file);
1211 opts_unpack_charp("cn_guid_file",
1212 p_key, p_val, &p_opts->cn_guid_file);
1214 opts_unpack_charp("ids_guid_file",
1215 p_key, p_val, &p_opts->ids_guid_file);
1217 opts_unpack_charp("guid_routing_order_file",
1218 p_key, p_val, &p_opts->guid_routing_order_file);
1220 opts_unpack_charp("sa_db_file",
1221 p_key, p_val, &p_opts->sa_db_file);
1223 opts_unpack_boolean("exit_on_fatal",
1224 p_key, p_val, &p_opts->exit_on_fatal);
1226 opts_unpack_boolean("honor_guid2lid_file",
1227 p_key, p_val, &p_opts->honor_guid2lid_file);
1229 opts_unpack_boolean("daemon", p_key, p_val, &p_opts->daemon);
1231 opts_unpack_boolean("sm_inactive",
1232 p_key, p_val, &p_opts->sm_inactive);
1234 opts_unpack_boolean("babbling_port_policy",
1236 &p_opts->babbling_port_policy);
1238 #ifdef ENABLE_OSM_PERF_MGR
1239 opts_unpack_boolean("perfmgr", p_key, p_val, &p_opts->perfmgr);
1241 opts_unpack_boolean("perfmgr_redir",
1242 p_key, p_val, &p_opts->perfmgr_redir);
1244 opts_unpack_uint16("perfmgr_sweep_time_s",
1245 p_key, p_val, &p_opts->perfmgr_sweep_time_s);
1247 opts_unpack_uint32("perfmgr_max_outstanding_queries",
1249 &p_opts->perfmgr_max_outstanding_queries);
1251 opts_unpack_charp("event_db_dump_file",
1252 p_key, p_val, &p_opts->event_db_dump_file);
1253 #endif /* ENABLE_OSM_PERF_MGR */
1255 opts_unpack_charp("event_plugin_name",
1256 p_key, p_val, &p_opts->event_plugin_name);
1258 opts_unpack_charp("node_name_map_name",
1259 p_key, p_val, &p_opts->node_name_map_name);
1261 subn_parse_qos_options("qos",
1262 p_key, p_val, &p_opts->qos_options);
1264 subn_parse_qos_options("qos_ca",
1265 p_key, p_val, &p_opts->qos_ca_options);
1267 subn_parse_qos_options("qos_sw0",
1268 p_key, p_val, &p_opts->qos_sw0_options);
1270 subn_parse_qos_options("qos_swe",
1271 p_key, p_val, &p_opts->qos_swe_options);
1273 subn_parse_qos_options("qos_rtr",
1274 p_key, p_val, &p_opts->qos_rtr_options);
1276 opts_unpack_boolean("enable_quirks",
1277 p_key, p_val, &p_opts->enable_quirks);
1279 opts_unpack_boolean("no_clients_rereg",
1280 p_key, p_val, &p_opts->no_clients_rereg);
1282 opts_unpack_charp("prefix_routes_file",
1283 p_key, p_val, &p_opts->prefix_routes_file);
1285 opts_unpack_boolean("consolidate_ipv6_snm_req",
1286 p_key, p_val, &p_opts->consolidate_ipv6_snm_req);
1290 osm_subn_verify_config(p_opts);
1295 int osm_subn_rescan_conf_files(IN osm_subn_t * const p_subn)
1299 char *p_key, *p_val, *p_last;
1301 if (!p_subn->opt.config_file)
1304 opts_file = fopen(p_subn->opt.config_file, "r");
1306 if (errno == ENOENT)
1308 OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR,
1309 "cannot open file \'%s\': %s\n",
1310 p_subn->opt.config_file, strerror(errno));
1314 subn_init_qos_options(&p_subn->opt.qos_options);
1315 subn_init_qos_options(&p_subn->opt.qos_ca_options);
1316 subn_init_qos_options(&p_subn->opt.qos_sw0_options);
1317 subn_init_qos_options(&p_subn->opt.qos_swe_options);
1318 subn_init_qos_options(&p_subn->opt.qos_rtr_options);
1320 while (fgets(line, 1023, opts_file) != NULL) {
1321 /* get the first token */
1322 p_key = strtok_r(line, " \t\n", &p_last);
1324 p_val = strtok_r(NULL, " \t\n", &p_last);
1326 subn_parse_qos_options("qos", p_key, p_val,
1327 &p_subn->opt.qos_options);
1329 subn_parse_qos_options("qos_ca", p_key, p_val,
1330 &p_subn->opt.qos_ca_options);
1332 subn_parse_qos_options("qos_sw0", p_key, p_val,
1333 &p_subn->opt.qos_sw0_options);
1335 subn_parse_qos_options("qos_swe", p_key, p_val,
1336 &p_subn->opt.qos_swe_options);
1338 subn_parse_qos_options("qos_rtr", p_key, p_val,
1339 &p_subn->opt.qos_rtr_options);
1345 osm_subn_verify_config(&p_subn->opt);
1347 osm_parse_prefix_routes_file(p_subn);
1352 /**********************************************************************
1353 **********************************************************************/
1354 int osm_subn_output_conf(FILE *out, IN osm_subn_opt_t *const p_opts)
1357 "#\n# DEVICE ATTRIBUTES OPTIONS\n#\n"
1358 "# The port GUID on which the OpenSM is running\n"
1359 "guid 0x%016" PRIx64 "\n\n"
1360 "# M_Key value sent to all ports qualifying all Set(PortInfo)\n"
1361 "m_key 0x%016" PRIx64 "\n\n"
1362 "# The lease period used for the M_Key on this subnet in [sec]\n"
1363 "m_key_lease_period %u\n\n"
1364 "# SM_Key value of the SM used for SM authentication\n"
1365 "sm_key 0x%016" PRIx64 "\n\n"
1366 "# SM_Key value to qualify rcv SA queries as 'trusted'\n"
1367 "sa_key 0x%016" PRIx64 "\n\n"
1368 "# Note that for both values above (sm_key and sa_key)\n"
1369 "# OpenSM version 3.2.1 and below used the default value '1'\n"
1370 "# in a host byte order, it is fixed now but you may need to\n"
1371 "# change the values to interoperate with old OpenSM running\n"
1372 "# on a little endian machine.\n\n"
1373 "# Subnet prefix used on this subnet\n"
1374 "subnet_prefix 0x%016" PRIx64 "\n\n"
1375 "# The LMC value used on this subnet\n"
1377 "# lmc_esp0 determines whether LMC value used on subnet is used for\n"
1378 "# enhanced switch port 0. If TRUE, LMC value for subnet is used for\n"
1379 "# ESP0. Otherwise, LMC value for ESP0s is 0.\n"
1381 "# The code of maximal time a packet can live in a switch\n"
1382 "# The actual time is 4.096usec * 2^<packet_life_time>\n"
1383 "# The value 0x14 disables this mechanism\n"
1384 "packet_life_time 0x%02x\n\n"
1385 "# The number of sequential packets dropped that cause the port\n"
1386 "# to enter the VLStalled state. The result of setting this value to\n"
1387 "# zero is undefined.\n"
1388 "vl_stall_count 0x%02x\n\n"
1389 "# The number of sequential packets dropped that cause the port\n"
1390 "# to enter the VLStalled state. This value is for switch ports\n"
1391 "# driving a CA or router port. The result of setting this value\n"
1392 "# to zero is undefined.\n"
1393 "leaf_vl_stall_count 0x%02x\n\n"
1394 "# The code of maximal time a packet can wait at the head of\n"
1395 "# transmission queue.\n"
1396 "# The actual time is 4.096usec * 2^<head_of_queue_lifetime>\n"
1397 "# The value 0x14 disables this mechanism\n"
1398 "head_of_queue_lifetime 0x%02x\n\n"
1399 "# The maximal time a packet can wait at the head of queue on\n"
1400 "# switch port connected to a CA or router port\n"
1401 "leaf_head_of_queue_lifetime 0x%02x\n\n"
1402 "# Limit the maximal operational VLs\n"
1404 "# Force PortInfo:LinkSpeedEnabled on switch ports\n"
1405 "# If 0, don't modify PortInfo:LinkSpeedEnabled on switch port\n"
1406 "# Otherwise, use value for PortInfo:LinkSpeedEnabled on switch port\n"
1407 "# Values are (IB Spec 1.2.1, 14.2.5.6 Table 146 \"PortInfo\")\n"
1409 "# 3: 2.5 or 5.0 Gbps\n"
1410 "# 5: 2.5 or 10.0 Gbps\n"
1411 "# 7: 2.5 or 5.0 or 10.0 Gbps\n"
1412 "# 2,4,6,8-14 Reserved\n"
1413 "# Default 15: set to PortInfo:LinkSpeedSupported\n"
1414 "force_link_speed %u\n\n"
1415 "# The subnet_timeout code that will be set for all the ports\n"
1416 "# The actual timeout is 4.096usec * 2^<subnet_timeout>\n"
1417 "subnet_timeout %u\n\n"
1418 "# Threshold of local phy errors for sending Trap 129\n"
1419 "local_phy_errors_threshold 0x%02x\n\n"
1420 "# Threshold of credit overrun errors for sending Trap 130\n"
1421 "overrun_errors_threshold 0x%02x\n\n",
1422 cl_ntoh64(p_opts->guid),
1423 cl_ntoh64(p_opts->m_key),
1424 cl_ntoh16(p_opts->m_key_lease_period),
1425 cl_ntoh64(p_opts->sm_key),
1426 cl_ntoh64(p_opts->sa_key),
1427 cl_ntoh64(p_opts->subnet_prefix),
1429 p_opts->lmc_esp0 ? "TRUE" : "FALSE",
1430 p_opts->packet_life_time,
1431 p_opts->vl_stall_count,
1432 p_opts->leaf_vl_stall_count,
1433 p_opts->head_of_queue_lifetime,
1434 p_opts->leaf_head_of_queue_lifetime,
1436 p_opts->force_link_speed,
1437 p_opts->subnet_timeout,
1438 p_opts->local_phy_errors_threshold,
1439 p_opts->overrun_errors_threshold);
1442 "#\n# PARTITIONING OPTIONS\n#\n"
1443 "# Partition configuration file to be used\n"
1444 "partition_config_file %s\n\n"
1445 "# Disable partition enforcement by switches\n"
1446 "no_partition_enforcement %s\n\n",
1447 p_opts->partition_config_file,
1448 p_opts->no_partition_enforcement ? "TRUE" : "FALSE");
1451 "#\n# SWEEP OPTIONS\n#\n"
1452 "# The number of seconds between subnet sweeps (0 disables it)\n"
1453 "sweep_interval %u\n\n"
1454 "# If TRUE cause all lids to be reassigned\n"
1455 "reassign_lids %s\n\n"
1456 "# If TRUE forces every sweep to be a heavy sweep\n"
1457 "force_heavy_sweep %s\n\n"
1458 "# If TRUE every trap will cause a heavy sweep.\n"
1459 "# NOTE: successive identical traps (>10) are suppressed\n"
1460 "sweep_on_trap %s\n\n",
1461 p_opts->sweep_interval,
1462 p_opts->reassign_lids ? "TRUE" : "FALSE",
1463 p_opts->force_heavy_sweep ? "TRUE" : "FALSE",
1464 p_opts->sweep_on_trap ? "TRUE" : "FALSE");
1467 "#\n# ROUTING OPTIONS\n#\n"
1468 "# If TRUE count switches as link subscriptions\n"
1469 "port_profile_switch_nodes %s\n\n",
1470 p_opts->port_profile_switch_nodes ? "TRUE" : "FALSE");
1473 "# Name of file with port guids to be ignored by port profiling\n"
1474 "port_prof_ignore_file %s\n\n", p_opts->port_prof_ignore_file ?
1475 p_opts->port_prof_ignore_file : null_str);
1478 "# Routing engine\n"
1479 "# Multiple routing engines can be specified separated by\n"
1480 "# commas so that specific ordering of routing algorithms will\n"
1481 "# be tried if earlier routing engines fail.\n"
1482 "# Supported engines: minhop, updn, file, ftree, lash, dor\n"
1483 "routing_engine %s\n\n", p_opts->routing_engine_names ?
1484 p_opts->routing_engine_names : null_str);
1487 "# Connect roots (use FALSE if unsure)\n"
1488 "connect_roots %s\n\n",
1489 p_opts->connect_roots ? "TRUE" : "FALSE");
1492 "# Use unicast routing cache (use FALSE if unsure)\n"
1493 "use_ucast_cache %s\n\n",
1494 p_opts->use_ucast_cache ? "TRUE" : "FALSE");
1497 "# Lid matrix dump file name\n"
1498 "lid_matrix_dump_file %s\n\n", p_opts->lid_matrix_dump_file ?
1499 p_opts->lid_matrix_dump_file : null_str);
1502 "# LFTs file name\nlfts_file %s\n\n",
1503 p_opts->lfts_file ? p_opts->lfts_file : null_str);
1506 "# The file holding the root node guids (for fat-tree or Up/Down)\n"
1507 "# One guid in each line\nroot_guid_file %s\n\n",
1508 p_opts->root_guid_file ? p_opts->root_guid_file : null_str);
1511 "# The file holding the fat-tree compute node guids\n"
1512 "# One guid in each line\ncn_guid_file %s\n\n",
1513 p_opts->cn_guid_file ? p_opts->cn_guid_file : null_str);
1516 "# The file holding the node ids which will be used by"
1517 " Up/Down algorithm instead\n# of GUIDs (one guid and"
1518 " id in each line)\nids_guid_file %s\n\n",
1519 p_opts->ids_guid_file ? p_opts->ids_guid_file : null_str);
1522 "# The file holding guid routing order guids (for MinHop and Up/Down)\n"
1523 "guid_routing_order_file %s\n\n",
1524 p_opts->guid_routing_order_file ? p_opts->guid_routing_order_file : null_str);
1527 "# SA database file name\nsa_db_file %s\n\n",
1528 p_opts->sa_db_file ? p_opts->sa_db_file : null_str);
1531 "#\n# HANDOVER - MULTIPLE SMs OPTIONS\n#\n"
1532 "# SM priority used for deciding who is the master\n"
1533 "# Range goes from 0 (lowest priority) to 15 (highest).\n"
1534 "sm_priority %u\n\n"
1535 "# If TRUE other SMs on the subnet should be ignored\n"
1536 "ignore_other_sm %s\n\n"
1537 "# Timeout in [msec] between two polls of active master SM\n"
1538 "sminfo_polling_timeout %u\n\n"
1539 "# Number of failing polls of remote SM that declares it dead\n"
1540 "polling_retry_number %u\n\n"
1541 "# If TRUE honor the guid2lid file when coming out of standby\n"
1542 "# state, if such file exists and is valid\n"
1543 "honor_guid2lid_file %s\n\n",
1544 p_opts->sm_priority,
1545 p_opts->ignore_other_sm ? "TRUE" : "FALSE",
1546 p_opts->sminfo_polling_timeout,
1547 p_opts->polling_retry_number,
1548 p_opts->honor_guid2lid_file ? "TRUE" : "FALSE");
1551 "#\n# TIMING AND THREADING OPTIONS\n#\n"
1552 "# Maximum number of SMPs sent in parallel\n"
1553 "max_wire_smps %u\n\n"
1554 "# The maximum time in [msec] allowed for a transaction to complete\n"
1555 "transaction_timeout %u\n\n"
1556 "# Maximal time in [msec] a message can stay in the incoming message queue.\n"
1557 "# If there is more than one message in the queue and the last message\n"
1558 "# stayed in the queue more than this value, any SA request will be\n"
1559 "# immediately returned with a BUSY status.\n"
1560 "max_msg_fifo_timeout %u\n\n"
1561 "# Use a single thread for handling SA queries\n"
1562 "single_thread %s\n\n",
1563 p_opts->max_wire_smps,
1564 p_opts->transaction_timeout,
1565 p_opts->max_msg_fifo_timeout,
1566 p_opts->single_thread ? "TRUE" : "FALSE");
1569 "#\n# MISC OPTIONS\n#\n"
1573 "sm_inactive %s\n\n"
1574 "# Babbling Port Policy\n"
1575 "babbling_port_policy %s\n\n",
1576 p_opts->daemon ? "TRUE" : "FALSE",
1577 p_opts->sm_inactive ? "TRUE" : "FALSE",
1578 p_opts->babbling_port_policy ? "TRUE" : "FALSE");
1580 #ifdef ENABLE_OSM_PERF_MGR
1582 "#\n# Performance Manager Options\n#\n"
1583 "# perfmgr enable\n"
1585 "# perfmgr redirection enable\n"
1586 "perfmgr_redir %s\n\n"
1587 "# sweep time in seconds\n"
1588 "perfmgr_sweep_time_s %u\n\n"
1589 "# Max outstanding queries\n"
1590 "perfmgr_max_outstanding_queries %u\n\n",
1591 p_opts->perfmgr ? "TRUE" : "FALSE",
1592 p_opts->perfmgr_redir ? "TRUE" : "FALSE",
1593 p_opts->perfmgr_sweep_time_s,
1594 p_opts->perfmgr_max_outstanding_queries);
1597 "#\n# Event DB Options\n#\n"
1598 "# Dump file to dump the events to\n"
1599 "event_db_dump_file %s\n\n", p_opts->event_db_dump_file ?
1600 p_opts->event_db_dump_file : null_str);
1601 #endif /* ENABLE_OSM_PERF_MGR */
1604 "#\n# Event Plugin Options\n#\n"
1605 "event_plugin_name %s\n\n", p_opts->event_plugin_name ?
1606 p_opts->event_plugin_name : null_str);
1609 "#\n# Node name map for mapping node's to more descriptive node descriptions\n"
1610 "# (man ibnetdiscover for more information)\n#\n"
1611 "node_name_map_name %s\n\n", p_opts->node_name_map_name ?
1612 p_opts->node_name_map_name : null_str);
1615 "#\n# DEBUG FEATURES\n#\n"
1616 "# The log flags used\n"
1617 "log_flags 0x%02x\n\n"
1618 "# Force flush of the log file after each log message\n"
1619 "force_log_flush %s\n\n"
1620 "# Log file to be used\n"
1622 "# Limit the size of the log file in MB. If overrun, log is restarted\n"
1623 "log_max_size %lu\n\n"
1624 "# If TRUE will accumulate the log over multiple OpenSM sessions\n"
1625 "accum_log_file %s\n\n"
1626 "# The directory to hold the file OpenSM dumps\n"
1627 "dump_files_dir %s\n\n"
1628 "# If TRUE enables new high risk options and hardware specific quirks\n"
1629 "enable_quirks %s\n\n"
1630 "# If TRUE disables client reregistration\n"
1631 "no_clients_rereg %s\n\n"
1632 "# If TRUE OpenSM should disable multicast support and\n"
1633 "# no multicast routing is performed if TRUE\n"
1634 "disable_multicast %s\n\n"
1635 "# If TRUE opensm will exit on fatal initialization issues\n"
1636 "exit_on_fatal %s\n\n" "# console [off|local"
1637 #ifdef ENABLE_OSM_CONSOLE_SOCKET
1638 "|loopback|socket]\n"
1643 "# Telnet port for console (default %d)\n"
1644 "console_port %d\n\n",
1646 p_opts->force_log_flush ? "TRUE" : "FALSE",
1648 p_opts->log_max_size/1024/1024,
1649 p_opts->accum_log_file ? "TRUE" : "FALSE",
1650 p_opts->dump_files_dir,
1651 p_opts->enable_quirks ? "TRUE" : "FALSE",
1652 p_opts->no_clients_rereg ? "TRUE" : "FALSE",
1653 p_opts->disable_multicast ? "TRUE" : "FALSE",
1654 p_opts->exit_on_fatal ? "TRUE" : "FALSE",
1656 OSM_DEFAULT_CONSOLE_PORT, p_opts->console_port);
1659 "#\n# QoS OPTIONS\n#\n"
1660 "# Enable QoS setup\n"
1662 "# QoS policy file to be used\n"
1663 "qos_policy_file %s\n\n",
1664 p_opts->qos ? "TRUE" : "FALSE", p_opts->qos_policy_file);
1666 subn_dump_qos_options(out,
1667 "QoS default options", "qos",
1668 &p_opts->qos_options);
1670 subn_dump_qos_options(out,
1671 "QoS CA options", "qos_ca",
1672 &p_opts->qos_ca_options);
1674 subn_dump_qos_options(out,
1675 "QoS Switch Port 0 options", "qos_sw0",
1676 &p_opts->qos_sw0_options);
1678 subn_dump_qos_options(out,
1679 "QoS Switch external ports options", "qos_swe",
1680 &p_opts->qos_swe_options);
1682 subn_dump_qos_options(out,
1683 "QoS Router ports options", "qos_rtr",
1684 &p_opts->qos_rtr_options);
1688 "# Prefix routes file name\n"
1689 "prefix_routes_file %s\n\n",
1690 p_opts->prefix_routes_file);
1693 "#\n# IPv6 Solicited Node Multicast (SNM) Options\n#\n"
1694 "consolidate_ipv6_snm_req %s\n\n",
1695 p_opts->consolidate_ipv6_snm_req ? "TRUE" : "FALSE");
1697 /* optional string attributes ... */
1702 int osm_subn_write_conf_file(char *file_name, IN osm_subn_opt_t *const p_opts)
1706 opts_file = fopen(file_name, "w");
1708 printf("cannot open file \'%s\' for writing: %s\n",
1709 file_name, strerror(errno));
1713 if (osm_subn_output_conf(opts_file, p_opts) < 0)