[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