1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff/* 37219820Sjeff * Abstract: 38219820Sjeff * Command line interface for opensm. 39219820Sjeff */ 40219820Sjeff 41219820Sjeff#if HAVE_CONFIG_H 42219820Sjeff# include <config.h> 43219820Sjeff#endif /* HAVE_CONFIG_H */ 44219820Sjeff 45219820Sjeff#include <stdio.h> 46219820Sjeff#include <stdlib.h> 47219820Sjeff#include <getopt.h> 48219820Sjeff#include <unistd.h> 49219820Sjeff#include <signal.h> 50219820Sjeff#include <sys/types.h> 51219820Sjeff#include <sys/stat.h> 52219820Sjeff#include <fcntl.h> 53219820Sjeff#include <complib/cl_types.h> 54219820Sjeff#include <complib/cl_debug.h> 55219820Sjeff#include <vendor/osm_vendor_api.h> 56219820Sjeff#include <opensm/osm_version.h> 57219820Sjeff#include <opensm/osm_opensm.h> 58219820Sjeff#include <opensm/osm_console.h> 59219820Sjeff#include <opensm/osm_console_io.h> 60219820Sjeff#include <opensm/osm_perfmgr.h> 61219820Sjeff 62219820Sjeffvolatile unsigned int osm_exit_flag = 0; 63219820Sjeff 64219820Sjeffstatic volatile unsigned int osm_hup_flag = 0; 65219820Sjeffstatic volatile unsigned int osm_usr1_flag = 0; 66219820Sjeff 67219820Sjeff#define GUID_ARRAY_SIZE 64 68219820Sjeff#define INVALID_GUID (0xFFFFFFFFFFFFFFFFULL) 69219820Sjeff 70219820Sjeffstatic void mark_exit_flag(int signum) 71219820Sjeff{ 72219820Sjeff if (!osm_exit_flag) 73219820Sjeff printf("OpenSM: Got signal %d - exiting...\n", signum); 74219820Sjeff osm_exit_flag = 1; 75219820Sjeff} 76219820Sjeff 77219820Sjeffstatic void mark_hup_flag(int signum) 78219820Sjeff{ 79219820Sjeff osm_hup_flag = 1; 80219820Sjeff} 81219820Sjeff 82219820Sjeffstatic void mark_usr1_flag(int signum) 83219820Sjeff{ 84219820Sjeff osm_usr1_flag = 1; 85219820Sjeff} 86219820Sjeff 87219820Sjeffstatic sigset_t saved_sigset; 88219820Sjeff 89219820Sjeffstatic void block_signals() 90219820Sjeff{ 91219820Sjeff sigset_t set; 92219820Sjeff 93219820Sjeff sigemptyset(&set); 94219820Sjeff sigaddset(&set, SIGINT); 95219820Sjeff sigaddset(&set, SIGTERM); 96219820Sjeff sigaddset(&set, SIGHUP); 97219820Sjeff#ifndef HAVE_OLD_LINUX_THREADS 98219820Sjeff sigaddset(&set, SIGUSR1); 99219820Sjeff#endif 100219820Sjeff pthread_sigmask(SIG_SETMASK, &set, &saved_sigset); 101219820Sjeff} 102219820Sjeff 103219820Sjeffstatic void setup_signals() 104219820Sjeff{ 105219820Sjeff struct sigaction act; 106219820Sjeff 107219820Sjeff sigemptyset(&act.sa_mask); 108219820Sjeff act.sa_handler = mark_exit_flag; 109219820Sjeff act.sa_flags = 0; 110219820Sjeff sigaction(SIGINT, &act, NULL); 111219820Sjeff sigaction(SIGTERM, &act, NULL); 112219820Sjeff act.sa_handler = mark_hup_flag; 113219820Sjeff sigaction(SIGHUP, &act, NULL); 114219820Sjeff sigaction(SIGCONT, &act, NULL); 115219820Sjeff#ifndef HAVE_OLD_LINUX_THREADS 116219820Sjeff act.sa_handler = mark_usr1_flag; 117219820Sjeff sigaction(SIGUSR1, &act, NULL); 118219820Sjeff#endif 119219820Sjeff pthread_sigmask(SIG_SETMASK, &saved_sigset, NULL); 120219820Sjeff} 121219820Sjeff 122219820Sjeff/********************************************************************** 123219820Sjeff **********************************************************************/ 124219820Sjeff 125219820Sjeffstatic void show_usage(void) 126219820Sjeff{ 127219820Sjeff printf("\n------- OpenSM - Usage and options ----------------------\n"); 128219820Sjeff printf("Usage: opensm [options]\n"); 129219820Sjeff printf("Options:\n"); 130219820Sjeff printf("--version\n Prints OpenSM version and exits.\n\n"); 131219820Sjeff printf("--config, -F <file-name>\n" 132219820Sjeff " The name of the OpenSM config file. When not specified\n" 133219820Sjeff " " OSM_DEFAULT_CONFIG_FILE " will be used (if exists).\n\n"); 134219820Sjeff printf("--create-config, -c <file-name>\n" 135219820Sjeff " OpenSM will dump its configuration to the specified file and exit.\n" 136219820Sjeff " This is a way to generate OpenSM configuration file template.\n\n"); 137219820Sjeff printf("--guid, -g <GUID in hex>\n" 138219820Sjeff " This option specifies the local port GUID value\n" 139219820Sjeff " with which OpenSM should bind. OpenSM may be\n" 140219820Sjeff " bound to 1 port at a time.\n" 141219820Sjeff " If GUID given is 0, OpenSM displays a list\n" 142219820Sjeff " of possible port GUIDs and waits for user input.\n" 143219820Sjeff " Without -g, OpenSM tries to use the default port.\n\n"); 144219820Sjeff printf("--lmc, -l <LMC>\n" 145219820Sjeff " This option specifies the subnet's LMC value.\n" 146219820Sjeff " The number of LIDs assigned to each port is 2^LMC.\n" 147219820Sjeff " The LMC value must be in the range 0-7.\n" 148219820Sjeff " LMC values > 0 allow multiple paths between ports.\n" 149219820Sjeff " LMC values > 0 should only be used if the subnet\n" 150219820Sjeff " topology actually provides multiple paths between\n" 151219820Sjeff " ports, i.e. multiple interconnects between switches.\n" 152219820Sjeff " Without -l, OpenSM defaults to LMC = 0, which allows\n" 153219820Sjeff " one path between any two ports.\n\n"); 154219820Sjeff printf("--priority, -p <PRIORITY>\n" 155219820Sjeff " This option specifies the SM's PRIORITY.\n" 156219820Sjeff " This will effect the handover cases, where master\n" 157219820Sjeff " is chosen by priority and GUID. Range goes\n" 158219820Sjeff " from 0 (lowest priority) to 15 (highest).\n\n"); 159219820Sjeff printf("--smkey, -k <SM_Key>\n" 160219820Sjeff " This option specifies the SM's SM_Key (64 bits).\n" 161219820Sjeff " This will effect SM authentication.\n" 162219820Sjeff " Note that OpenSM version 3.2.1 and below used the\n" 163219820Sjeff " default value '1' in a host byte order, it is fixed\n" 164219820Sjeff " now but you may need this option to interoperate\n" 165219820Sjeff " with old OpenSM running on a little endian machine.\n\n"); 166219820Sjeff printf("--reassign_lids, -r\n" 167219820Sjeff " This option causes OpenSM to reassign LIDs to all\n" 168219820Sjeff " end nodes. Specifying -r on a running subnet\n" 169219820Sjeff " may disrupt subnet traffic.\n" 170219820Sjeff " Without -r, OpenSM attempts to preserve existing\n" 171219820Sjeff " LID assignments resolving multiple use of same LID.\n\n"); 172219820Sjeff printf("--routing_engine, -R <engine name>\n" 173219820Sjeff " This option chooses routing engine(s) to use instead of default\n" 174219820Sjeff " Min Hop algorithm. Multiple routing engines can be specified\n" 175219820Sjeff " separated by commas so that specific ordering of routing\n" 176219820Sjeff " algorithms will be tried if earlier routing engines fail.\n" 177219820Sjeff " Supported engines: updn, file, ftree, lash, dor\n\n"); 178219820Sjeff printf("--connect_roots, -z\n" 179219820Sjeff " This option enforces a routing engine (currently\n" 180219820Sjeff " up/down only) to make connectivity between root switches\n" 181219820Sjeff " and in this way be IBA compliant. In many cases,\n" 182219820Sjeff " this can violate \"pure\" deadlock free algorithm, so\n" 183219820Sjeff " use it carefully.\n\n"); 184219820Sjeff printf("--ucast_cache, -A\n" 185219820Sjeff " This option enables unicast routing cache to prevent\n" 186219820Sjeff " routing recalculation (which is a heavy task in a\n" 187219820Sjeff " large cluster) when there was no topology change\n" 188219820Sjeff " detected during the heavy sweep, or when the topology\n" 189219820Sjeff " change does not require new routing calculation,\n" 190219820Sjeff " e.g. in case of host reboot.\n" 191219820Sjeff " This option becomes very handy when the cluster size\n" 192219820Sjeff " is thousands of nodes.\n\n"); 193219820Sjeff printf("--lid_matrix_file, -M <file name>\n" 194219820Sjeff " This option specifies the name of the lid matrix dump file\n" 195219820Sjeff " from where switch lid matrices (min hops tables will be\n" 196219820Sjeff " loaded.\n\n"); 197219820Sjeff printf("--lfts_file, -U <file name>\n" 198219820Sjeff " This option specifies the name of the LFTs file\n" 199219820Sjeff " from where switch forwarding tables will be loaded.\n\n"); 200219820Sjeff printf("--sadb_file, -S <file name>\n" 201219820Sjeff " This option specifies the name of the SA DB dump file\n" 202219820Sjeff " from where SA database will be loaded.\n\n"); 203219820Sjeff printf("--root_guid_file, -a <path to file>\n" 204219820Sjeff " Set the root nodes for the Up/Down or Fat-Tree routing\n" 205219820Sjeff " algorithm to the guids provided in the given file (one\n" 206219820Sjeff " to a line)\n" "\n"); 207219820Sjeff printf("--cn_guid_file, -u <path to file>\n" 208219820Sjeff " Set the compute nodes for the Fat-Tree routing algorithm\n" 209219820Sjeff " to the guids provided in the given file (one to a line)\n\n"); 210219820Sjeff printf("--ids_guid_file, -m <path to file>\n" 211219820Sjeff " Name of the map file with set of the IDs which will be used\n" 212219820Sjeff " by Up/Down routing algorithm instead of node GUIDs\n" 213219820Sjeff " (format: <guid> <id> per line)\n\n"); 214219820Sjeff printf("--guid_routing_order_file, -X <path to file>\n" 215219820Sjeff " Set the order port guids will be routed for the MinHop\n" 216219820Sjeff " and Up/Down routing algorithms to the guids provided in the\n" 217219820Sjeff " given file (one to a line)\n\n"); 218219820Sjeff printf("--once, -o\n" 219219820Sjeff " This option causes OpenSM to configure the subnet\n" 220219820Sjeff " once, then exit. Ports remain in the ACTIVE state.\n\n"); 221219820Sjeff printf("--sweep, -s <interval>\n" 222219820Sjeff " This option specifies the number of seconds between\n" 223219820Sjeff " subnet sweeps. Specifying -s 0 disables sweeping.\n" 224219820Sjeff " Without -s, OpenSM defaults to a sweep interval of\n" 225219820Sjeff " 10 seconds.\n\n"); 226219820Sjeff printf("--timeout, -t <milliseconds>\n" 227219820Sjeff " This option specifies the time in milliseconds\n" 228219820Sjeff " used for transaction timeouts.\n" 229219820Sjeff " Specifying -t 0 disables timeouts.\n" 230219820Sjeff " Without -t, OpenSM defaults to a timeout value of\n" 231219820Sjeff " 200 milliseconds.\n\n"); 232219820Sjeff printf("--maxsmps, -n <number>\n" 233219820Sjeff " This option specifies the number of VL15 SMP MADs\n" 234219820Sjeff " allowed on the wire at any one time.\n" 235219820Sjeff " Specifying --maxsmps 0 allows unlimited outstanding\n" 236219820Sjeff " SMPs.\n" 237219820Sjeff " Without --maxsmps, OpenSM defaults to a maximum of\n" 238219820Sjeff " 4 outstanding SMPs.\n\n"); 239219820Sjeff printf("--console, -q [off|local" 240219820Sjeff#ifdef ENABLE_OSM_CONSOLE_SOCKET 241219820Sjeff "|socket|loopback" 242219820Sjeff#endif 243219820Sjeff "]\n This option activates the OpenSM console (default off).\n\n"); 244219820Sjeff#ifdef ENABLE_OSM_CONSOLE_SOCKET 245219820Sjeff printf("--console-port, -C <port>\n" 246219820Sjeff " Specify an alternate telnet port for the console (default %d).\n\n", 247219820Sjeff OSM_DEFAULT_CONSOLE_PORT); 248219820Sjeff#endif 249219820Sjeff printf("--ignore-guids, -i <equalize-ignore-guids-file>\n" 250219820Sjeff " This option provides the means to define a set of ports\n" 251219820Sjeff " (by guid) that will be ignored by the link load\n" 252219820Sjeff " equalization algorithm.\n\n"); 253219820Sjeff printf("--honor_guid2lid, -x\n" 254219820Sjeff " This option forces OpenSM to honor the guid2lid file,\n" 255219820Sjeff " when it comes out of Standby state, if such file exists\n" 256219820Sjeff " under OSM_CACHE_DIR, and is valid. By default, this is FALSE.\n\n"); 257219820Sjeff printf("--log_file, -f <log-file-name>\n" 258219820Sjeff " This option defines the log to be the given file.\n" 259219820Sjeff " By default, the log goes to /var/log/opensm.log.\n" 260219820Sjeff " For the log to go to standard output use -f stdout.\n\n"); 261219820Sjeff printf("--log_limit, -L <size in MB>\n" 262219820Sjeff " This option defines maximal log file size in MB. When\n" 263219820Sjeff " specified the log file will be truncated upon reaching\n" 264219820Sjeff " this limit.\n\n"); 265219820Sjeff printf("--erase_log_file, -e\n" 266219820Sjeff " This option will cause deletion of the log file\n" 267219820Sjeff " (if it previously exists). By default, the log file\n" 268219820Sjeff " is accumulative.\n\n"); 269219820Sjeff printf("--Pconfig, -P <partition-config-file>\n" 270219820Sjeff " This option defines the optional partition configuration file.\n" 271219820Sjeff " The default name is \'" 272219820Sjeff OSM_DEFAULT_PARTITION_CONFIG_FILE "\'.\n\n"); 273219820Sjeff printf("--no_part_enforce, -N\n" 274219820Sjeff " This option disables partition enforcement on switch external ports.\n\n"); 275219820Sjeff printf("--qos, -Q\n" " This option enables QoS setup.\n\n"); 276219820Sjeff printf("--qos_policy_file, -Y <QoS-policy-file>\n" 277219820Sjeff " This option defines the optional QoS policy file.\n" 278219820Sjeff " The default name is \'" OSM_DEFAULT_QOS_POLICY_FILE 279219820Sjeff "\'.\n\n"); 280219820Sjeff printf("--stay_on_fatal, -y\n" 281219820Sjeff " This option will cause SM not to exit on fatal initialization\n" 282219820Sjeff " issues: if SM discovers duplicated guids or 12x link with\n" 283219820Sjeff " lane reversal badly configured.\n" 284219820Sjeff " By default, the SM will exit on these errors.\n\n"); 285219820Sjeff printf("--daemon, -B\n" 286219820Sjeff " Run in daemon mode - OpenSM will run in the background.\n\n"); 287219820Sjeff printf("--inactive, -I\n" 288219820Sjeff " Start SM in inactive rather than normal init SM state.\n\n"); 289219820Sjeff#ifdef ENABLE_OSM_PERF_MGR 290219820Sjeff printf("--perfmgr\n" " Start with PerfMgr enabled.\n\n"); 291219820Sjeff printf("--perfmgr_sweep_time_s <sec.>\n" 292219820Sjeff " PerfMgr sweep interval in seconds.\n\n"); 293219820Sjeff#endif 294219820Sjeff printf("--prefix_routes_file <path to file>\n" 295219820Sjeff " This option specifies the prefix routes file.\n" 296219820Sjeff " Prefix routes control how the SA responds to path record\n" 297219820Sjeff " queries for off-subnet DGIDs. Default file is:\n" 298219820Sjeff " " OSM_DEFAULT_PREFIX_ROUTES_FILE "\n\n"); 299219820Sjeff printf("--consolidate_ipv6_snm_req\n" 300219820Sjeff " Consolidate IPv6 Solicited Node Multicast group joins\n" 301219820Sjeff " into 1 IB multicast group.\n\n"); 302219820Sjeff printf("--verbose, -v\n" 303219820Sjeff " This option increases the log verbosity level.\n" 304219820Sjeff " The -v option may be specified multiple times\n" 305219820Sjeff " to further increase the verbosity level.\n" 306219820Sjeff " See the -D option for more information about\n" 307219820Sjeff " log verbosity.\n\n"); 308219820Sjeff printf("--V, -V\n" 309219820Sjeff " This option sets the maximum verbosity level and\n" 310219820Sjeff " forces log flushing.\n" 311219820Sjeff " The -V is equivalent to '-D 0xFF -d 2'.\n" 312219820Sjeff " See the -D option for more information about\n" 313219820Sjeff " log verbosity.\n\n"); 314219820Sjeff printf("--D, -D <flags>\n" 315219820Sjeff " This option sets the log verbosity level.\n" 316219820Sjeff " A flags field must follow the -D option.\n" 317219820Sjeff " A bit set/clear in the flags enables/disables a\n" 318219820Sjeff " specific log level as follows:\n" 319219820Sjeff " BIT LOG LEVEL ENABLED\n" 320219820Sjeff " ---- -----------------\n" 321219820Sjeff " 0x01 - ERROR (error messages)\n" 322219820Sjeff " 0x02 - INFO (basic messages, low volume)\n" 323219820Sjeff " 0x04 - VERBOSE (interesting stuff, moderate volume)\n" 324219820Sjeff " 0x08 - DEBUG (diagnostic, high volume)\n" 325219820Sjeff " 0x10 - FUNCS (function entry/exit, very high volume)\n" 326219820Sjeff " 0x20 - FRAMES (dumps all SMP and GMP frames)\n" 327219820Sjeff " 0x40 - ROUTING (dump FDB routing information)\n" 328219820Sjeff " 0x80 - currently unused.\n" 329219820Sjeff " Without -D, OpenSM defaults to ERROR + INFO (0x3).\n" 330219820Sjeff " Specifying -D 0 disables all messages.\n" 331219820Sjeff " Specifying -D 0xFF enables all messages (see -V).\n" 332219820Sjeff " High verbosity levels may require increasing\n" 333219820Sjeff " the transaction timeout with the -t option.\n\n"); 334219820Sjeff printf("--debug, -d <number>\n" 335219820Sjeff " This option specifies a debug option.\n" 336219820Sjeff " These options are not normally needed.\n" 337219820Sjeff " The number following -d selects the debug\n" 338219820Sjeff " option to enable as follows:\n" 339219820Sjeff " OPT Description\n" 340219820Sjeff " --- -----------------\n" 341219820Sjeff " -d0 - Ignore other SM nodes\n" 342219820Sjeff " -d1 - Force single threaded dispatching\n" 343219820Sjeff " -d2 - Force log flushing after each log message\n" 344219820Sjeff " -d3 - Disable multicast support\n" 345219820Sjeff " -d10 - Put OpenSM in testability mode\n" 346219820Sjeff " Without -d, no debug options are enabled\n\n"); 347219820Sjeff printf("--help, -h, -?\n" 348219820Sjeff " Display this usage info then exit.\n\n"); 349219820Sjeff fflush(stdout); 350219820Sjeff exit(2); 351219820Sjeff} 352219820Sjeff 353219820Sjeff/********************************************************************** 354219820Sjeff **********************************************************************/ 355219820Sjeffstatic ib_net64_t get_port_guid(IN osm_opensm_t * p_osm, uint64_t port_guid) 356219820Sjeff{ 357219820Sjeff ib_port_attr_t attr_array[GUID_ARRAY_SIZE]; 358219820Sjeff uint32_t num_ports = GUID_ARRAY_SIZE; 359219820Sjeff char junk[128]; 360219820Sjeff uint32_t i, choice = 0; 361219820Sjeff boolean_t done_flag = FALSE; 362219820Sjeff ib_api_status_t status; 363219820Sjeff 364219820Sjeff /* 365219820Sjeff Call the transport layer for a list of local port 366219820Sjeff GUID values. 367219820Sjeff */ 368219820Sjeff status = 369219820Sjeff osm_vendor_get_all_port_attr(p_osm->p_vendor, attr_array, 370219820Sjeff &num_ports); 371219820Sjeff if (status != IB_SUCCESS) { 372219820Sjeff printf("\nError from osm_vendor_get_all_port_attr (%x)\n", 373219820Sjeff status); 374219820Sjeff return (0); 375219820Sjeff } 376219820Sjeff 377219820Sjeff /* if num_ports is 0 - return 0 */ 378219820Sjeff if (num_ports == 0) { 379219820Sjeff printf("\nNo local ports detected!\n"); 380219820Sjeff return (0); 381219820Sjeff } 382219820Sjeff /* If num_ports is 1, then there is only one possible port to use. 383219820Sjeff * Use it. */ 384219820Sjeff if (num_ports == 1) { 385219820Sjeff printf("Using default GUID 0x%" PRIx64 "\n", 386219820Sjeff cl_hton64(attr_array[0].port_guid)); 387219820Sjeff return (attr_array[0].port_guid); 388219820Sjeff } 389219820Sjeff /* If port_guid is 0 - use the first connected port */ 390219820Sjeff if (port_guid == 0) { 391219820Sjeff for (i = 0; i < num_ports; i++) 392219820Sjeff if (attr_array[i].link_state > IB_LINK_DOWN) 393219820Sjeff break; 394219820Sjeff if (i == num_ports) 395219820Sjeff i = 0; 396219820Sjeff printf("Using default GUID 0x%" PRIx64 "\n", 397219820Sjeff cl_hton64(attr_array[i].port_guid)); 398219820Sjeff return (attr_array[i].port_guid); 399219820Sjeff } 400219820Sjeff 401219820Sjeff if (p_osm->subn.opt.daemon) 402219820Sjeff return 0; 403219820Sjeff 404219820Sjeff /* More than one possible port - list all ports and let the user 405219820Sjeff * to choose. */ 406219820Sjeff while (done_flag == FALSE) { 407219820Sjeff printf("\nChoose a local port number with which to bind:\n\n"); 408219820Sjeff for (i = 0; i < num_ports; i++) 409219820Sjeff /* Print the index + 1 since by convention, port 410219820Sjeff * numbers start with 1 on host channel adapters. */ 411219820Sjeff printf("\t%u: GUID 0x%" PRIx64 412219820Sjeff ", lid %u, state %s\n", i + 1, 413219820Sjeff cl_ntoh64(attr_array[i].port_guid), 414219820Sjeff attr_array[i].lid, 415219820Sjeff ib_get_port_state_str(attr_array[i].link_state)); 416219820Sjeff printf("\nEnter choice (1-%u): ", i); 417219820Sjeff fflush(stdout); 418219820Sjeff if (scanf("%u", &choice)) { 419219820Sjeff if (choice > num_ports || choice < 1) { 420219820Sjeff printf("\nError: Lame choice!\n"); 421219820Sjeff fflush(stdin); 422219820Sjeff } else { 423219820Sjeff choice--; 424219820Sjeff done_flag = TRUE; 425219820Sjeff } 426219820Sjeff } else { 427219820Sjeff /* get rid of the junk in the selection line */ 428219820Sjeff scanf("%s", junk); 429219820Sjeff printf("\nError: Lame choice!\n"); 430219820Sjeff fflush(stdin); 431219820Sjeff } 432219820Sjeff } 433219820Sjeff printf("Choice guid=0x%" PRIx64 "\n", 434219820Sjeff cl_ntoh64(attr_array[choice].port_guid)); 435219820Sjeff return (attr_array[choice].port_guid); 436219820Sjeff} 437219820Sjeff 438219820Sjeff/********************************************************************** 439219820Sjeff **********************************************************************/ 440219820Sjeff 441219820Sjeffstatic int daemonize(osm_opensm_t * osm) 442219820Sjeff{ 443219820Sjeff pid_t pid; 444219820Sjeff int fd; 445219820Sjeff 446219820Sjeff fd = open("/dev/null", O_WRONLY); 447219820Sjeff if (fd < 0) { 448219820Sjeff perror("open"); 449219820Sjeff return -1; 450219820Sjeff } 451219820Sjeff 452219820Sjeff if ((pid = fork()) < 0) { 453219820Sjeff perror("fork"); 454219820Sjeff exit(-1); 455219820Sjeff } else if (pid > 0) 456219820Sjeff exit(0); 457219820Sjeff 458219820Sjeff setsid(); 459219820Sjeff 460219820Sjeff if ((pid = fork()) < 0) { 461219820Sjeff perror("fork"); 462219820Sjeff exit(-1); 463219820Sjeff } else if (pid > 0) 464219820Sjeff exit(0); 465219820Sjeff 466219820Sjeff close(0); 467219820Sjeff close(1); 468219820Sjeff close(2); 469219820Sjeff 470219820Sjeff dup2(fd, 0); 471219820Sjeff dup2(fd, 1); 472219820Sjeff dup2(fd, 2); 473219820Sjeff 474219820Sjeff return 0; 475219820Sjeff} 476219820Sjeff 477219820Sjeff/********************************************************************** 478219820Sjeff **********************************************************************/ 479219820Sjeffint osm_manager_loop(osm_subn_opt_t * p_opt, osm_opensm_t * p_osm) 480219820Sjeff{ 481219820Sjeff int console_init_flag = 0; 482219820Sjeff 483219820Sjeff if (is_console_enabled(p_opt)) { 484219820Sjeff if (!osm_console_init(p_opt, &p_osm->console, &p_osm->log)) 485219820Sjeff console_init_flag = 1; 486219820Sjeff } 487219820Sjeff 488219820Sjeff /* 489219820Sjeff Sit here forever - dwell or do console i/o & cmds 490219820Sjeff */ 491219820Sjeff while (!osm_exit_flag) { 492219820Sjeff if (console_init_flag) 493219820Sjeff osm_console(p_osm); 494219820Sjeff else 495219820Sjeff cl_thread_suspend(10000); 496219820Sjeff 497219820Sjeff if (osm_usr1_flag) { 498219820Sjeff osm_usr1_flag = 0; 499219820Sjeff osm_log_reopen_file(&(p_osm->log)); 500219820Sjeff } 501219820Sjeff if (osm_hup_flag) { 502219820Sjeff osm_hup_flag = 0; 503219820Sjeff /* a HUP signal should only start a new heavy sweep */ 504219820Sjeff p_osm->subn.force_heavy_sweep = TRUE; 505219820Sjeff osm_opensm_sweep(p_osm); 506219820Sjeff } 507219820Sjeff } 508219820Sjeff if (is_console_enabled(p_opt)) 509219820Sjeff osm_console_exit(&p_osm->console, &p_osm->log); 510219820Sjeff return 0; 511219820Sjeff} 512219820Sjeff 513219820Sjeff/********************************************************************** 514219820Sjeff **********************************************************************/ 515219820Sjeffint main(int argc, char *argv[]) 516219820Sjeff{ 517219820Sjeff osm_opensm_t osm; 518219820Sjeff osm_subn_opt_t opt; 519219820Sjeff ib_net64_t sm_key = 0; 520219820Sjeff ib_api_status_t status; 521219820Sjeff uint32_t temp, dbg_lvl; 522219820Sjeff boolean_t run_once_flag = FALSE; 523219820Sjeff int32_t vendor_debug = 0; 524219820Sjeff uint32_t next_option; 525219820Sjeff char *conf_template = NULL; 526219820Sjeff uint32_t val; 527219820Sjeff unsigned config_file_done = 0; 528219820Sjeff const char *const short_option = 529219820Sjeff "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:"; 530219820Sjeff 531219820Sjeff /* 532219820Sjeff In the array below, the 2nd parameter specifies the number 533219820Sjeff of arguments as follows: 534219820Sjeff 0: no arguments 535219820Sjeff 1: argument 536219820Sjeff 2: optional 537219820Sjeff */ 538219820Sjeff const struct option long_option[] = { 539219820Sjeff {"version", 0, NULL, 12}, 540219820Sjeff {"config", 1, NULL, 'F'}, 541219820Sjeff {"create-config", 1, NULL, 'c'}, 542219820Sjeff {"debug", 1, NULL, 'd'}, 543219820Sjeff {"guid", 1, NULL, 'g'}, 544219820Sjeff {"ignore_guids", 1, NULL, 'i'}, 545219820Sjeff {"lmc", 1, NULL, 'l'}, 546219820Sjeff {"sweep", 1, NULL, 's'}, 547219820Sjeff {"timeout", 1, NULL, 't'}, 548219820Sjeff {"verbose", 0, NULL, 'v'}, 549219820Sjeff {"D", 1, NULL, 'D'}, 550219820Sjeff {"log_file", 1, NULL, 'f'}, 551219820Sjeff {"log_limit", 1, NULL, 'L'}, 552219820Sjeff {"erase_log_file", 0, NULL, 'e'}, 553219820Sjeff {"Pconfig", 1, NULL, 'P'}, 554219820Sjeff {"no_part_enforce", 0, NULL, 'N'}, 555219820Sjeff {"qos", 0, NULL, 'Q'}, 556219820Sjeff {"qos_policy_file", 1, NULL, 'Y'}, 557219820Sjeff {"maxsmps", 1, NULL, 'n'}, 558219820Sjeff {"console", 1, NULL, 'q'}, 559219820Sjeff {"V", 0, NULL, 'V'}, 560219820Sjeff {"help", 0, NULL, 'h'}, 561219820Sjeff {"once", 0, NULL, 'o'}, 562219820Sjeff {"reassign_lids", 0, NULL, 'r'}, 563219820Sjeff {"priority", 1, NULL, 'p'}, 564219820Sjeff {"smkey", 1, NULL, 'k'}, 565219820Sjeff {"routing_engine", 1, NULL, 'R'}, 566219820Sjeff {"ucast_cache", 0, NULL, 'A'}, 567219820Sjeff {"connect_roots", 0, NULL, 'z'}, 568219820Sjeff {"lid_matrix_file", 1, NULL, 'M'}, 569219820Sjeff {"lfts_file", 1, NULL, 'U'}, 570219820Sjeff {"sadb_file", 1, NULL, 'S'}, 571219820Sjeff {"root_guid_file", 1, NULL, 'a'}, 572219820Sjeff {"cn_guid_file", 1, NULL, 'u'}, 573219820Sjeff {"ids_guid_file", 1, NULL, 'm'}, 574219820Sjeff {"guid_routing_order_file", 1, NULL, 'X'}, 575219820Sjeff {"stay_on_fatal", 0, NULL, 'y'}, 576219820Sjeff {"honor_guid2lid", 0, NULL, 'x'}, 577219820Sjeff#ifdef ENABLE_OSM_CONSOLE_SOCKET 578219820Sjeff {"console-port", 1, NULL, 'C'}, 579219820Sjeff#endif 580219820Sjeff {"daemon", 0, NULL, 'B'}, 581219820Sjeff {"inactive", 0, NULL, 'I'}, 582219820Sjeff#ifdef ENABLE_OSM_PERF_MGR 583219820Sjeff {"perfmgr", 0, NULL, 1}, 584219820Sjeff {"perfmgr_sweep_time_s", 1, NULL, 2}, 585219820Sjeff#endif 586219820Sjeff {"prefix_routes_file", 1, NULL, 3}, 587219820Sjeff {"consolidate_ipv6_snm_req", 0, NULL, 4}, 588219820Sjeff {NULL, 0, NULL, 0} /* Required at the end of the array */ 589219820Sjeff }; 590219820Sjeff 591219820Sjeff /* Make sure that the opensm and complib were compiled using 592219820Sjeff same modes (debug/free) */ 593219820Sjeff if (osm_is_debug() != cl_is_debug()) { 594219820Sjeff fprintf(stderr, 595219820Sjeff "ERROR: OpenSM and Complib were compiled using different modes\n"); 596219820Sjeff fprintf(stderr, "ERROR: OpenSM debug:%d Complib debug:%d \n", 597219820Sjeff osm_is_debug(), cl_is_debug()); 598219820Sjeff exit(1); 599219820Sjeff } 600219820Sjeff#if defined (_DEBUG_) && defined (OSM_VENDOR_INTF_OPENIB) 601219820Sjeff enable_stack_dump(1); 602219820Sjeff#endif 603219820Sjeff 604219820Sjeff printf("-------------------------------------------------\n"); 605219820Sjeff printf("%s\n", OSM_VERSION); 606219820Sjeff 607219820Sjeff osm_subn_set_default_opt(&opt); 608219820Sjeff 609219820Sjeff if (osm_subn_parse_conf_file(OSM_DEFAULT_CONFIG_FILE, &opt) < 0) 610219820Sjeff printf("\nosm_subn_parse_conf_file failed!\n"); 611219820Sjeff 612219820Sjeff printf("Command Line Arguments:\n"); 613219820Sjeff do { 614219820Sjeff next_option = getopt_long_only(argc, argv, short_option, 615219820Sjeff long_option, NULL); 616219820Sjeff switch (next_option) { 617219820Sjeff case 12: /* --version - already printed above */ 618219820Sjeff exit(0); 619219820Sjeff break; 620219820Sjeff case 'F': 621219820Sjeff if (config_file_done) 622219820Sjeff break; 623219820Sjeff printf("Reloading config from `%s`:\n", optarg); 624219820Sjeff if (osm_subn_parse_conf_file(optarg, &opt)) { 625219820Sjeff printf("cannot parse config file.\n"); 626219820Sjeff exit(1); 627219820Sjeff } 628219820Sjeff printf("Rescaning command line:\n"); 629219820Sjeff config_file_done = 1; 630219820Sjeff optind = 0; 631219820Sjeff break; 632219820Sjeff case 'c': 633219820Sjeff conf_template = optarg; 634219820Sjeff printf(" Creating config file template \'%s\'.\n", 635219820Sjeff conf_template); 636219820Sjeff break; 637219820Sjeff case 'o': 638219820Sjeff /* 639219820Sjeff Run once option. 640219820Sjeff */ 641219820Sjeff run_once_flag = TRUE; 642219820Sjeff printf(" Run Once\n"); 643219820Sjeff break; 644219820Sjeff 645219820Sjeff case 'r': 646219820Sjeff /* 647219820Sjeff Reassign LIDs subnet option. 648219820Sjeff */ 649219820Sjeff opt.reassign_lids = TRUE; 650219820Sjeff printf(" Reassign LIDs\n"); 651219820Sjeff break; 652219820Sjeff 653219820Sjeff case 'i': 654219820Sjeff /* 655219820Sjeff Specifies ignore guids file. 656219820Sjeff */ 657219820Sjeff opt.port_prof_ignore_file = optarg; 658219820Sjeff printf(" Ignore Guids File = %s\n", 659219820Sjeff opt.port_prof_ignore_file); 660219820Sjeff break; 661219820Sjeff 662219820Sjeff case 'g': 663219820Sjeff /* 664219820Sjeff Specifies port guid with which to bind. 665219820Sjeff */ 666219820Sjeff opt.guid = cl_hton64(strtoull(optarg, NULL, 16)); 667219820Sjeff if (!opt.guid) 668219820Sjeff /* If guid is 0 - need to display the 669219820Sjeff * guid list */ 670219820Sjeff opt.guid = INVALID_GUID; 671219820Sjeff else 672219820Sjeff printf(" Guid <0x%" PRIx64 ">\n", 673219820Sjeff cl_hton64(opt.guid)); 674219820Sjeff break; 675219820Sjeff 676219820Sjeff case 's': 677219820Sjeff val = strtol(optarg, NULL, 0); 678219820Sjeff /* Check that the number is not too large */ 679219820Sjeff if (((uint32_t) (val * 1000000)) / 1000000 != val) 680219820Sjeff fprintf(stderr, 681219820Sjeff "ERROR: sweep interval given is too large. Ignoring it.\n"); 682219820Sjeff else { 683219820Sjeff opt.sweep_interval = val; 684219820Sjeff printf(" sweep interval = %d\n", 685219820Sjeff opt.sweep_interval); 686219820Sjeff } 687219820Sjeff break; 688219820Sjeff 689219820Sjeff case 't': 690219820Sjeff opt.transaction_timeout = strtol(optarg, NULL, 0); 691219820Sjeff printf(" Transaction timeout = %d\n", 692219820Sjeff opt.transaction_timeout); 693219820Sjeff break; 694219820Sjeff 695219820Sjeff case 'n': 696219820Sjeff opt.max_wire_smps = strtol(optarg, NULL, 0); 697219820Sjeff if (opt.max_wire_smps <= 0) 698219820Sjeff opt.max_wire_smps = 0x7FFFFFFF; 699219820Sjeff printf(" Max wire smp's = %d\n", opt.max_wire_smps); 700219820Sjeff break; 701219820Sjeff 702219820Sjeff case 'q': 703219820Sjeff /* 704219820Sjeff * OpenSM interactive console 705219820Sjeff */ 706219820Sjeff if (strcmp(optarg, OSM_DISABLE_CONSOLE) == 0 707219820Sjeff || strcmp(optarg, OSM_LOCAL_CONSOLE) == 0 708219820Sjeff#ifdef ENABLE_OSM_CONSOLE_SOCKET 709219820Sjeff || strcmp(optarg, OSM_REMOTE_CONSOLE) == 0 710219820Sjeff || strcmp(optarg, OSM_LOOPBACK_CONSOLE) == 0 711219820Sjeff#endif 712219820Sjeff ) 713219820Sjeff opt.console = optarg; 714219820Sjeff else 715219820Sjeff printf("-console %s option not understood\n", 716219820Sjeff optarg); 717219820Sjeff break; 718219820Sjeff 719219820Sjeff#ifdef ENABLE_OSM_CONSOLE_SOCKET 720219820Sjeff case 'C': 721219820Sjeff opt.console_port = strtol(optarg, NULL, 0); 722219820Sjeff break; 723219820Sjeff#endif 724219820Sjeff 725219820Sjeff case 'd': 726219820Sjeff dbg_lvl = strtol(optarg, NULL, 0); 727219820Sjeff printf(" d level = 0x%x\n", dbg_lvl); 728219820Sjeff if (dbg_lvl == 0) { 729219820Sjeff printf(" Debug mode: Ignore Other SMs\n"); 730219820Sjeff opt.ignore_other_sm = TRUE; 731219820Sjeff } else if (dbg_lvl == 1) { 732219820Sjeff printf(" Debug mode: Forcing Single Thread\n"); 733219820Sjeff opt.single_thread = TRUE; 734219820Sjeff } else if (dbg_lvl == 2) { 735219820Sjeff printf(" Debug mode: Force Log Flush\n"); 736219820Sjeff opt.force_log_flush = TRUE; 737219820Sjeff } else if (dbg_lvl == 3) { 738219820Sjeff printf 739219820Sjeff (" Debug mode: Disable multicast support\n"); 740219820Sjeff opt.disable_multicast = TRUE; 741219820Sjeff } 742219820Sjeff /* 743219820Sjeff * NOTE: Debug level 4 used to be used for memory 744219820Sjeff * tracking but this is now deprecated 745219820Sjeff */ 746219820Sjeff else if (dbg_lvl == 5) 747219820Sjeff vendor_debug++; 748219820Sjeff else 749219820Sjeff printf(" OpenSM: Unknown debug option %d" 750219820Sjeff " ignored\n", dbg_lvl); 751219820Sjeff break; 752219820Sjeff 753219820Sjeff case 'l': 754219820Sjeff temp = strtol(optarg, NULL, 0); 755219820Sjeff if (temp > 7) { 756219820Sjeff fprintf(stderr, 757219820Sjeff "ERROR: LMC must be 7 or less.\n"); 758219820Sjeff return (-1); 759219820Sjeff } 760219820Sjeff opt.lmc = (uint8_t) temp; 761219820Sjeff printf(" LMC = %d\n", temp); 762219820Sjeff break; 763219820Sjeff 764219820Sjeff case 'D': 765219820Sjeff opt.log_flags = strtol(optarg, NULL, 0); 766219820Sjeff printf(" verbose option -D = 0x%x\n", opt.log_flags); 767219820Sjeff break; 768219820Sjeff 769219820Sjeff case 'f': 770219820Sjeff opt.log_file = optarg; 771219820Sjeff break; 772219820Sjeff 773219820Sjeff case 'L': 774219820Sjeff opt.log_max_size = 775219820Sjeff strtoul(optarg, NULL, 0) * (1024 * 1024); 776219820Sjeff printf(" Log file max size is %lu bytes\n", 777219820Sjeff opt.log_max_size); 778219820Sjeff break; 779219820Sjeff 780219820Sjeff case 'e': 781219820Sjeff opt.accum_log_file = FALSE; 782219820Sjeff printf(" Creating new log file\n"); 783219820Sjeff break; 784219820Sjeff 785219820Sjeff case 'P': 786219820Sjeff opt.partition_config_file = optarg; 787219820Sjeff break; 788219820Sjeff 789219820Sjeff case 'N': 790219820Sjeff opt.no_partition_enforcement = TRUE; 791219820Sjeff break; 792219820Sjeff 793219820Sjeff case 'Q': 794219820Sjeff opt.qos = TRUE; 795219820Sjeff break; 796219820Sjeff 797219820Sjeff case 'Y': 798219820Sjeff opt.qos_policy_file = optarg; 799219820Sjeff printf(" QoS policy file \'%s\'\n", optarg); 800219820Sjeff break; 801219820Sjeff 802219820Sjeff case 'y': 803219820Sjeff opt.exit_on_fatal = FALSE; 804219820Sjeff printf(" Staying on fatal initialization errors\n"); 805219820Sjeff break; 806219820Sjeff 807219820Sjeff case 'v': 808219820Sjeff opt.log_flags = (opt.log_flags << 1) | 1; 809219820Sjeff printf(" Verbose option -v (log flags = 0x%X)\n", 810219820Sjeff opt.log_flags); 811219820Sjeff break; 812219820Sjeff 813219820Sjeff case 'V': 814219820Sjeff opt.log_flags = 0xFF; 815219820Sjeff opt.force_log_flush = TRUE; 816219820Sjeff printf(" Big V selected\n"); 817219820Sjeff break; 818219820Sjeff 819219820Sjeff case 'p': 820219820Sjeff temp = strtol(optarg, NULL, 0); 821219820Sjeff if (0 > temp || 15 < temp) { 822219820Sjeff fprintf(stderr, 823219820Sjeff "ERROR: priority must be between 0 and 15\n"); 824219820Sjeff return (-1); 825219820Sjeff } 826219820Sjeff opt.sm_priority = (uint8_t) temp; 827219820Sjeff printf(" Priority = %d\n", temp); 828219820Sjeff break; 829219820Sjeff 830219820Sjeff case 'k': 831219820Sjeff sm_key = cl_hton64(strtoull(optarg, NULL, 16)); 832219820Sjeff printf(" SM Key <0x%" PRIx64 ">\n", cl_hton64(sm_key)); 833219820Sjeff opt.sm_key = sm_key; 834219820Sjeff break; 835219820Sjeff 836219820Sjeff case 'R': 837219820Sjeff opt.routing_engine_names = optarg; 838219820Sjeff printf(" Activate \'%s\' routing engine(s)\n", optarg); 839219820Sjeff break; 840219820Sjeff 841219820Sjeff case 'z': 842219820Sjeff opt.connect_roots = TRUE; 843219820Sjeff printf(" Connect roots option is on\n"); 844219820Sjeff break; 845219820Sjeff 846219820Sjeff case 'A': 847219820Sjeff opt.use_ucast_cache = TRUE; 848219820Sjeff printf(" Unicast routing cache option is on\n"); 849219820Sjeff break; 850219820Sjeff 851219820Sjeff case 'M': 852219820Sjeff opt.lid_matrix_dump_file = optarg; 853219820Sjeff printf(" Lid matrix dump file is \'%s\'\n", optarg); 854219820Sjeff break; 855219820Sjeff 856219820Sjeff case 'U': 857219820Sjeff opt.lfts_file = optarg; 858219820Sjeff printf(" LFTs file is \'%s\'\n", optarg); 859219820Sjeff break; 860219820Sjeff 861219820Sjeff case 'S': 862219820Sjeff opt.sa_db_file = optarg; 863219820Sjeff printf(" SA DB file is \'%s\'\n", optarg); 864219820Sjeff break; 865219820Sjeff 866219820Sjeff case 'a': 867219820Sjeff /* 868219820Sjeff Specifies root guids file 869219820Sjeff */ 870219820Sjeff opt.root_guid_file = optarg; 871219820Sjeff printf(" Root Guid File: %s\n", opt.root_guid_file); 872219820Sjeff break; 873219820Sjeff 874219820Sjeff case 'u': 875219820Sjeff /* 876219820Sjeff Specifies compute node guids file 877219820Sjeff */ 878219820Sjeff opt.cn_guid_file = optarg; 879219820Sjeff printf(" Compute Node Guid File: %s\n", 880219820Sjeff opt.cn_guid_file); 881219820Sjeff break; 882219820Sjeff 883219820Sjeff case 'm': 884219820Sjeff /* Specifies ids guid file */ 885219820Sjeff opt.ids_guid_file = optarg; 886219820Sjeff printf(" IDs Guid File: %s\n", opt.ids_guid_file); 887219820Sjeff break; 888219820Sjeff 889219820Sjeff case 'X': 890219820Sjeff /* Specifies guid routing order file */ 891219820Sjeff opt.guid_routing_order_file = optarg; 892219820Sjeff printf(" GUID Routing Order File: %s\n", opt.guid_routing_order_file); 893219820Sjeff break; 894219820Sjeff 895219820Sjeff case 'x': 896219820Sjeff opt.honor_guid2lid_file = TRUE; 897219820Sjeff printf(" Honor guid2lid file, if possible\n"); 898219820Sjeff break; 899219820Sjeff 900219820Sjeff case 'B': 901219820Sjeff opt.daemon = TRUE; 902219820Sjeff printf(" Daemon mode\n"); 903219820Sjeff break; 904219820Sjeff 905219820Sjeff case 'I': 906219820Sjeff opt.sm_inactive = TRUE; 907219820Sjeff printf(" SM started in inactive state\n"); 908219820Sjeff break; 909219820Sjeff 910219820Sjeff#ifdef ENABLE_OSM_PERF_MGR 911219820Sjeff case 1: 912219820Sjeff opt.perfmgr = TRUE; 913219820Sjeff break; 914219820Sjeff case 2: 915219820Sjeff opt.perfmgr_sweep_time_s = atoi(optarg); 916219820Sjeff break; 917219820Sjeff#endif /* ENABLE_OSM_PERF_MGR */ 918219820Sjeff 919219820Sjeff case 3: 920219820Sjeff opt.prefix_routes_file = optarg; 921219820Sjeff break; 922219820Sjeff case 4: 923219820Sjeff opt.consolidate_ipv6_snm_req = TRUE; 924219820Sjeff break; 925219820Sjeff case 'h': 926219820Sjeff case '?': 927219820Sjeff case ':': 928219820Sjeff show_usage(); 929219820Sjeff break; 930219820Sjeff 931219820Sjeff case -1: 932219820Sjeff break; /* done with option */ 933219820Sjeff default: /* something wrong */ 934219820Sjeff abort(); 935219820Sjeff } 936219820Sjeff } 937219820Sjeff while (next_option != -1); 938219820Sjeff 939219820Sjeff if (opt.log_file != NULL) 940219820Sjeff printf(" Log File: %s\n", opt.log_file); 941219820Sjeff /* Done with options description */ 942219820Sjeff printf("-------------------------------------------------\n"); 943219820Sjeff 944219820Sjeff if (conf_template) { 945219820Sjeff status = osm_subn_write_conf_file(conf_template, &opt); 946219820Sjeff if (status) 947219820Sjeff printf("\nosm_subn_write_conf_file failed!\n"); 948219820Sjeff exit(status); 949219820Sjeff } 950219820Sjeff 951219820Sjeff osm_subn_verify_config(&opt); 952219820Sjeff 953219820Sjeff if (vendor_debug) 954219820Sjeff osm_vendor_set_debug(osm.p_vendor, vendor_debug); 955219820Sjeff 956219820Sjeff block_signals(); 957219820Sjeff 958219820Sjeff if (opt.daemon) 959219820Sjeff daemonize(&osm); 960219820Sjeff 961219820Sjeff complib_init(); 962219820Sjeff 963219820Sjeff status = osm_opensm_init(&osm, &opt); 964219820Sjeff if (status != IB_SUCCESS) { 965219820Sjeff const char *err_str = ib_get_err_str(status); 966219820Sjeff if (err_str == NULL) 967219820Sjeff err_str = "Unknown Error Type"; 968219820Sjeff printf("\nError from osm_opensm_init: %s.\n", err_str); 969219820Sjeff /* We will just exit, and not go to Exit, since we don't 970219820Sjeff want the destroy to be called. */ 971219820Sjeff complib_exit(); 972219820Sjeff return (status); 973219820Sjeff } 974219820Sjeff 975219820Sjeff /* 976219820Sjeff If the user didn't specify a GUID on the command line, 977219820Sjeff then get a port GUID value with which to bind. 978219820Sjeff */ 979219820Sjeff if (opt.guid == 0 || cl_hton64(opt.guid) == CL_HTON64(INVALID_GUID)) 980219820Sjeff opt.guid = get_port_guid(&osm, opt.guid); 981219820Sjeff 982219820Sjeff status = osm_opensm_bind(&osm, opt.guid); 983219820Sjeff if (status != IB_SUCCESS) { 984219820Sjeff printf("\nError from osm_opensm_bind (0x%X)\n", status); 985219820Sjeff printf 986219820Sjeff ("Perhaps another instance of OpenSM is already running\n"); 987219820Sjeff goto Exit; 988219820Sjeff } 989219820Sjeff 990219820Sjeff setup_signals(); 991219820Sjeff 992219820Sjeff osm_opensm_sweep(&osm); 993219820Sjeff 994219820Sjeff if (run_once_flag == TRUE) { 995219820Sjeff while (!osm_exit_flag) { 996219820Sjeff status = 997219820Sjeff osm_opensm_wait_for_subnet_up(&osm, 998219820Sjeff osm.subn.opt. 999219820Sjeff sweep_interval * 1000219820Sjeff 1000000, TRUE); 1001219820Sjeff if (!status) 1002219820Sjeff osm_exit_flag = 1; 1003219820Sjeff } 1004219820Sjeff } else { 1005219820Sjeff /* 1006219820Sjeff * Sit here until signaled to exit 1007219820Sjeff */ 1008219820Sjeff osm_manager_loop(&opt, &osm); 1009219820Sjeff } 1010219820Sjeff 1011219820Sjeff if (osm.mad_pool.mads_out) { 1012219820Sjeff fprintf(stdout, 1013219820Sjeff "There are still %u MADs out. Forcing the exit of the OpenSM application...\n", 1014219820Sjeff osm.mad_pool.mads_out); 1015219820Sjeff#ifdef HAVE_LIBPTHREAD 1016219820Sjeff pthread_cond_signal(&osm.stats.cond); 1017219820Sjeff#else 1018219820Sjeff cl_event_signal(&osm.stats.event); 1019219820Sjeff#endif 1020219820Sjeff } 1021219820Sjeff 1022219820SjeffExit: 1023219820Sjeff osm_opensm_destroy(&osm); 1024219820Sjeff complib_exit(); 1025219820Sjeff 1026219820Sjeff exit(0); 1027219820Sjeff} 1028