int osm_ucast_cache_process(osm_ucast_mgr_t * p_mgr) { cl_qmap_t *tbl = &p_mgr->p_subn->sw_guid_tbl; cl_map_item_t *item; osm_switch_t *p_sw; uint16_t lft_size; if (!p_mgr->p_subn->opt.use_ucast_cache) return 1; ucast_cache_validate(p_mgr); if (!p_mgr->cache_valid) return 1; OSM_LOG(p_mgr->p_log, OSM_LOG_INFO, "Configuring switch tables using cached routing\n"); for (item = cl_qmap_head(tbl); item != cl_qmap_end(tbl); item = cl_qmap_next(item)) { p_sw = (osm_switch_t *) item; if (p_sw->need_update) { if (!p_sw->new_lft) /* no new routing was recently calculated for this switch, but the LFT needs to be updated anyway */ p_sw->new_lft = p_sw->lft; lft_size = (p_sw->max_lid_ho / IB_SMP_DATA_SIZE + 1) * IB_SMP_DATA_SIZE; p_sw->lft = malloc(lft_size); if (!p_sw->lft) return IB_INSUFFICIENT_MEMORY; p_sw->lft_size = lft_size; memset(p_sw->lft, OSM_NO_PATH, p_sw->lft_size); } } osm_ucast_mgr_set_fwd_tables(p_mgr); return 0; }
static int ucast_mgr_route(struct osm_routing_engine *r, osm_opensm_t * osm) { int ret; OSM_LOG(&osm->log, OSM_LOG_VERBOSE, "building routing with \'%s\' routing algorithm...\n", r->name); /* Set the before each lft build to keep the routes in place between sweeps */ if (osm->subn.opt.scatter_ports) srandom(osm->subn.opt.scatter_ports); if (!r->build_lid_matrices || (ret = r->build_lid_matrices(r->context)) > 0) ret = osm_ucast_mgr_build_lid_matrices(&osm->sm.ucast_mgr); if (ret < 0) { OSM_LOG(&osm->log, OSM_LOG_ERROR, "%s: cannot build lid matrices\n", r->name); return ret; } if (!r->ucast_build_fwd_tables || (ret = r->ucast_build_fwd_tables(r->context)) > 0) ret = ucast_mgr_build_lfts(&osm->sm.ucast_mgr); if (ret < 0) { OSM_LOG(&osm->log, OSM_LOG_ERROR, "%s: cannot build fwd tables\n", r->name); return ret; } osm->routing_engine_used = r; osm_ucast_mgr_set_fwd_tables(&osm->sm.ucast_mgr); return 0; }
int osm_ucast_mgr_process(IN osm_ucast_mgr_t * p_mgr) { osm_opensm_t *p_osm; struct osm_routing_engine *p_routing_eng; cl_qmap_t *p_sw_guid_tbl; int failed = 0; OSM_LOG_ENTER(p_mgr->p_log); p_sw_guid_tbl = &p_mgr->p_subn->sw_guid_tbl; p_osm = p_mgr->p_subn->p_osm; p_routing_eng = p_osm->routing_engine_list; CL_PLOCK_EXCL_ACQUIRE(p_mgr->p_lock); /* If there are no switches in the subnet, we are done. */ if (cl_qmap_count(p_sw_guid_tbl) == 0 || ucast_mgr_setup_all_switches(p_mgr->p_subn) < 0) goto Exit; failed = -1; p_osm->routing_engine_used = NULL; while (p_routing_eng) { failed = ucast_mgr_route(p_routing_eng, p_osm); if (!failed) break; p_routing_eng = p_routing_eng->next; } if (!p_osm->routing_engine_used && p_osm->no_fallback_routing_engine != TRUE) { /* If configured routing algorithm failed, use default MinHop */ struct osm_routing_engine *r = p_osm->default_routing_engine; r->build_lid_matrices(r->context); failed = r->ucast_build_fwd_tables(r->context); if (!failed) { p_osm->routing_engine_used = r; osm_ucast_mgr_set_fwd_tables(p_mgr); } } if (p_osm->routing_engine_used) { OSM_LOG(p_mgr->p_log, OSM_LOG_INFO, "%s tables configured on all switches\n", osm_routing_engine_type_str(p_osm-> routing_engine_used->type)); if (p_mgr->p_subn->opt.use_ucast_cache) p_mgr->cache_valid = TRUE; } else { p_mgr->p_subn->subnet_initialization_error = TRUE; OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "No routing engine able to successfully configure " " switch tables on current fabric\n"); } Exit: CL_PLOCK_RELEASE(p_mgr->p_lock); OSM_LOG_EXIT(p_mgr->p_log); return failed; }