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.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 * Command line interface for opensm.
43 #endif /* HAVE_CONFIG_H */
50 #include <sys/types.h>
53 #include <complib/cl_types.h>
54 #include <complib/cl_debug.h>
55 #include <vendor/osm_vendor_api.h>
56 #include <opensm/osm_version.h>
57 #include <opensm/osm_opensm.h>
58 #include <opensm/osm_console.h>
59 #include <opensm/osm_console_io.h>
60 #include <opensm/osm_perfmgr.h>
62 volatile unsigned int osm_exit_flag = 0;
64 static volatile unsigned int osm_hup_flag = 0;
65 static volatile unsigned int osm_usr1_flag = 0;
67 #define GUID_ARRAY_SIZE 64
68 #define INVALID_GUID (0xFFFFFFFFFFFFFFFFULL)
70 static void mark_exit_flag(int signum)
73 printf("OpenSM: Got signal %d - exiting...\n", signum);
77 static void mark_hup_flag(int signum)
82 static void mark_usr1_flag(int signum)
87 static sigset_t saved_sigset;
89 static void block_signals()
94 sigaddset(&set, SIGINT);
95 sigaddset(&set, SIGTERM);
96 sigaddset(&set, SIGHUP);
97 #ifndef HAVE_OLD_LINUX_THREADS
98 sigaddset(&set, SIGUSR1);
100 pthread_sigmask(SIG_SETMASK, &set, &saved_sigset);
103 static void setup_signals()
105 struct sigaction act;
107 sigemptyset(&act.sa_mask);
108 act.sa_handler = mark_exit_flag;
110 sigaction(SIGINT, &act, NULL);
111 sigaction(SIGTERM, &act, NULL);
112 act.sa_handler = mark_hup_flag;
113 sigaction(SIGHUP, &act, NULL);
114 sigaction(SIGCONT, &act, NULL);
115 #ifndef HAVE_OLD_LINUX_THREADS
116 act.sa_handler = mark_usr1_flag;
117 sigaction(SIGUSR1, &act, NULL);
119 pthread_sigmask(SIG_SETMASK, &saved_sigset, NULL);
122 /**********************************************************************
123 **********************************************************************/
125 static void show_usage(void)
127 printf("\n------- OpenSM - Usage and options ----------------------\n");
128 printf("Usage: opensm [options]\n");
129 printf("Options:\n");
130 printf("--version\n Prints OpenSM version and exits.\n\n");
131 printf("--config, -F <file-name>\n"
132 " The name of the OpenSM config file. When not specified\n"
133 " " OSM_DEFAULT_CONFIG_FILE " will be used (if exists).\n\n");
134 printf("--create-config, -c <file-name>\n"
135 " OpenSM will dump its configuration to the specified file and exit.\n"
136 " This is a way to generate OpenSM configuration file template.\n\n");
137 printf("--guid, -g <GUID in hex>\n"
138 " This option specifies the local port GUID value\n"
139 " with which OpenSM should bind. OpenSM may be\n"
140 " bound to 1 port at a time.\n"
141 " If GUID given is 0, OpenSM displays a list\n"
142 " of possible port GUIDs and waits for user input.\n"
143 " Without -g, OpenSM tries to use the default port.\n\n");
144 printf("--lmc, -l <LMC>\n"
145 " This option specifies the subnet's LMC value.\n"
146 " The number of LIDs assigned to each port is 2^LMC.\n"
147 " The LMC value must be in the range 0-7.\n"
148 " LMC values > 0 allow multiple paths between ports.\n"
149 " LMC values > 0 should only be used if the subnet\n"
150 " topology actually provides multiple paths between\n"
151 " ports, i.e. multiple interconnects between switches.\n"
152 " Without -l, OpenSM defaults to LMC = 0, which allows\n"
153 " one path between any two ports.\n\n");
154 printf("--priority, -p <PRIORITY>\n"
155 " This option specifies the SM's PRIORITY.\n"
156 " This will effect the handover cases, where master\n"
157 " is chosen by priority and GUID. Range goes\n"
158 " from 0 (lowest priority) to 15 (highest).\n\n");
159 printf("--smkey, -k <SM_Key>\n"
160 " This option specifies the SM's SM_Key (64 bits).\n"
161 " This will effect SM authentication.\n"
162 " Note that OpenSM version 3.2.1 and below used the\n"
163 " default value '1' in a host byte order, it is fixed\n"
164 " now but you may need this option to interoperate\n"
165 " with old OpenSM running on a little endian machine.\n\n");
166 printf("--reassign_lids, -r\n"
167 " This option causes OpenSM to reassign LIDs to all\n"
168 " end nodes. Specifying -r on a running subnet\n"
169 " may disrupt subnet traffic.\n"
170 " Without -r, OpenSM attempts to preserve existing\n"
171 " LID assignments resolving multiple use of same LID.\n\n");
172 printf("--routing_engine, -R <engine name>\n"
173 " This option chooses routing engine(s) to use instead of default\n"
174 " Min Hop algorithm. Multiple routing engines can be specified\n"
175 " separated by commas so that specific ordering of routing\n"
176 " algorithms will be tried if earlier routing engines fail.\n"
177 " Supported engines: updn, file, ftree, lash, dor\n\n");
178 printf("--connect_roots, -z\n"
179 " This option enforces a routing engine (currently\n"
180 " up/down only) to make connectivity between root switches\n"
181 " and in this way be IBA compliant. In many cases,\n"
182 " this can violate \"pure\" deadlock free algorithm, so\n"
183 " use it carefully.\n\n");
184 printf("--ucast_cache, -A\n"
185 " This option enables unicast routing cache to prevent\n"
186 " routing recalculation (which is a heavy task in a\n"
187 " large cluster) when there was no topology change\n"
188 " detected during the heavy sweep, or when the topology\n"
189 " change does not require new routing calculation,\n"
190 " e.g. in case of host reboot.\n"
191 " This option becomes very handy when the cluster size\n"
192 " is thousands of nodes.\n\n");
193 printf("--lid_matrix_file, -M <file name>\n"
194 " This option specifies the name of the lid matrix dump file\n"
195 " from where switch lid matrices (min hops tables will be\n"
197 printf("--lfts_file, -U <file name>\n"
198 " This option specifies the name of the LFTs file\n"
199 " from where switch forwarding tables will be loaded.\n\n");
200 printf("--sadb_file, -S <file name>\n"
201 " This option specifies the name of the SA DB dump file\n"
202 " from where SA database will be loaded.\n\n");
203 printf("--root_guid_file, -a <path to file>\n"
204 " Set the root nodes for the Up/Down or Fat-Tree routing\n"
205 " algorithm to the guids provided in the given file (one\n"
206 " to a line)\n" "\n");
207 printf("--cn_guid_file, -u <path to file>\n"
208 " Set the compute nodes for the Fat-Tree routing algorithm\n"
209 " to the guids provided in the given file (one to a line)\n\n");
210 printf("--ids_guid_file, -m <path to file>\n"
211 " Name of the map file with set of the IDs which will be used\n"
212 " by Up/Down routing algorithm instead of node GUIDs\n"
213 " (format: <guid> <id> per line)\n\n");
214 printf("--guid_routing_order_file, -X <path to file>\n"
215 " Set the order port guids will be routed for the MinHop\n"
216 " and Up/Down routing algorithms to the guids provided in the\n"
217 " given file (one to a line)\n\n");
218 printf("--once, -o\n"
219 " This option causes OpenSM to configure the subnet\n"
220 " once, then exit. Ports remain in the ACTIVE state.\n\n");
221 printf("--sweep, -s <interval>\n"
222 " This option specifies the number of seconds between\n"
223 " subnet sweeps. Specifying -s 0 disables sweeping.\n"
224 " Without -s, OpenSM defaults to a sweep interval of\n"
226 printf("--timeout, -t <milliseconds>\n"
227 " This option specifies the time in milliseconds\n"
228 " used for transaction timeouts.\n"
229 " Specifying -t 0 disables timeouts.\n"
230 " Without -t, OpenSM defaults to a timeout value of\n"
231 " 200 milliseconds.\n\n");
232 printf("--maxsmps, -n <number>\n"
233 " This option specifies the number of VL15 SMP MADs\n"
234 " allowed on the wire at any one time.\n"
235 " Specifying --maxsmps 0 allows unlimited outstanding\n"
237 " Without --maxsmps, OpenSM defaults to a maximum of\n"
238 " 4 outstanding SMPs.\n\n");
239 printf("--console, -q [off|local"
240 #ifdef ENABLE_OSM_CONSOLE_SOCKET
243 "]\n This option activates the OpenSM console (default off).\n\n");
244 #ifdef ENABLE_OSM_CONSOLE_SOCKET
245 printf("--console-port, -C <port>\n"
246 " Specify an alternate telnet port for the console (default %d).\n\n",
247 OSM_DEFAULT_CONSOLE_PORT);
249 printf("--ignore-guids, -i <equalize-ignore-guids-file>\n"
250 " This option provides the means to define a set of ports\n"
251 " (by guid) that will be ignored by the link load\n"
252 " equalization algorithm.\n\n");
253 printf("--honor_guid2lid, -x\n"
254 " This option forces OpenSM to honor the guid2lid file,\n"
255 " when it comes out of Standby state, if such file exists\n"
256 " under OSM_CACHE_DIR, and is valid. By default, this is FALSE.\n\n");
257 printf("--log_file, -f <log-file-name>\n"
258 " This option defines the log to be the given file.\n"
259 " By default, the log goes to /var/log/opensm.log.\n"
260 " For the log to go to standard output use -f stdout.\n\n");
261 printf("--log_limit, -L <size in MB>\n"
262 " This option defines maximal log file size in MB. When\n"
263 " specified the log file will be truncated upon reaching\n"
265 printf("--erase_log_file, -e\n"
266 " This option will cause deletion of the log file\n"
267 " (if it previously exists). By default, the log file\n"
268 " is accumulative.\n\n");
269 printf("--Pconfig, -P <partition-config-file>\n"
270 " This option defines the optional partition configuration file.\n"
271 " The default name is \'"
272 OSM_DEFAULT_PARTITION_CONFIG_FILE "\'.\n\n");
273 printf("--no_part_enforce, -N\n"
274 " This option disables partition enforcement on switch external ports.\n\n");
275 printf("--qos, -Q\n" " This option enables QoS setup.\n\n");
276 printf("--qos_policy_file, -Y <QoS-policy-file>\n"
277 " This option defines the optional QoS policy file.\n"
278 " The default name is \'" OSM_DEFAULT_QOS_POLICY_FILE
280 printf("--stay_on_fatal, -y\n"
281 " This option will cause SM not to exit on fatal initialization\n"
282 " issues: if SM discovers duplicated guids or 12x link with\n"
283 " lane reversal badly configured.\n"
284 " By default, the SM will exit on these errors.\n\n");
285 printf("--daemon, -B\n"
286 " Run in daemon mode - OpenSM will run in the background.\n\n");
287 printf("--inactive, -I\n"
288 " Start SM in inactive rather than normal init SM state.\n\n");
289 #ifdef ENABLE_OSM_PERF_MGR
290 printf("--perfmgr\n" " Start with PerfMgr enabled.\n\n");
291 printf("--perfmgr_sweep_time_s <sec.>\n"
292 " PerfMgr sweep interval in seconds.\n\n");
294 printf("--prefix_routes_file <path to file>\n"
295 " This option specifies the prefix routes file.\n"
296 " Prefix routes control how the SA responds to path record\n"
297 " queries for off-subnet DGIDs. Default file is:\n"
298 " " OSM_DEFAULT_PREFIX_ROUTES_FILE "\n\n");
299 printf("--consolidate_ipv6_snm_req\n"
300 " Consolidate IPv6 Solicited Node Multicast group joins\n"
301 " into 1 IB multicast group.\n\n");
302 printf("--verbose, -v\n"
303 " This option increases the log verbosity level.\n"
304 " The -v option may be specified multiple times\n"
305 " to further increase the verbosity level.\n"
306 " See the -D option for more information about\n"
307 " log verbosity.\n\n");
309 " This option sets the maximum verbosity level and\n"
310 " forces log flushing.\n"
311 " The -V is equivalent to '-D 0xFF -d 2'.\n"
312 " See the -D option for more information about\n"
313 " log verbosity.\n\n");
314 printf("--D, -D <flags>\n"
315 " This option sets the log verbosity level.\n"
316 " A flags field must follow the -D option.\n"
317 " A bit set/clear in the flags enables/disables a\n"
318 " specific log level as follows:\n"
319 " BIT LOG LEVEL ENABLED\n"
320 " ---- -----------------\n"
321 " 0x01 - ERROR (error messages)\n"
322 " 0x02 - INFO (basic messages, low volume)\n"
323 " 0x04 - VERBOSE (interesting stuff, moderate volume)\n"
324 " 0x08 - DEBUG (diagnostic, high volume)\n"
325 " 0x10 - FUNCS (function entry/exit, very high volume)\n"
326 " 0x20 - FRAMES (dumps all SMP and GMP frames)\n"
327 " 0x40 - ROUTING (dump FDB routing information)\n"
328 " 0x80 - currently unused.\n"
329 " Without -D, OpenSM defaults to ERROR + INFO (0x3).\n"
330 " Specifying -D 0 disables all messages.\n"
331 " Specifying -D 0xFF enables all messages (see -V).\n"
332 " High verbosity levels may require increasing\n"
333 " the transaction timeout with the -t option.\n\n");
334 printf("--debug, -d <number>\n"
335 " This option specifies a debug option.\n"
336 " These options are not normally needed.\n"
337 " The number following -d selects the debug\n"
338 " option to enable as follows:\n"
340 " --- -----------------\n"
341 " -d0 - Ignore other SM nodes\n"
342 " -d1 - Force single threaded dispatching\n"
343 " -d2 - Force log flushing after each log message\n"
344 " -d3 - Disable multicast support\n"
345 " -d10 - Put OpenSM in testability mode\n"
346 " Without -d, no debug options are enabled\n\n");
347 printf("--help, -h, -?\n"
348 " Display this usage info then exit.\n\n");
353 /**********************************************************************
354 **********************************************************************/
355 static ib_net64_t get_port_guid(IN osm_opensm_t * p_osm, uint64_t port_guid)
357 ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
358 uint32_t num_ports = GUID_ARRAY_SIZE;
360 uint32_t i, choice = 0;
361 boolean_t done_flag = FALSE;
362 ib_api_status_t status;
365 Call the transport layer for a list of local port
369 osm_vendor_get_all_port_attr(p_osm->p_vendor, attr_array,
371 if (status != IB_SUCCESS) {
372 printf("\nError from osm_vendor_get_all_port_attr (%x)\n",
377 /* if num_ports is 0 - return 0 */
378 if (num_ports == 0) {
379 printf("\nNo local ports detected!\n");
382 /* If num_ports is 1, then there is only one possible port to use.
384 if (num_ports == 1) {
385 printf("Using default GUID 0x%" PRIx64 "\n",
386 cl_hton64(attr_array[0].port_guid));
387 return (attr_array[0].port_guid);
389 /* If port_guid is 0 - use the first connected port */
390 if (port_guid == 0) {
391 for (i = 0; i < num_ports; i++)
392 if (attr_array[i].link_state > IB_LINK_DOWN)
396 printf("Using default GUID 0x%" PRIx64 "\n",
397 cl_hton64(attr_array[i].port_guid));
398 return (attr_array[i].port_guid);
401 if (p_osm->subn.opt.daemon)
404 /* More than one possible port - list all ports and let the user
406 while (done_flag == FALSE) {
407 printf("\nChoose a local port number with which to bind:\n\n");
408 for (i = 0; i < num_ports; i++)
409 /* Print the index + 1 since by convention, port
410 * numbers start with 1 on host channel adapters. */
411 printf("\t%u: GUID 0x%" PRIx64
412 ", lid %u, state %s\n", i + 1,
413 cl_ntoh64(attr_array[i].port_guid),
415 ib_get_port_state_str(attr_array[i].link_state));
416 printf("\nEnter choice (1-%u): ", i);
418 if (scanf("%u", &choice)) {
419 if (choice > num_ports || choice < 1) {
420 printf("\nError: Lame choice!\n");
427 /* get rid of the junk in the selection line */
429 printf("\nError: Lame choice!\n");
433 printf("Choice guid=0x%" PRIx64 "\n",
434 cl_ntoh64(attr_array[choice].port_guid));
435 return (attr_array[choice].port_guid);
438 /**********************************************************************
439 **********************************************************************/
441 static int daemonize(osm_opensm_t * osm)
446 fd = open("/dev/null", O_WRONLY);
452 if ((pid = fork()) < 0) {
460 if ((pid = fork()) < 0) {
477 /**********************************************************************
478 **********************************************************************/
479 int osm_manager_loop(osm_subn_opt_t * p_opt, osm_opensm_t * p_osm)
481 int console_init_flag = 0;
483 if (is_console_enabled(p_opt)) {
484 if (!osm_console_init(p_opt, &p_osm->console, &p_osm->log))
485 console_init_flag = 1;
489 Sit here forever - dwell or do console i/o & cmds
491 while (!osm_exit_flag) {
492 if (console_init_flag)
495 cl_thread_suspend(10000);
499 osm_log_reopen_file(&(p_osm->log));
503 /* a HUP signal should only start a new heavy sweep */
504 p_osm->subn.force_heavy_sweep = TRUE;
505 osm_opensm_sweep(p_osm);
508 if (is_console_enabled(p_opt))
509 osm_console_exit(&p_osm->console, &p_osm->log);
513 /**********************************************************************
514 **********************************************************************/
515 int main(int argc, char *argv[])
519 ib_net64_t sm_key = 0;
520 ib_api_status_t status;
521 uint32_t temp, dbg_lvl;
522 boolean_t run_once_flag = FALSE;
523 int32_t vendor_debug = 0;
524 uint32_t next_option;
525 char *conf_template = NULL;
527 unsigned config_file_done = 0;
528 const char *const short_option =
529 "F:c:i:f:ed:D:g:l:L:s:t:a:u:m:X:R:zM:U:S:P:Y:ANBIQvVhoryxp:n:q:k:C:";
532 In the array below, the 2nd parameter specifies the number
533 of arguments as follows:
538 const struct option long_option[] = {
539 {"version", 0, NULL, 12},
540 {"config", 1, NULL, 'F'},
541 {"create-config", 1, NULL, 'c'},
542 {"debug", 1, NULL, 'd'},
543 {"guid", 1, NULL, 'g'},
544 {"ignore_guids", 1, NULL, 'i'},
545 {"lmc", 1, NULL, 'l'},
546 {"sweep", 1, NULL, 's'},
547 {"timeout", 1, NULL, 't'},
548 {"verbose", 0, NULL, 'v'},
550 {"log_file", 1, NULL, 'f'},
551 {"log_limit", 1, NULL, 'L'},
552 {"erase_log_file", 0, NULL, 'e'},
553 {"Pconfig", 1, NULL, 'P'},
554 {"no_part_enforce", 0, NULL, 'N'},
555 {"qos", 0, NULL, 'Q'},
556 {"qos_policy_file", 1, NULL, 'Y'},
557 {"maxsmps", 1, NULL, 'n'},
558 {"console", 1, NULL, 'q'},
560 {"help", 0, NULL, 'h'},
561 {"once", 0, NULL, 'o'},
562 {"reassign_lids", 0, NULL, 'r'},
563 {"priority", 1, NULL, 'p'},
564 {"smkey", 1, NULL, 'k'},
565 {"routing_engine", 1, NULL, 'R'},
566 {"ucast_cache", 0, NULL, 'A'},
567 {"connect_roots", 0, NULL, 'z'},
568 {"lid_matrix_file", 1, NULL, 'M'},
569 {"lfts_file", 1, NULL, 'U'},
570 {"sadb_file", 1, NULL, 'S'},
571 {"root_guid_file", 1, NULL, 'a'},
572 {"cn_guid_file", 1, NULL, 'u'},
573 {"ids_guid_file", 1, NULL, 'm'},
574 {"guid_routing_order_file", 1, NULL, 'X'},
575 {"stay_on_fatal", 0, NULL, 'y'},
576 {"honor_guid2lid", 0, NULL, 'x'},
577 #ifdef ENABLE_OSM_CONSOLE_SOCKET
578 {"console-port", 1, NULL, 'C'},
580 {"daemon", 0, NULL, 'B'},
581 {"inactive", 0, NULL, 'I'},
582 #ifdef ENABLE_OSM_PERF_MGR
583 {"perfmgr", 0, NULL, 1},
584 {"perfmgr_sweep_time_s", 1, NULL, 2},
586 {"prefix_routes_file", 1, NULL, 3},
587 {"consolidate_ipv6_snm_req", 0, NULL, 4},
588 {NULL, 0, NULL, 0} /* Required at the end of the array */
591 /* Make sure that the opensm and complib were compiled using
592 same modes (debug/free) */
593 if (osm_is_debug() != cl_is_debug()) {
595 "ERROR: OpenSM and Complib were compiled using different modes\n");
596 fprintf(stderr, "ERROR: OpenSM debug:%d Complib debug:%d \n",
597 osm_is_debug(), cl_is_debug());
600 #if defined (_DEBUG_) && defined (OSM_VENDOR_INTF_OPENIB)
601 enable_stack_dump(1);
604 printf("-------------------------------------------------\n");
605 printf("%s\n", OSM_VERSION);
607 osm_subn_set_default_opt(&opt);
609 if (osm_subn_parse_conf_file(OSM_DEFAULT_CONFIG_FILE, &opt) < 0)
610 printf("\nosm_subn_parse_conf_file failed!\n");
612 printf("Command Line Arguments:\n");
614 next_option = getopt_long_only(argc, argv, short_option,
616 switch (next_option) {
617 case 12: /* --version - already printed above */
621 if (config_file_done)
623 printf("Reloading config from `%s`:\n", optarg);
624 if (osm_subn_parse_conf_file(optarg, &opt)) {
625 printf("cannot parse config file.\n");
628 printf("Rescaning command line:\n");
629 config_file_done = 1;
633 conf_template = optarg;
634 printf(" Creating config file template \'%s\'.\n",
641 run_once_flag = TRUE;
642 printf(" Run Once\n");
647 Reassign LIDs subnet option.
649 opt.reassign_lids = TRUE;
650 printf(" Reassign LIDs\n");
655 Specifies ignore guids file.
657 opt.port_prof_ignore_file = optarg;
658 printf(" Ignore Guids File = %s\n",
659 opt.port_prof_ignore_file);
664 Specifies port guid with which to bind.
666 opt.guid = cl_hton64(strtoull(optarg, NULL, 16));
668 /* If guid is 0 - need to display the
670 opt.guid = INVALID_GUID;
672 printf(" Guid <0x%" PRIx64 ">\n",
673 cl_hton64(opt.guid));
677 val = strtol(optarg, NULL, 0);
678 /* Check that the number is not too large */
679 if (((uint32_t) (val * 1000000)) / 1000000 != val)
681 "ERROR: sweep interval given is too large. Ignoring it.\n");
683 opt.sweep_interval = val;
684 printf(" sweep interval = %d\n",
690 opt.transaction_timeout = strtol(optarg, NULL, 0);
691 printf(" Transaction timeout = %d\n",
692 opt.transaction_timeout);
696 opt.max_wire_smps = strtol(optarg, NULL, 0);
697 if (opt.max_wire_smps <= 0)
698 opt.max_wire_smps = 0x7FFFFFFF;
699 printf(" Max wire smp's = %d\n", opt.max_wire_smps);
704 * OpenSM interactive console
706 if (strcmp(optarg, OSM_DISABLE_CONSOLE) == 0
707 || strcmp(optarg, OSM_LOCAL_CONSOLE) == 0
708 #ifdef ENABLE_OSM_CONSOLE_SOCKET
709 || strcmp(optarg, OSM_REMOTE_CONSOLE) == 0
710 || strcmp(optarg, OSM_LOOPBACK_CONSOLE) == 0
713 opt.console = optarg;
715 printf("-console %s option not understood\n",
719 #ifdef ENABLE_OSM_CONSOLE_SOCKET
721 opt.console_port = strtol(optarg, NULL, 0);
726 dbg_lvl = strtol(optarg, NULL, 0);
727 printf(" d level = 0x%x\n", dbg_lvl);
729 printf(" Debug mode: Ignore Other SMs\n");
730 opt.ignore_other_sm = TRUE;
731 } else if (dbg_lvl == 1) {
732 printf(" Debug mode: Forcing Single Thread\n");
733 opt.single_thread = TRUE;
734 } else if (dbg_lvl == 2) {
735 printf(" Debug mode: Force Log Flush\n");
736 opt.force_log_flush = TRUE;
737 } else if (dbg_lvl == 3) {
739 (" Debug mode: Disable multicast support\n");
740 opt.disable_multicast = TRUE;
743 * NOTE: Debug level 4 used to be used for memory
744 * tracking but this is now deprecated
746 else if (dbg_lvl == 5)
749 printf(" OpenSM: Unknown debug option %d"
750 " ignored\n", dbg_lvl);
754 temp = strtol(optarg, NULL, 0);
757 "ERROR: LMC must be 7 or less.\n");
760 opt.lmc = (uint8_t) temp;
761 printf(" LMC = %d\n", temp);
765 opt.log_flags = strtol(optarg, NULL, 0);
766 printf(" verbose option -D = 0x%x\n", opt.log_flags);
770 opt.log_file = optarg;
775 strtoul(optarg, NULL, 0) * (1024 * 1024);
776 printf(" Log file max size is %lu bytes\n",
781 opt.accum_log_file = FALSE;
782 printf(" Creating new log file\n");
786 opt.partition_config_file = optarg;
790 opt.no_partition_enforcement = TRUE;
798 opt.qos_policy_file = optarg;
799 printf(" QoS policy file \'%s\'\n", optarg);
803 opt.exit_on_fatal = FALSE;
804 printf(" Staying on fatal initialization errors\n");
808 opt.log_flags = (opt.log_flags << 1) | 1;
809 printf(" Verbose option -v (log flags = 0x%X)\n",
814 opt.log_flags = 0xFF;
815 opt.force_log_flush = TRUE;
816 printf(" Big V selected\n");
820 temp = strtol(optarg, NULL, 0);
821 if (0 > temp || 15 < temp) {
823 "ERROR: priority must be between 0 and 15\n");
826 opt.sm_priority = (uint8_t) temp;
827 printf(" Priority = %d\n", temp);
831 sm_key = cl_hton64(strtoull(optarg, NULL, 16));
832 printf(" SM Key <0x%" PRIx64 ">\n", cl_hton64(sm_key));
837 opt.routing_engine_names = optarg;
838 printf(" Activate \'%s\' routing engine(s)\n", optarg);
842 opt.connect_roots = TRUE;
843 printf(" Connect roots option is on\n");
847 opt.use_ucast_cache = TRUE;
848 printf(" Unicast routing cache option is on\n");
852 opt.lid_matrix_dump_file = optarg;
853 printf(" Lid matrix dump file is \'%s\'\n", optarg);
857 opt.lfts_file = optarg;
858 printf(" LFTs file is \'%s\'\n", optarg);
862 opt.sa_db_file = optarg;
863 printf(" SA DB file is \'%s\'\n", optarg);
868 Specifies root guids file
870 opt.root_guid_file = optarg;
871 printf(" Root Guid File: %s\n", opt.root_guid_file);
876 Specifies compute node guids file
878 opt.cn_guid_file = optarg;
879 printf(" Compute Node Guid File: %s\n",
884 /* Specifies ids guid file */
885 opt.ids_guid_file = optarg;
886 printf(" IDs Guid File: %s\n", opt.ids_guid_file);
890 /* Specifies guid routing order file */
891 opt.guid_routing_order_file = optarg;
892 printf(" GUID Routing Order File: %s\n", opt.guid_routing_order_file);
896 opt.honor_guid2lid_file = TRUE;
897 printf(" Honor guid2lid file, if possible\n");
902 printf(" Daemon mode\n");
906 opt.sm_inactive = TRUE;
907 printf(" SM started in inactive state\n");
910 #ifdef ENABLE_OSM_PERF_MGR
915 opt.perfmgr_sweep_time_s = atoi(optarg);
917 #endif /* ENABLE_OSM_PERF_MGR */
920 opt.prefix_routes_file = optarg;
923 opt.consolidate_ipv6_snm_req = TRUE;
932 break; /* done with option */
933 default: /* something wrong */
937 while (next_option != -1);
939 if (opt.log_file != NULL)
940 printf(" Log File: %s\n", opt.log_file);
941 /* Done with options description */
942 printf("-------------------------------------------------\n");
945 status = osm_subn_write_conf_file(conf_template, &opt);
947 printf("\nosm_subn_write_conf_file failed!\n");
951 osm_subn_verify_config(&opt);
954 osm_vendor_set_debug(osm.p_vendor, vendor_debug);
963 status = osm_opensm_init(&osm, &opt);
964 if (status != IB_SUCCESS) {
965 const char *err_str = ib_get_err_str(status);
967 err_str = "Unknown Error Type";
968 printf("\nError from osm_opensm_init: %s.\n", err_str);
969 /* We will just exit, and not go to Exit, since we don't
970 want the destroy to be called. */
976 If the user didn't specify a GUID on the command line,
977 then get a port GUID value with which to bind.
979 if (opt.guid == 0 || cl_hton64(opt.guid) == CL_HTON64(INVALID_GUID))
980 opt.guid = get_port_guid(&osm, opt.guid);
982 status = osm_opensm_bind(&osm, opt.guid);
983 if (status != IB_SUCCESS) {
984 printf("\nError from osm_opensm_bind (0x%X)\n", status);
986 ("Perhaps another instance of OpenSM is already running\n");
992 osm_opensm_sweep(&osm);
994 if (run_once_flag == TRUE) {
995 while (!osm_exit_flag) {
997 osm_opensm_wait_for_subnet_up(&osm,
1006 * Sit here until signaled to exit
1008 osm_manager_loop(&opt, &osm);
1011 if (osm.mad_pool.mads_out) {
1013 "There are still %u MADs out. Forcing the exit of the OpenSM application...\n",
1014 osm.mad_pool.mads_out);
1015 #ifdef HAVE_LIBPTHREAD
1016 pthread_cond_signal(&osm.stats.cond);
1018 cl_event_signal(&osm.stats.event);
1023 osm_opensm_destroy(&osm);