[openib-general] [PATCH 4/5] opensm: lid matrix file loader
Sasha Khapyorsky
sashak at voltaire.com
Thu Oct 19 13:35:24 PDT 2006
This adds lid matrices dump file parser and loader. It is part of 'file'
routing engine, the file name should be specified in OpenSM command line
with -M or --lid_matrix_file option (no default value). Example of valid
usage is:
opensm -R file -M ./opensm-lid-matrix.dump
The file format is compatible with one generated by OpenSM ucast dumper
(will be created when OSM_LOG_ROUTING logging flag is set).
When specified file does not exist or in case of parser/loader failure
default lid matrix calculation algorithm will be used.
Signed-off-by: Sasha Khapyorsky <sashak at voltaire.com>
---
osm/include/opensm/osm_subnet.h | 5 +
osm/opensm/main.c | 13 +++-
osm/opensm/osm_subnet.c | 10 +++
osm/opensm/osm_ucast_file.c | 166 +++++++++++++++++++++++++++++++++++++++
4 files changed, 193 insertions(+), 1 deletions(-)
diff --git a/osm/include/opensm/osm_subnet.h b/osm/include/opensm/osm_subnet.h
index 36a4b55..abd3c56 100644
--- a/osm/include/opensm/osm_subnet.h
+++ b/osm/include/opensm/osm_subnet.h
@@ -276,6 +276,7 @@ typedef struct _osm_subn_opt
boolean_t sweep_on_trap;
osm_testability_modes_t testability_mode;
char * routing_engine_name;
+ char * lid_matrix_dump_file;
char * ucast_dump_file;
char * updn_guid_file;
boolean_t exit_on_fatal;
@@ -431,6 +432,10 @@ typedef struct _osm_subn_opt
* Name of used routing engine
* (other than default Min Hop Algorithm)
*
+* lid_matrix_dump_file
+* Name of the lid matrix dump file from where switch
+* lid matrices (min hops tables) will be loaded
+*
* ucast_dump_file
* Name of the unicast routing dump file from where switch
* forwarding tables will be loaded
diff --git a/osm/opensm/main.c b/osm/opensm/main.c
index 90f3dbd..729702a 100644
--- a/osm/opensm/main.c
+++ b/osm/opensm/main.c
@@ -177,6 +177,11 @@ show_usage(void)
"--routing_engine <engine name>\n"
" This option chooses routing engine instead of Min Hop\n"
" algorithm (default). Supported engines: updn, file\n\n");
+ printf( "-M\n"
+ "--lid_matrix_file <file name>\n"
+ " This option specifies name of the lid matrix dump file\n"
+ " from where switch lid matrices (min hops tables will be\n"
+ " loaded.\n\n");
printf( "-U\n"
"--ucast_file <file name>\n"
" This option specifies name of the unicast dump file\n"
@@ -531,7 +536,7 @@ #endif
boolean_t cache_options = FALSE;
char *ignore_guids_file_name = NULL;
uint32_t val;
- const char * const short_option = "i:f:ed:g:l:L:s:t:a:R:U:P:NQvVhorcyx";
+ const char * const short_option = "i:f:ed:g:l:L:s:t:a:R:M:U:P:NQvVhorcyx";
/*
In the array below, the 2nd parameter specified the number
@@ -565,6 +570,7 @@ #endif
{ "priority", 1, NULL, 'p'},
{ "smkey", 1, NULL, 'k'},
{ "routing_engine",1, NULL, 'R'},
+ { "lid_matrix_file",1, NULL, 'M'},
{ "ucast_file" ,1, NULL, 'U'},
{ "add_guid_file", 1, NULL, 'a'},
{ "cache-options", 0, NULL, 'c'},
@@ -795,6 +801,11 @@ #endif
printf(" Activate \'%s\' routing engine\n", optarg);
break;
+ case 'M':
+ opt.lid_matrix_dump_file = optarg;
+ printf(" Lid matrix dump file is \'%s\'\n", optarg);
+ break;
+
case 'U':
opt.ucast_dump_file = optarg;
printf(" Ucast dump file is \'%s\'\n", optarg);
diff --git a/osm/opensm/osm_subnet.c b/osm/opensm/osm_subnet.c
index 2b25fc7..9c9acee 100644
--- a/osm/opensm/osm_subnet.c
+++ b/osm/opensm/osm_subnet.c
@@ -492,6 +492,7 @@ osm_subn_set_default_opt(
p_opt->sweep_on_trap = TRUE;
p_opt->testability_mode = OSM_TEST_MODE_NONE;
p_opt->routing_engine_name = NULL;
+ p_opt->lid_matrix_dump_file = NULL;
p_opt->ucast_dump_file = NULL;
p_opt->updn_guid_file = NULL;
p_opt->exit_on_fatal = TRUE;
@@ -950,6 +951,10 @@ osm_subn_parse_conf_file(
"dump_files_dir",
p_key, p_val, &p_opts->dump_files_dir);
+ __osm_subn_opts_unpack_charp(
+ "lid_matrix_dump_file",
+ p_key, p_val, &p_opts->lid_matrix_dump_file);
+
__osm_subn_opts_unpack_charp(
"ucast_dump_file",
p_key, p_val, &p_opts->ucast_dump_file);
@@ -1123,6 +1128,11 @@ osm_subn_write_conf_file(
"# Routing engine\n"
"routing_engine %s\n\n",
p_opts->routing_engine_name);
+ if (p_opts->lid_matrix_dump_file)
+ fprintf( opts_file,
+ "# Lid matrix dump file name\n"
+ "lid_matrix_dump_file %s\n\n",
+ p_opts->lid_matrix_dump_file);
if (p_opts->ucast_dump_file)
fprintf( opts_file,
"# Ucast dump file name\n"
diff --git a/osm/opensm/osm_ucast_file.c b/osm/opensm/osm_ucast_file.c
index 446c243..a9ea2c0 100644
--- a/osm/opensm/osm_ucast_file.c
+++ b/osm/opensm/osm_ucast_file.c
@@ -108,6 +108,28 @@ static void add_path(osm_opensm_t * p_os
(osm_switch_get_node_ptr(p_sw))));
}
+static void add_lid_hops(osm_opensm_t *p_osm, osm_switch_t *p_sw,
+ uint16_t lid, ib_net64_t guid,
+ uint8_t hops[], unsigned len)
+{
+ uint16_t new_lid;
+ unsigned i;
+
+ new_lid = guid ? remap_lid(p_osm, lid, guid) : lid;
+ if (len > osm_switch_get_num_ports(p_sw))
+ len = osm_switch_get_num_ports(p_sw);
+
+ for (i = 0 ; i < len ; i++)
+ osm_switch_set_hops(p_sw, lid, i, hops[i]);
+}
+
+static void clean_sw_lid_matrix(cl_map_item_t* const p_map_item, void *context)
+{
+ osm_switch_t * const p_sw = (osm_switch_t *)p_map_item;
+
+ osm_lid_matrix_clear(&p_sw->lmx);
+}
+
static void clean_sw_fwd_table(cl_map_item_t* const p_map_item, void *context)
{
osm_switch_t * const p_sw = (osm_switch_t *)p_map_item;
@@ -254,9 +276,153 @@ static int do_ucast_file_load(void *cont
return 0;
}
+static int do_lid_matrix_file_load(void *context)
+{
+ char line[1024];
+ uint8_t hops[256];
+ char *file_name;
+ FILE *file;
+ ib_net64_t guid;
+ osm_opensm_t *p_osm = context;
+ osm_switch_t *p_sw;
+ unsigned lineno;
+ uint16_t lid;
+
+ file_name = p_osm->subn.opt.lid_matrix_dump_file;
+ if (!file_name) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR|OSM_LOG_SYS,
+ "do_lid_matrix_file_load: ERR 6304: "
+ "lid matrix file name is not defined; "
+ "using default lid matrix generation algorithm\n");
+ return -1;
+ }
+
+ file = fopen(file_name, "r");
+ if (!file) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR|OSM_LOG_SYS,
+ "do_do_lid_matrix_file_load: ERR 6305: "
+ "cannot open lid matrix file \'%s\'; "
+ "using default lid matrix generation algorithm\n",
+ file_name);
+ return -1;
+ }
+
+ cl_qmap_apply_func(&p_osm->subn.sw_guid_tbl, clean_sw_lid_matrix, NULL);
+
+ lineno = 0;
+ p_sw = NULL;
+
+ while (fgets(line, sizeof(line) - 1, file) != NULL) {
+ char *p, *q;
+ lineno++;
+
+ p = line;
+ while (isspace(*p))
+ p++;
+
+ if (*p == '#')
+ continue;
+
+ if (!strncmp(p, "Switch", 6)) {
+ q = strstr(p, " guid 0x");
+ if (!q) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR,
+ "PARSE ERROR: %s:%u: "
+ "cannot parse switch definition\n",
+ file_name, lineno);
+ return -1;
+ }
+ p = q + 8;
+ guid = strtoull(p, &q, 16);
+ if (q == p || !isspace(*q)) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR,
+ "PARSE ERROR: %s:%u: "
+ "cannot parse switch guid: \'%s\'\n",
+ file_name, lineno, p);
+ return -1;
+ }
+ guid = cl_hton64(guid);
+
+ p_sw = (osm_switch_t *)cl_qmap_get(&p_osm->subn.sw_guid_tbl,
+ guid);
+ if (!p_sw ||
+ p_sw == (osm_switch_t *)cl_qmap_end(&p_osm->subn.sw_guid_tbl)) {
+ p_sw = NULL;
+ osm_log(&p_osm->log, OSM_LOG_VERBOSE,
+ "do_lid_matrix_file_load: "
+ "cannot find switch %016" PRIx64 "\n",
+ cl_ntoh64(guid));
+ continue;
+ }
+ } else if (p_sw && !strncmp(p, "0x", 2)) {
+ unsigned long num;
+ unsigned len = 0;
+
+ memset(hops, 0xff, sizeof(hops));
+
+ p += 2;
+ num = strtoul(p, &q, 16);
+ if (num > 0xffff || q == p ||
+ (*q != ':' && !isspace(*q))) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR,
+ "PARSE ERROR: %s:%u: "
+ "cannot parse lid: \'%s\'\n",
+ file_name, lineno, p);
+ return -1;
+ }
+ lid = num;
+ p = q;
+ while (isspace(*p) || *p == ':')
+ p++;
+ while (len < 256 && *p && *p != '#') {
+ num = strtoul(p, &q, 16);
+ if (num > 0xff || q == p) {
+ osm_log(&p_osm->log, OSM_LOG_ERROR,
+ "PARSE ERROR: %s:%u: "
+ "cannot parse hops number: \'%s\'\n",
+ file_name, lineno, p);
+ return -1;
+ }
+ hops[len++] = num;
+ p = q;
+ while (isspace(*p))
+ p++;
+ }
+ /* additionally try to exract guid */
+ q = strstr(p, " portguid 0x");
+ if (!q) {
+ osm_log(&p_osm->log, OSM_LOG_VERBOSE,
+ "PARSE WARNING: %s:%u: "
+ "cannot find port guid "
+ "(maybe broken dump): \'%s\'\n",
+ file_name, lineno, p);
+ guid = 0;
+ }
+ else {
+ p = q + 12;
+ guid = strtoull(p, &q, 16);
+ if (q == p || !isspace(*q)) {
+ osm_log(&p_osm->log, OSM_LOG_VERBOSE,
+ "PARSE WARNING: %s:%u: "
+ "cannot parse port guid "
+ "(maybe broken dump): \'%s\'\n",
+ file_name, lineno, p);
+ guid = 0;
+ }
+ }
+ guid = cl_hton64(guid);
+ add_lid_hops(p_osm, p_sw, lid, guid, hops, len);
+ }
+ }
+
+ fclose(file);
+ return 0;
+}
+
int osm_ucast_file_setup(osm_opensm_t * p_osm)
{
p_osm->routing_engine.context = (void *)p_osm;
+ p_osm->routing_engine.build_lid_matrices = do_lid_matrix_file_load;
p_osm->routing_engine.ucast_build_fwd_tables = do_ucast_file_load;
return 0;
}
--
1.4.3.g7768
More information about the general
mailing list