[openib-general] [PATCH 3/4] New routing module which loads LFT tables from dump file.
Eitan Zahavi
eitan at mellanox.co.il
Tue Jun 13 04:30:37 PDT 2006
Hi Sasha,
Please see my comments inside
Sasha Khapyorsky wrote:
> This patch implements trivial routing module which able to load LFT
> tables from dump file. Main features:
> - support for unicast LFTs only, support for multicast can be added later
> - this will run after min hop matrix calculation
> - this will load switch LFTs according to the path entries introduced in
> the dump file
> - no additional checks will be performed (like is port connected, etc)
> - in case when fabric LIDs were changed this will try to reconstruct LFTs
> correctly if endport GUIDs are represented in the dump file (in order
> to disable this GUIDs may be removed from the dump file or zeroed)
I think you cold use the concept of directed routes for storing the LIDs too.
So in case of new LID assignments you can extract the old -> new mapping by
scanning the LIDs of end ports by their DR path.
Anyway, I think it is required that you also perform topology matching such that
if someone changed the topology you are able to figure it out and stop.
THIS IS A SERIOUS LIMITATION OF YOUR PROPOSAL.
>
> The dump file format is compatible with output of 'ibroute' util and for
> whole fabric may be generated with script like this:
>
> for sw_lid in `ibswitches | awk '{print $NF}'` ; do
> ibroute $sw_lid
> done > /path/to/dump_file
>
> , or using DR paths:
>
>
> for sw_dr in `ibnetdiscover -v \
> | sed -ne '/^DR path .* switch /s/^DR path \[\(.*\)\].*$/\1/p' \
> | sed -e 's/\]\[/,/g' \
> | sort -u` ; do
> ibroute -D ${sw_dr}
> done > /path/to/dump_file
WE SHOULD ALSO PROVIDE A DUMP FILE VIA:
1. OpenSM should dump its routes using this format (like it does today using osm.fdbs)
2. ibdiagnet
>
>
>
> diff --git a/osm/include/opensm/osm_subnet.h b/osm/include/opensm/osm_subnet.h
> index a637367..ec1d056 100644
> --- a/osm/include/opensm/osm_subnet.h
> +++ b/osm/include/opensm/osm_subnet.h
> @@ -423,6 +424,10 @@ typedef struct _osm_subn_opt
> * routing_engine_name
> * Name of used routing engine (other than default Min Hop Algorithm)
> *
> +* ucast_dump_file
> +* Name of the unicast routing dump file from where switch
> +* forwearding tables will be loaded
^^^^^^^^^^^
forwarding
> +*
> * updn_guid_file
> * Pointer to name of the UPDN guid file given by User
> *
>
> diff --git a/osm/opensm/osm_ucast_file.c b/osm/opensm/osm_ucast_file.c
> new file mode 100644
> index 0000000..a68d9ec
> --- /dev/null
> +++ b/osm/opensm/osm_ucast_file.c
> @@ -0,0 +1,258 @@
> +/*
> + * Copyright (c) 2006 Voltaire, Inc. All rights reserved.
> + *
> + * This software is available to you under a choice of one of two
> + * licenses. You may choose to be licensed under the terms of the GNU
> + * General Public License (GPL) Version 2, available from the file
> + * COPYING in the main directory of this source tree, or the
> + * OpenIB.org BSD license below:
> + *
> + * Redistribution and use in source and binary forms, with or
> + * without modification, are permitted provided that the following
> + * conditions are met:
> + *
> + * - Redistributions of source code must retain the above
> + * copyright notice, this list of conditions and the following
> + * disclaimer.
> + *
> + * - Redistributions in binary form must reproduce the above
> + * copyright notice, this list of conditions and the following
> + * disclaimer in the documentation and/or other materials
> + * provided with the distribution.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + *
> + * $Id$
> + */
> +
> +/*
> + * Abstract:
> + * Implementation of OpenSM unicast routing module which loads
> + * routes from the dump file
> + *
> + * Environment:
> + * Linux User Mode
> + *
> + */
> +
> +#if HAVE_CONFIG_H
> +# include <config.h>
> +#endif /* HAVE_CONFIG_H */
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <ctype.h>
> +
> +#include <iba/ib_types.h>
> +#include <complib/cl_qmap.h>
> +#include <opensm/osm_opensm.h>
> +#include <opensm/osm_switch.h>
> +#include <opensm/osm_log.h>
> +
> +#define PARSEERR(log, file_name, lineno, fmt, arg...) \
> + osm_log(log, OSM_LOG_ERROR, "PARSE ERROR: %s:%u: " fmt , \
> + file_name, lineno, ##arg )
> +
> +#define PARSEWARN(log, file_name, lineno, fmt, arg...) \
> + osm_log(log, OSM_LOG_VERBOSE, "PARSE WARN: %s:%u: " fmt , \
> + file_name, lineno, ##arg )
> +
> +static uint16_t remap_lid(osm_opensm_t *p_osm, uint16_t lid, ib_net64_t guid)
> +{
> + osm_port_t *p_port;
> + uint16_t min_lid, max_lid;
> + uint8_t lmc;
> +
> + p_port = (osm_port_t *)cl_qmap_get(&p_osm->subn.port_guid_tbl, guid);
> + if (!p_port ||
> + p_port == (osm_port_t *)cl_qmap_end(&p_osm->subn.port_guid_tbl)) {
> + osm_log(&p_osm->log, OSM_LOG_VERBOSE,
> + "remap_lid: cannot find port guid 0x%016" PRIx64
> + " , will use the same lid.\n", cl_ntoh64(guid));
> + return lid;
> + }
> +
> + osm_port_get_lid_range_ho(p_port, &min_lid, &max_lid);
> + if (min_lid <= lid && lid <= max_lid)
> + return lid;
> +
> + lmc = osm_port_get_lmc(p_port);
> + return min_lid + (lid & ((1 << lmc) - 1));
> +}
> +
> +static void add_path(osm_opensm_t * p_osm,
> + osm_switch_t * p_sw, uint16_t lid, uint8_t port_num,
> + ib_net64_t port_guid)
> +{
> + uint16_t new_lid;
> + uint8_t old_port;
> +
> + new_lid = port_guid ? remap_lid(p_osm, lid, port_guid) : lid;
> + old_port = osm_fwd_tbl_get(osm_switch_get_fwd_tbl_ptr(p_sw), new_lid);
> + if (old_port != OSM_NO_PATH && old_port != port_num) {
> + osm_log(&p_osm->log, OSM_LOG_VERBOSE,
> + "add_path: LID collision is detected on switch "
> + "0x016%" PRIx64 ", will overwrite LID 0x%x entry.\n",
> + cl_ntoh64(osm_node_get_node_guid
> + (osm_switch_get_node_ptr(p_sw))), new_lid);
> + }
> +
> + osm_switch_set_path(p_sw, new_lid, port_num, TRUE);
> +
> + osm_log(&p_osm->log, OSM_LOG_DEBUG,
> + "add_path: route 0x%04x(was 0x%04x) %u 0x%016" PRIx64
> + " is added to switch 0x%016" PRIx64 "\n",
> + new_lid, lid, port_num, cl_ntoh64(port_guid),
> + cl_ntoh64(osm_node_get_node_guid
> + (osm_switch_get_node_ptr(p_sw))));
> +}
> +
> +static void clean_sw_fwd_table(void *arg, void *context)
> +{
> + osm_switch_t *p_sw = arg;
> + uint16_t lid, max_lid;
> +
> + max_lid = osm_switch_get_max_lid_ho(p_sw);
> + for (lid = 1 ; lid <= max_lid ; lid++)
> + osm_switch_set_path(p_sw, lid, OSM_NO_PATH, TRUE);
> +}
> +
> +static int do_ucast_file_load(void *context)
> +{
> + char line[1024];
> + char *file_name;
> + FILE *file;
> + ib_net64_t sw_guid, port_guid;
> + osm_opensm_t *p_osm = context;
> + osm_switch_t *p_sw;
> + uint16_t lid;
> + uint8_t port_num;
> + unsigned lineno;
> +
> + file_name = p_osm->subn.opt.ucast_dump_file;
> +
> + if (!file_name) {
> + osm_log(&p_osm->log, OSM_LOG_ERROR,
> + "do_ucast_file_load: "
> + "ucast dump file name is not defined.\n");
> + return -1;
> + }
> +
> + file = fopen(file_name, "r");
> + if (!file) {
> + osm_log(&p_osm->log, OSM_LOG_ERROR,
> + "do_ucast_file_load: "
> + "cannot open ucast dump file \'%s\'\n", file_name);
> + return -1;
> + }
> +
> + cl_qmap_apply_func(&p_osm->subn.sw_guid_tbl, clean_sw_fwd_table, 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, "Multicast mlids", 15)) {
> + osm_log(&p_osm->log, OSM_LOG_ERROR,
> + "do_ucast_file_load: "
> + "Multicast dump file is detected. "
> + "Skip parsing.\n");
> + }
> + else if (!strncmp(p, "Unicast lids", 12)) {
> + q = strstr(p, " guid 0x");
> + if (!q) {
> + PARSEERR(&p_osm->log, file_name, lineno,
> + "cannot parse switch definition\n");
> + return -1;
> + }
> + p = q + 6;
> + sw_guid = strtoll(p, &q, 16);
> + if (q && !isspace(*q)) {
> + PARSEERR(&p_osm->log, file_name, lineno,
> + "cannot parse switch guid: \'%s\'\n",
> + p);
> + return -1;
> + }
> + sw_guid = cl_hton64(sw_guid);
> +
> + p_sw = (osm_switch_t *)cl_qmap_get(&p_osm->subn.sw_guid_tbl,
> + sw_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_ucast_file_load: "
> + "cannot find switch %016" PRIx64 ".\n",
> + cl_ntoh64(sw_guid));
> + continue;
> + }
> + }
> + else if (p_sw && !strncmp(p, "0x", 2)) {
> + lid = strtoul(p, &q, 16);
> + if (q && !isspace(*q)) {
> + PARSEERR(&p_osm->log, file_name, lineno,
> + "cannot parse lid: \'%s\'\n", p);
> + return -1;
> + }
> + p = q;
> + while (isspace(*p))
> + p++;
> + port_num = strtoul(p, &q, 10);
> + if (q && !isspace(*q)) {
> + PARSEERR(&p_osm->log, file_name, lineno,
> + "cannot parse port: \'%s\'\n", p);
> + return -1;
> + }
> + p = q;
> + /* additionally try to exract guid */
> + q = strstr(p, " portguid 0x");
> + if (!q) {
> + PARSEWARN(&p_osm->log, file_name, lineno,
> + "cannot find port guid "
> + "(maybe broken dump): \'%s\'\n", p);
> + port_guid = 0;
> + }
> + else {
> + p = q + 10;
> + port_guid = strtoll(p, &q, 16);
> + if (!q && !isspace(*q) && *q != ':') {
> + PARSEWARN(&p_osm->log, file_name,
> + lineno,
> + "cannot parse port guid "
> + "(maybe broken dump): "
> + "\'%s\'\n", p);
> + port_guid = 0;
> + }
> + }
> + port_guid = cl_hton64(port_guid);
> + add_path(p_osm, p_sw, lid, port_num, port_guid);
> + }
> + }
> +
> + fclose(file);
> + return 0;
> +}
In OpenSM we write with style:
if () {
}
else if ()
{
}
else
{
}
Not any other combination
> +
> +int osm_ucast_file_setup(osm_opensm_t * p_osm)
> +{
> + p_osm->routing_engine.context = (void *)p_osm;
> + p_osm->routing_engine.ucast_build_fwd_tables = do_ucast_file_load;
> + return 0;
> +}
More information about the general
mailing list