opensm源码
路由算法此版本为opensm3.5版本, 涉及到的路由算法有以下几种:
1. Min Hop算法
2. UPDN 路由算法
3. DNUP路由算法
4. Fat-tree路由算法
5. LASH 路由算法
6.DOR 路由算法
7.Torus-2QoS路由算法等等
UPDN算法极力推荐使用, 该算法旨在防止死锁在子网构成循环中发生。 死锁这种情况不再在任何两个主机之间发送数据中发生。 因此建议使用UPDN路由算法。胖树这种算法对于高负载的情况会发生。
应用介绍
此版本为opensm3.5版本, 涉及到的路由算法有以下几种:
1. Min Hop算法
2. UPDN 路由算法
3. DNUP路由算法
4. Fat-tree路由算法
5. LASH 路由算法
6.DOR 路由算法
7.Torus-2QoS路由算法等等
UPDN算法极力推荐使用, 该算法旨在防止死锁在子网构成循环中发生。 死锁这种情况不再在任何两个主机之间发送数据中发生。 因此建议使用UPDN路由算法。胖树这种算法对于高负载的情况会发生死锁。
此代码纯c编写,主代码如下,其中最让人值得学习的是其中用了很多层回调函数,其中用了纯c编写的数据库,进行数据的存储,效率极高,具体可以查看源码
int main(int argc, char *argv[])
{
osm_opensm_t osm;
osm_subn_opt_t opt;
ib_net64_t sm_key = 0;
ib_api_status_t status;
uint32_t temp, dbg_lvl;
boolean_t run_once_flag = FALSE;
int32_t vendor_debug = 0;
int next_option;
char *conf_template = NULL;
const char *config_file = NULL;
uint32_t val;
const char *const short_option =
"F:c:i:w:O:f:ed:D:g:l:L:s:t:a:u:m:X:R:zM:U:S:P:Y:ANZ:WBIQvVhoryxp:n:q:k:C:G:H:";
/*
In the array below, the 2nd parameter specifies the number
of arguments as follows:
0: no arguments
1: argument
2: optional
*/
const struct option long_option[] = {
{"version", 0, NULL, 12},
{"config", 1, NULL, 'F'},
{"create-config", 1, NULL, 'c'},
{"debug", 1, NULL, 'd'},
{"guid", 1, NULL, 'g'},
{"ignore_guids", 1, NULL, 'i'},
{"hop_weights_file", 1, NULL, 'w'},
{"dimn_ports_file", 1, NULL, 'O'},
{"port_search_ordering_file", 1, NULL, 'O'},
{"lmc", 1, NULL, 'l'},
{"sweep", 1, NULL, 's'},
{"timeout", 1, NULL, 't'},
{"verbose", 0, NULL, 'v'},
{"D", 1, NULL, 'D'},
{"log_file", 1, NULL, 'f'},
{"log_limit", 1, NULL, 'L'},
{"erase_log_file", 0, NULL, 'e'},
{"Pconfig", 1, NULL, 'P'},
{"no_part_enforce", 0, NULL, 'N'},
{"part_enforce", 1, NULL, 'Z'},
{"allow_both_pkeys", 0, NULL, 'W'},
{"qos", 0, NULL, 'Q'},
{"qos_policy_file", 1, NULL, 'Y'},
{"congestion_control", 0, NULL, 128},
{"cc_key", 1, NULL, 129},
{"maxsmps", 1, NULL, 'n'},
{"console", 1, NULL, 'q'},
{"V", 0, NULL, 'V'},
{"help", 0, NULL, 'h'},
{"once", 0, NULL, 'o'},
{"reassign_lids", 0, NULL, 'r'},
{"priority", 1, NULL, 'p'},
{"smkey", 1, NULL, 'k'},
{"routing_engine", 1, NULL, 'R'},
{"ucast_cache", 0, NULL, 'A'},
{"connect_roots", 0, NULL, 'z'},
{"lid_matrix_file", 1, NULL, 'M'},
{"lfts_file", 1, NULL, 'U'},
{"sadb_file", 1, NULL, 'S'},
{"root_guid_file", 1, NULL, 'a'},
{"cn_guid_file", 1, NULL, 'u'},
{"io_guid_file", 1, NULL, 'G'},
{"port-shifting", 0, NULL, 11},
{"scatter-ports", 1, NULL, 14},
{"max_reverse_hops", 1, NULL, 'H'},
{"ids_guid_file", 1, NULL, 'm'},
{"guid_routing_order_file", 1, NULL, 'X'},
{"stay_on_fatal", 0, NULL, 'y'},
{"honor_guid2lid", 0, NULL, 'x'},
#ifdef ENABLE_OSM_CONSOLE_LOOPBACK
{"console-port", 1, NULL, 'C'},
#endif
{"daemon", 0, NULL, 'B'},
{"pidfile", 1, NULL, 'J'},
{"inactive", 0, NULL, 'I'},
#ifdef ENABLE_OSM_PERF_MGR
{"perfmgr", 0, NULL, 1},
{"perfmgr_sweep_time_s", 1, NULL, 2},
#endif
{"prefix_routes_file", 1, NULL, 3},
{"consolidate_ipv6_snm_req", 0, NULL, 4},
{"do_mesh_analysis", 0, NULL, 5},
{"lash_start_vl", 1, NULL, 6},
{"sm_sl", 1, NULL, 7},
{"retries", 1, NULL, 8},
{"log_prefix", 1, NULL, 9},
{"torus_config", 1, NULL, 10},
{"guid_routing_order_no_scatter", 0, NULL, 13},
{NULL, 0, NULL, 0} /* Required at the end of the array */
};
/* force stdout to be line-buffered */
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
/* Make sure that the opensm and complib were compiled using
same modes (debug/free) */
if (osm_is_debug() != cl_is_debug()) {
fprintf(stderr,
"ERROR: OpenSM and Complib were compiled using different modes\n");
fprintf(stderr, "ERROR: OpenSM debug:%d Complib debug:%d \n",
osm_is_debug(), cl_is_debug());
exit(1);
}
printf("-------------------------------------------------\n");
printf("%s\n", OSM_VERSION);
do {
next_option = getopt_long_only(argc, argv, short_option,
long_option, NULL);
switch (next_option) {
case 'F':
config_file = optarg;
printf("Config file is `%s`:\n", config_file);
break;
default:
break;
}
} while (next_option != -1);
optind = 0; /* reset command line */
if (!config_file)
config_file = OSM_DEFAULT_CONFIG_FILE;
osm_subn_set_default_opt(&opt);
if (osm_subn_parse_conf_file(config_file, &opt) < 0)
printf("\nFail to parse config file \'%s\'\n", config_file);
printf("Command Line Arguments:\n");
do {
next_option = getopt_long_only(argc, argv, short_option,
long_option, NULL);
switch (next_option) {
case 12: /* --version - already printed above */
exit(0);
break;
case 'F':
break;
case 'c':
conf_template = optarg;
printf(" Creating config file template \'%s\'.\n",
conf_template);
break;
case 'o':
/*
Run once option.
*/
run_once_flag = TRUE;
printf(" Run Once\n");
break;
case 'r':
/*
Reassign LIDs subnet option.
*/
opt.reassign_lids = TRUE;
printf(" Reassign LIDs\n");
break;
case 'i':
/*
Specifies ignore guids file.
*/
SET_STR_OPT(opt.port_prof_ignore_file, optarg);
printf(" Ignore Guids File = %s\n",
opt.port_prof_ignore_file);
break;
case 'w':
SET_STR_OPT(opt.hop_weights_file, optarg);
printf(" Hop Weights File = %s\n",
opt.hop_weights_file);
break;
case 'O':
SET_STR_OPT(opt.port_search_ordering_file, optarg);
printf(" Port Search Ordering/Dimension Ports File = %s\n",
opt.port_search_ordering_file);
break;
case 'g':
/*
Specifies port guid with which to bind.
*/
opt.guid = cl_hton64(strtoull(optarg, NULL, 16));
if (!opt.guid)
/* If guid is 0 - need to display the
* guid list */
opt.guid = INVALID_GUID;
else
printf(" Guid <0x%" PRIx64 ">\n",
cl_hton64(opt.guid));
break;
case 's':
val = strtol(optarg, NULL, 0);
/* Check that the number is not too large */
if (((uint32_t) (val * 1000000)) / 1000000 != val)
fprintf(stderr,
"ERROR: sweep interval given is too large. Ignoring it.\n");
else {
opt.sweep_interval = val;
printf(" sweep interval = %d\n",
opt.sweep_interval);
}
break;
case 't':
val = strtoul(optarg, NULL, 0);
opt.transaction_timeout = strtoul(optarg, NULL, 0);
if (val == 0)
fprintf(stderr, "ERROR: timeout value 0 is invalid. Ignoring it.\n");
else {
opt.transaction_timeout = val;
printf(" Transaction timeout = %u\n",
opt.transaction_timeout);
}
break;
case 'n':
opt.max_wire_smps = strtoul(optarg, NULL, 0);
if (opt.max_wire_smps == 0 ||
opt.max_wire_smps > 0x7FFFFFFF)
opt.max_wire_smps = 0x7FFFFFFF;
printf(" Max wire smp's = %d\n", opt.max_wire_smps);
break;
case 'q':
/*
* OpenSM interactive console
*/
if (strcmp(optarg, OSM_DISABLE_CONSOLE) == 0
|| strcmp(optarg, OSM_LOCAL_CONSOLE) == 0
#ifdef ENABLE_OSM_CONSOLE_SOCKET
|| strcmp(optarg, OSM_REMOTE_CONSOLE) == 0
#endif
#ifdef ENABLE_OSM_CONSOLE_LOOPBACK
|| strcmp(optarg, OSM_LOOPBACK_CONSOLE) == 0
#endif
)
SET_STR_OPT(opt.console, optarg);
else
printf("-console %s option not understood\n",
optarg);
break;
#ifdef ENABLE_OSM_CONSOLE_LOOPBACK
case 'C':
opt.console_port = strtol(optarg, NULL, 0);
break;
#endif
case 'd':
dbg_lvl = strtol(optarg, NULL, 0);
printf(" d level = 0x%x\n", dbg_lvl);
if (dbg_lvl == 0) {
printf(" Debug mode: Ignore Other SMs\n");
opt.ignore_other_sm = TRUE;
} else if (dbg_lvl == 1) {
printf(" Debug mode: Forcing Single Thread\n");
opt.single_thread = TRUE;
} else if (dbg_lvl == 2) {
printf(" Debug mode: Force Log Flush\n");
opt.force_log_flush = TRUE;
} else if (dbg_lvl == 3) {
printf
(" Debug mode: Disable multicast support\n");
opt.disable_multicast = TRUE;
}
/*
* NOTE: Debug level 4 used to be used for memory
* tracking but this is now deprecated
*/
else if (dbg_lvl == 5)
vendor_debug++;
else
printf(" OpenSM: Unknown debug option %d"
" ignored\n", dbg_lvl);
break;
case 'l':
temp = strtoul(optarg, NULL, 0);
if (temp > 7) {
fprintf(stderr,
"ERROR: LMC must be 7 or less.\n");
return -1;
}
opt.lmc = (uint8_t) temp;
printf(" LMC = %d\n", temp);
break;
case 'D':
opt.log_flags = strtol(optarg, NULL, 0);
printf(" verbose option -D = 0x%x\n", opt.log_flags);
break;
case 'f':
SET_STR_OPT(opt.log_file, optarg);
break;
case 'L':
opt.log_max_size = strtoul(optarg, NULL, 0);
printf(" Log file max size is %u MBytes\n",
opt.log_max_size);
break;
case 'e':
opt.accum_log_file = FALSE;
printf(" Creating new log file\n");
break;
case 'J':
pidfile = optarg;
break;
case 'P':
SET_STR_OPT(opt.partition_config_file, optarg);
break;
case 'N':
opt.no_partition_enforcement = TRUE;
break;
case 'Z':
if (strcmp(optarg, OSM_PARTITION_ENFORCE_BOTH) == 0
|| strcmp(optarg, OSM_PARTITION_ENFORCE_IN) == 0
|| strcmp(optarg, OSM_PARTITION_ENFORCE_OUT) == 0
|| strcmp(optarg, OSM_PARTITION_ENFORCE_OFF) == 0) {
SET_STR_OPT(opt.part_enforce, optarg);
if (strcmp(optarg, OSM_PARTITION_ENFORCE_BOTH) == 0)
opt.part_enforce_enum = OSM_PARTITION_ENFORCE_TYPE_BOTH;
else if (strcmp(optarg, OSM_PARTITION_ENFORCE_IN) == 0)
opt.part_enforce_enum = OSM_PARTITION_ENFORCE_TYPE_IN;
else if (strcmp(optarg, OSM_PARTITION_ENFORCE_OUT) == 0)
opt.part_enforce_enum = OSM_PARTITION_ENFORCE_TYPE_OUT;
else
opt.part_enforce_enum = OSM_PARTITION_ENFORCE_TYPE_OFF;
} else
printf("-part_enforce %s option not understood\n",
optarg);
break;
case 'W':
opt.allow_both_pkeys = TRUE;
break;
case 'Q':
opt.qos = TRUE;
break;
case 'Y':
SET_STR_OPT(opt.qos_policy_file, optarg);
printf(" QoS policy file \'%s\'\n", optarg);
break;
case 128:
opt.congestion_control = TRUE;
break;
case 129:
opt.cc_key = strtoull(optarg, NULL, 0);
printf(" CC Key 0x%" PRIx64 "\n", opt.cc_key);
break;
case 'y':
opt.exit_on_fatal = FALSE;
printf(" Staying on fatal initialization errors\n");
break;
case 'v':
opt.log_flags = (opt.log_flags << 1) | 1;
printf(" Verbose option -v (log flags = 0x%X)\n",
opt.log_flags);
break;
case 'V':
opt.log_flags = 0xFF;
opt.force_log_flush = TRUE;
printf(" Big V selected\n");
break;
case 'p':
temp = strtoul(optarg, NULL, 0);
if (temp > 15) {
fprintf(stderr,
"ERROR: priority must be between 0 and 15\n");
return -1;
}
opt.sm_priority = (uint8_t) temp;
printf(" Priority = %d\n", temp);
break;
case 'k':
sm_key = cl_hton64(strtoull(optarg, NULL, 16));
printf(" SM Key <0x%" PRIx64 ">\n", cl_hton64(sm_key));
opt.sm_key = sm_key;
break;
case 'R':
SET_STR_OPT(opt.routing_engine_names, optarg);
printf(" Activate \'%s\' routing engine(s)\n", optarg);
break;
case 'z':
opt.connect_roots = TRUE;
printf(" Connect roots option is on\n");
break;
case 'A':
opt.use_ucast_cache = TRUE;
printf(" Unicast routing cache option is on\n");
break;
case 'M':
SET_STR_OPT(opt.lid_matrix_dump_file, optarg);
printf(" Lid matrix dump file is \'%s\'\n", optarg);
break;
case 'U':
SET_STR_OPT(opt.lfts_file, optarg);
printf(" LFTs file is \'%s\'\n", optarg);
break;
case 'S':
SET_STR_OPT(opt.sa_db_file, optarg);
printf(" SA DB file is \'%s\'\n", optarg);
break;
case 'a':
SET_STR_OPT(opt.root_guid_file, optarg);
printf(" Root Guid File: %s\n", opt.root_guid_file);
break;
case 'u':
SET_STR_OPT(opt.cn_guid_file, optarg);
printf(" Compute Node Guid File: %s\n",
opt.cn_guid_file);
break;
case 'G':
SET_STR_OPT(opt.io_guid_file, optarg);
printf(" I/O Node Guid File: %s\n", opt.io_guid_file);
break;
case 11:
opt.port_shifting = TRUE;
printf(" Port Shifting is on\n");
break;
case 14:
opt.scatter_ports = strtol(optarg, NULL, 0);
printf(" Scatter Ports is on\n");
break;
case 'H':
opt.max_reverse_hops = atoi(optarg);
printf(" Max Reverse Hops: %d\n", opt.max_reverse_hops);
break;
case 'm':
SET_STR_OPT(opt.ids_guid_file, optarg);
printf(" IDs Guid File: %s\n", opt.ids_guid_file);
break;
case 'X':
SET_STR_OPT(opt.guid_routing_order_file, optarg);
printf(" GUID Routing Order File: %s\n",
opt.guid_routing_order_file);
break;
case 'x':
opt.honor_guid2lid_file = TRUE;
printf(" Honor guid2lid file, if possible\n");
break;
case 'B':
opt.daemon = TRUE;
printf(" Daemon mode\n");
break;
case 'I':
opt.sm_inactive = TRUE;
printf(" SM started in inactive state\n");
break;
#ifdef ENABLE_OSM_PERF_MGR
case 1:
opt.perfmgr = TRUE;
break;
case 2:
opt.perfmgr_sweep_time_s = atoi(optarg);
break;
#endif /* ENABLE_OSM_PERF_MGR */
case 3:
SET_STR_OPT(opt.prefix_routes_file, optarg);
break;
case 4:
opt.consolidate_ipv6_snm_req = TRUE;
break;
case 5:
opt.do_mesh_analysis = TRUE;
break;
case 6:
temp = strtoul(optarg, NULL, 0);
if (temp >= IB_MAX_NUM_VLS) {
fprintf(stderr,
"ERROR: starting lash vl must be between 0 and 15\n");
return -1;
}
opt.lash_start_vl = (uint8_t) temp;
printf(" LASH starting VL = %d\n", opt.lash_start_vl);
break;
case 7:
temp = strtoul(optarg, NULL, 0);
if (temp > 15) {
fprintf(stderr,
"ERROR: SM's SL must be between 0 and 15\n");
return -1;
}
opt.sm_sl = (uint8_t) temp;
printf(" SMSL = %d\n", opt.sm_sl);
break;
case 8:
opt.transaction_retries = strtoul(optarg, NULL, 0);
printf(" Transaction retries = %u\n",
opt.transaction_retries);
break;
case 9:
SET_STR_OPT(opt.log_prefix, optarg);
printf("Log prefix = %s\n", opt.log_prefix);
break;
case 10:
SET_STR_OPT(opt.torus_conf_file, optarg);
printf("Torus-2QoS config file = %s\n", opt.torus_conf_file);
break;
case 13:
opt.guid_routing_order_no_scatter = TRUE;
break;
case 'h':
case '?':
case ':':
show_usage();
break;
case -1:
break; /* done with option */
default: /* something wrong */
abort();
}
} while (next_option != -1);
if (opt.log_file != NULL)
printf(" Log File: %s\n", opt.log_file);
/* Done with options description */
printf("-------------------------------------------------\n");
if (conf_template) {
status = osm_subn_write_conf_file(conf_template, &opt);
if (status)
printf("\nosm_subn_write_conf_file failed!\n");
exit(status);
}
osm_subn_verify_config(&opt);
if (vendor_debug)
osm_vendor_set_debug(osm.p_vendor, vendor_debug);
block_signals();
if (opt.daemon) {
if (INVALID_GUID == opt.guid) {
fprintf(stderr,
"ERROR: Invalid GUID specified; exiting because of daemon mode\n");
return -1;
}
daemonize(&osm);
}
complib_init();
status = osm_opensm_init(&osm, &opt);
if (status != IB_SUCCESS) {
const char *err_str = ib_get_err_str(status);
if (err_str == NULL)
err_str = "Unknown Error Type";
printf("\nError from osm_opensm_init: %s.\n", err_str);
/* We will just exit, and not go to Exit, since we don't
want the destroy to be called. */
complib_exit();
return status;
}
/*
If the user didn't specify a GUID on the command line,
then get a port GUID value with which to bind.
*/
if (opt.guid == 0 || cl_hton64(opt.guid) == CL_HTON64(INVALID_GUID))
opt.guid = get_port_guid(&osm, opt.guid);
if (opt.guid == 0)
goto Exit2;
status = osm_opensm_init_finish(&osm, &opt);
if (status != IB_SUCCESS) {
const char *err_str = ib_get_err_str(status);
if (err_str == NULL)
err_str = "Unknown Error Type";
printf("\nError from osm_opensm_init_finish: %s.\n", err_str);
goto Exit2;
}
status = osm_opensm_bind(&osm, opt.guid);
if (status != IB_SUCCESS) {
printf("\nError from osm_opensm_bind (0x%X)\n", status);
printf
("Perhaps another instance of OpenSM is already running\n");
goto Exit;
}
setup_signals();
osm_opensm_sweep(&osm);
if (run_once_flag == TRUE) {
while (!osm_exit_flag) {
status =
osm_opensm_wait_for_subnet_up(&osm,
osm.subn.opt.
sweep_interval *
1000000, TRUE);
if (!status)
osm_exit_flag = 1;
}
} else {
/*
* Sit here until signaled to exit
*/
osm_manager_loop(&opt, &osm);
}
if (osm.mad_pool.mads_out) {
fprintf(stdout,
"There are still %u MADs out. Forcing the exit of the OpenSM application...\n",
osm.mad_pool.mads_out);
#ifdef HAVE_LIBPTHREAD
pthread_cond_signal(&osm.stats.cond);
#else
cl_event_signal(&osm.stats.event);
#endif
}
Exit:
osm_opensm_destroy(&osm);
Exit2:
osm_opensm_destroy_finish(&osm);
complib_exit();
remove_pidfile();
exit(0);
}
©版权声明:本文内容由互联网用户自发贡献,版权归原创作者所有,本站不拥有所有权,也不承担相关法律责任。如果您发现本站中有涉嫌抄袭的内容,欢迎发送邮件至: [email protected] 进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
转载请注明出处: apollocode » opensm源码
文件列表(部分)
名称 | 大小 | 修改日期 |
---|---|---|
opensm-3.3.20 | 0.00 KB | 2019-07-56 |
opensm-3.3.20 | 0.00 KB | 2019-07-58 |
aclocal.m4 | 34.00 KB | 2016-06-48 |
AUTHORS | 0.38 KB | 2013-02-28 |
autogen.sh | 1.91 KB | 2013-02-28 |
ChangeLog | 406.66 KB | 2016-06-18 |
complib | 0.00 KB | 2019-07-58 |
ChangeLog | 2.69 KB | 2013-02-28 |
cl_complib.c | 2.46 KB | 2013-02-28 |
cl_dispatcher.c | 10.23 KB | 2014-10-44 |
cl_event.c | 4.90 KB | 2013-02-28 |
cl_event_wheel.c | 17.00 KB | 2014-01-50 |
cl_list.c | 15.17 KB | 2013-02-28 |
cl_log.c | 3.33 KB | 2013-02-28 |
cl_map.c | 42.82 KB | 2013-02-28 |
cl_nodenamemap.c | 5.19 KB | 2014-01-50 |
cl_pool.c | 18.05 KB | 2013-02-28 |
cl_ptr_vector.c | 8.23 KB | 2013-02-28 |
cl_spinlock.c | 2.83 KB | 2013-02-28 |
cl_statustext.c | 2.20 KB | 2013-02-28 |
cl_thread.c | 3.80 KB | 2013-02-28 |
cl_threadpool.c | 4.19 KB | 2014-01-50 |
cl_timer.c | 11.77 KB | 2013-02-28 |
cl_vector.c | 13.25 KB | 2013-02-28 |
ib_statustext.c | 4.24 KB | 2013-02-28 |
libosmcomp.map | 3.18 KB | 2013-02-28 |
libosmcomp.ver | 0.33 KB | 2016-06-16 |
Makefile.am | 2.69 KB | 2014-01-50 |
Makefile.in | 39.83 KB | 2016-06-48 |
config | 0.00 KB | 2019-07-56 |
compile | 3.62 KB | 2014-07-46 |
config.guess | 41.05 KB | 2009-12-00 |
发表评论 取消回复