|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2010 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2009-2011 ZIH, TU Dresden, Federal Republic of Germany. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (C) 2012-2017 Tokyo Institute of Technology. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2019 Fabriscale Technologies AS. All rights reserved.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* This software is available to you under a choice of one of two
|
|
Packit |
13e616 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit |
13e616 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit |
13e616 |
* COPYING in the main directory of this source tree, or the
|
|
Packit |
13e616 |
* OpenIB.org BSD license below:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* Redistribution and use in source and binary forms, with or
|
|
Packit |
13e616 |
* without modification, are permitted provided that the following
|
|
Packit |
13e616 |
* conditions are met:
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions of source code must retain the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* - Redistributions in binary form must reproduce the above
|
|
Packit |
13e616 |
* copyright notice, this list of conditions and the following
|
|
Packit |
13e616 |
* disclaimer in the documentation and/or other materials
|
|
Packit |
13e616 |
* provided with the distribution.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
13e616 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
13e616 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
13e616 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit |
13e616 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit |
13e616 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit |
13e616 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit |
13e616 |
* SOFTWARE.
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Abstract:
|
|
Packit |
13e616 |
* Implementation of osm_opensm_t.
|
|
Packit |
13e616 |
* This object represents the opensm super object.
|
|
Packit |
13e616 |
* This object is part of the opensm family of objects.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if HAVE_CONFIG_H
|
|
Packit |
13e616 |
# include <config.h>
|
|
Packit |
13e616 |
#endif /* HAVE_CONFIG_H */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#include <stdio.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <string.h>
|
|
Packit |
13e616 |
#include <complib/cl_dispatcher.h>
|
|
Packit |
13e616 |
#include <complib/cl_list.h>
|
|
Packit |
13e616 |
#include <complib/cl_passivelock.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_OPENSM_C
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_api.h>
|
|
Packit |
13e616 |
#include <opensm/osm_version.h>
|
|
Packit |
13e616 |
#include <opensm/osm_base.h>
|
|
Packit |
13e616 |
#include <opensm/osm_opensm.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <opensm/osm_subnet.h>
|
|
Packit |
13e616 |
#include <opensm/osm_sm.h>
|
|
Packit |
13e616 |
#include <opensm/osm_vl15intf.h>
|
|
Packit |
13e616 |
#include <opensm/osm_event_plugin.h>
|
|
Packit |
13e616 |
#include <opensm/osm_congestion_control.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* built-in routing engine setup functions
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
extern int osm_ucast_minhop_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_updn_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_dnup_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_file_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_ftree_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_lash_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_dor_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_torus2QoS_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_nue_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_sssp_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
extern int osm_ucast_dfsssp_setup(struct osm_routing_engine *, osm_opensm_t *);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Local types
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
typedef struct builtin_routing_engine_module {
|
|
Packit |
13e616 |
const char *name;
|
|
Packit |
13e616 |
osm_routing_engine_type_t type;
|
|
Packit |
13e616 |
int (*setup)(struct osm_routing_engine *re, struct osm_opensm *osm);
|
|
Packit |
13e616 |
} builtin_routing_engine_module_t;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
typedef struct routing_engine_module {
|
|
Packit |
13e616 |
char *name;
|
|
Packit |
13e616 |
osm_routing_engine_type_t type;
|
|
Packit |
13e616 |
int (*setup)(struct osm_routing_engine *re, struct osm_opensm *osm);
|
|
Packit |
13e616 |
void *context;
|
|
Packit |
13e616 |
} routing_engine_module_t;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Local variables
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static const char *unknown_routing_engine_name = "unknown";
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_list_t routing_modules;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static osm_routing_engine_type_t last_external_routing_engine_type =
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_EXTERNAL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static builtin_routing_engine_module_t static_routing_modules[] = {
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"none",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_NONE,
|
|
Packit |
13e616 |
NULL
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"minhop",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_MINHOP,
|
|
Packit |
13e616 |
osm_ucast_minhop_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"updn",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_UPDN,
|
|
Packit |
13e616 |
osm_ucast_updn_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"dnup",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_DNUP,
|
|
Packit |
13e616 |
osm_ucast_dnup_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"file",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_FILE,
|
|
Packit |
13e616 |
osm_ucast_file_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"ftree",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_FTREE,
|
|
Packit |
13e616 |
osm_ucast_ftree_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"lash",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_LASH,
|
|
Packit |
13e616 |
osm_ucast_lash_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"dor",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_DOR,
|
|
Packit |
13e616 |
osm_ucast_dor_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"torus-2QoS",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_TORUS_2QOS,
|
|
Packit |
13e616 |
osm_ucast_torus2QoS_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"nue",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_NUE,
|
|
Packit |
13e616 |
osm_ucast_nue_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"dfsssp",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_DFSSSP,
|
|
Packit |
13e616 |
osm_ucast_dfsssp_setup
|
|
Packit |
13e616 |
},
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
"sssp",
|
|
Packit |
13e616 |
OSM_ROUTING_ENGINE_TYPE_SSSP,
|
|
Packit |
13e616 |
osm_ucast_sssp_setup
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
};
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Forward declarations
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t _match_routing_engine_type(
|
|
Packit |
13e616 |
IN const void *const p_object, IN void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t _match_routing_engine_str(
|
|
Packit |
13e616 |
IN const void *const p_object, IN void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void append_routing_engine(
|
|
Packit |
13e616 |
osm_opensm_t *osm, struct osm_routing_engine *routing_engine);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static struct osm_routing_engine *setup_routing_engine(
|
|
Packit |
13e616 |
osm_opensm_t *osm, const char *name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void dump_routing_engine(
|
|
Packit |
13e616 |
IN void *const p_object, IN void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void dump_routing_engines(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void setup_routing_engines(
|
|
Packit |
13e616 |
osm_opensm_t *osm, const char *engine_names);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t register_builtin_routing_engine(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm,
|
|
Packit |
13e616 |
IN const builtin_routing_engine_module_t *module);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t register_routing_engine(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm,
|
|
Packit |
13e616 |
IN const routing_engine_module_t *module);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void destroy_routing_engines(
|
|
Packit |
13e616 |
osm_opensm_t *osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __free_routing_module(
|
|
Packit |
13e616 |
void *p_object, void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static const char *routing_engine_type(
|
|
Packit |
13e616 |
IN osm_routing_engine_type_t type);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/** =========================================================================
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status_t osm_register_external_routing_engine(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm,
|
|
Packit |
13e616 |
IN const external_routing_engine_module_t *module,
|
|
Packit |
13e616 |
IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
routing_engine_module_t *copy = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!osm || !module)
|
|
Packit |
13e616 |
return CL_INVALID_PARAMETER;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Assign type '%d' to external routing engine with name: \'%s\'\n",
|
|
Packit |
13e616 |
last_external_routing_engine_type,
|
|
Packit |
13e616 |
module->name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy = (routing_engine_module_t *) malloc(sizeof(routing_engine_module_t));
|
|
Packit |
13e616 |
if (!copy) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR, "memory allocation failed\n");
|
|
Packit |
13e616 |
return CL_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy->name = strdup(module->name);
|
|
Packit |
13e616 |
if (!copy->name) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR, "memory allocation failed\n");
|
|
Packit |
13e616 |
__free_routing_module(copy, NULL);
|
|
Packit |
13e616 |
return CL_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy->setup = module->setup;
|
|
Packit |
13e616 |
copy->type = last_external_routing_engine_type++;
|
|
Packit |
13e616 |
copy->context = context;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = register_routing_engine(osm, copy);
|
|
Packit |
13e616 |
if (status != CL_SUCCESS)
|
|
Packit |
13e616 |
__free_routing_module(copy, NULL);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status_t register_builtin_routing_engine(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm,
|
|
Packit |
13e616 |
IN const builtin_routing_engine_module_t *module)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
routing_engine_module_t *copy;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!osm || !module)
|
|
Packit |
13e616 |
return CL_INVALID_PARAMETER;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy = (routing_engine_module_t *) malloc(sizeof(routing_engine_module_t));
|
|
Packit |
13e616 |
if (!copy) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR, "memory allocation failed\n");
|
|
Packit |
13e616 |
return CL_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy->name = strdup(module->name);
|
|
Packit |
13e616 |
if (!copy->name) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR, "memory allocation failed\n");
|
|
Packit |
13e616 |
__free_routing_module(copy, NULL);
|
|
Packit |
13e616 |
return CL_INSUFFICIENT_MEMORY;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
copy->setup = module->setup;
|
|
Packit |
13e616 |
copy->type = module->type;
|
|
Packit |
13e616 |
copy->context = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = register_routing_engine(osm, copy);
|
|
Packit |
13e616 |
if (status != CL_SUCCESS)
|
|
Packit |
13e616 |
__free_routing_module(copy, NULL);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_status_t register_routing_engine(
|
|
Packit |
13e616 |
IN osm_opensm_t *osm,
|
|
Packit |
13e616 |
IN const routing_engine_module_t *module)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_status_t status;
|
|
Packit |
13e616 |
osm_routing_engine_type_t existing_type, new_type;
|
|
Packit |
13e616 |
const char *existing_routing_engine_type, *new_routing_engine_type;
|
|
Packit |
13e616 |
const char *existing_routing_engine_name, *new_name;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
new_type = module->type;
|
|
Packit |
13e616 |
new_name = module->name;
|
|
Packit |
13e616 |
new_routing_engine_type = routing_engine_type(new_type);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* check if another routine engine has already been registered with the same name */
|
|
Packit |
13e616 |
existing_type = osm_routing_engine_type(new_name);
|
|
Packit |
13e616 |
if (existing_type != OSM_ROUTING_ENGINE_TYPE_UNKNOWN) {
|
|
Packit |
13e616 |
existing_routing_engine_type = routing_engine_type(existing_type);
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Failed to register %s routing engine with name \'%s\': "
|
|
Packit |
13e616 |
"%s routing engine with same name was already registered with type: '%d'\n",
|
|
Packit |
13e616 |
new_routing_engine_type,
|
|
Packit |
13e616 |
new_name,
|
|
Packit |
13e616 |
existing_routing_engine_type,
|
|
Packit |
13e616 |
existing_type);
|
|
Packit |
13e616 |
return CL_DUPLICATE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
/* check if another routine engine has already been registed with the same type */
|
|
Packit |
13e616 |
existing_routing_engine_name = osm_routing_engine_type_str(new_type);
|
|
Packit |
13e616 |
if (strcmp(existing_routing_engine_name, unknown_routing_engine_name) != 0) {
|
|
Packit |
13e616 |
existing_type = new_type;
|
|
Packit |
13e616 |
existing_routing_engine_type = routing_engine_type(existing_type);
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Failed to register %s routing engine with name \'%s\': "
|
|
Packit |
13e616 |
"%s routing engine with type '%d' "
|
|
Packit |
13e616 |
"was already registered with name: \'%s\'\n",
|
|
Packit |
13e616 |
new_routing_engine_type,
|
|
Packit |
13e616 |
new_name,
|
|
Packit |
13e616 |
existing_routing_engine_type,
|
|
Packit |
13e616 |
existing_type,
|
|
Packit |
13e616 |
existing_routing_engine_name);
|
|
Packit |
13e616 |
return CL_DUPLICATE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Register %s routine engine with name: \'%s\' and type: '%d'\n",
|
|
Packit |
13e616 |
new_routing_engine_type,
|
|
Packit |
13e616 |
new_name,
|
|
Packit |
13e616 |
new_type);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_list_insert_tail(&routing_modules, module);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t _match_routing_engine_type(
|
|
Packit |
13e616 |
IN const void *const p_object, IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_routing_engine_type_t type;
|
|
Packit |
13e616 |
routing_engine_module_t *module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
type = (osm_routing_engine_type_t) context;
|
|
Packit |
13e616 |
module = (routing_engine_module_t *) p_object;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return module->type == type ? CL_SUCCESS : CL_NOT_FOUND;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
const char *osm_routing_engine_type_str(IN osm_routing_engine_type_t type)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_iterator_t iter;
|
|
Packit |
13e616 |
routing_engine_module_t *module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
iter = cl_list_find_from_head(
|
|
Packit |
13e616 |
&routing_modules, _match_routing_engine_type, (void *)type);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (iter != cl_list_end(&routing_modules)) {
|
|
Packit |
13e616 |
module = (routing_engine_module_t *) cl_list_obj(iter);
|
|
Packit |
13e616 |
return module->name;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return unknown_routing_engine_name;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static cl_status_t _match_routing_engine_str(
|
|
Packit |
13e616 |
IN const void *const p_object, IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
const char *name = (char *) context;
|
|
Packit |
13e616 |
routing_engine_module_t *module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
name = (char *) context;
|
|
Packit |
13e616 |
module = (routing_engine_module_t *) p_object;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* For legacy reasons, consider a NULL pointer and the string
|
|
Packit |
13e616 |
* "null" as the minhop routing engine.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (!name || !strcasecmp(name, "null"))
|
|
Packit |
13e616 |
name = "minhop";
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (strcasecmp(module->name, name) == 0)
|
|
Packit |
13e616 |
return CL_SUCCESS;
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
return CL_NOT_FOUND;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_routing_engine_type_t osm_routing_engine_type(IN const char *str)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_iterator_t iter;
|
|
Packit |
13e616 |
routing_engine_module_t *module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
iter = cl_list_find_from_head(
|
|
Packit |
13e616 |
&routing_modules, _match_routing_engine_str, (void *)str);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (iter != cl_list_end(&routing_modules)) {
|
|
Packit |
13e616 |
module = (routing_engine_module_t *) cl_list_obj(iter);
|
|
Packit |
13e616 |
return module->type;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return OSM_ROUTING_ENGINE_TYPE_UNKNOWN;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void append_routing_engine(osm_opensm_t *osm,
|
|
Packit |
13e616 |
struct osm_routing_engine *routing_engine)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct osm_routing_engine *r;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
routing_engine->next = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!osm->routing_engine_list) {
|
|
Packit |
13e616 |
osm->routing_engine_list = routing_engine;
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
r = osm->routing_engine_list;
|
|
Packit |
13e616 |
while (r->next)
|
|
Packit |
13e616 |
r = r->next;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
r->next = routing_engine;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static struct osm_routing_engine *setup_routing_engine(osm_opensm_t *osm,
|
|
Packit |
13e616 |
const char *name)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct osm_routing_engine *re;
|
|
Packit |
13e616 |
routing_engine_module_t *m;
|
|
Packit |
13e616 |
cl_list_iterator_t iter;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!strcmp(name, "no_fallback")) {
|
|
Packit |
13e616 |
osm->no_fallback_routing_engine = TRUE;
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (iter = cl_list_head(&routing_modules);
|
|
Packit |
13e616 |
iter != cl_list_end(&routing_modules);
|
|
Packit |
13e616 |
iter = cl_list_next(iter)) {
|
|
Packit |
13e616 |
m = (routing_engine_module_t *)cl_list_obj(iter);
|
|
Packit |
13e616 |
if (!strcmp(m->name, name)) {
|
|
Packit |
13e616 |
re = malloc(sizeof(struct osm_routing_engine));
|
|
Packit |
13e616 |
if (!re) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"memory allocation failed\n");
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
memset(re, 0, sizeof(struct osm_routing_engine));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
re->name = m->name;
|
|
Packit |
13e616 |
re->context = m->context;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"setup of routing engine \'%s\' ...\n", name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
re->type = osm_routing_engine_type(m->name);
|
|
Packit |
13e616 |
if (m->setup(re, osm)) {
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"setup of routing"
|
|
Packit |
13e616 |
" engine \'%s\' failed\n", name);
|
|
Packit |
13e616 |
free(re);
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"\'%s\' routing engine set up\n", re->name);
|
|
Packit |
13e616 |
if (re->type == OSM_ROUTING_ENGINE_TYPE_MINHOP)
|
|
Packit |
13e616 |
osm->default_routing_engine = re;
|
|
Packit |
13e616 |
return re;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"cannot find or setup routing engine \'%s\'\n", name);
|
|
Packit |
13e616 |
return NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void setup_routing_engines(osm_opensm_t *osm, const char *engine_names)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char *name, *str, *p;
|
|
Packit |
13e616 |
struct osm_routing_engine *re;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
dump_routing_engines(osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (engine_names && *engine_names) {
|
|
Packit |
13e616 |
str = strdup(engine_names);
|
|
Packit |
13e616 |
name = strtok_r(str, ", \t\n", &p);
|
|
Packit |
13e616 |
while (name && *name) {
|
|
Packit |
13e616 |
re = setup_routing_engine(osm, name);
|
|
Packit |
13e616 |
if (re)
|
|
Packit |
13e616 |
append_routing_engine(osm, re);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Failed to setup routing engine \'%s\'\n", name);
|
|
Packit |
13e616 |
name = strtok_r(NULL, ", \t\n", &p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
free(str);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (!osm->default_routing_engine)
|
|
Packit |
13e616 |
setup_routing_engine(osm, "minhop");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void dump_routing_engine(IN void *const p_object, IN void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_opensm_t *osm;
|
|
Packit |
13e616 |
routing_engine_module_t *module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm = (osm_opensm_t *) context;
|
|
Packit |
13e616 |
module = (routing_engine_module_t *) p_object;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
" name: %s - Type: %d\n",
|
|
Packit |
13e616 |
module->name, module->type);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void dump_routing_engines(IN osm_opensm_t *osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_apply_func(
|
|
Packit |
13e616 |
&routing_modules,
|
|
Packit |
13e616 |
dump_routing_engine,
|
|
Packit |
13e616 |
(void *) osm);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static const char *routing_engine_type(IN osm_routing_engine_type_t type)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
return type < OSM_ROUTING_ENGINE_TYPE_UNKNOWN ?
|
|
Packit |
13e616 |
"built-in" : "external";
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_routing_modules_construct(IN osm_opensm_t *p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
size_t i, len;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
len = sizeof(static_routing_modules) /
|
|
Packit |
13e616 |
sizeof(builtin_routing_engine_module_t);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_list_construct(&routing_modules);
|
|
Packit |
13e616 |
cl_list_init(&routing_modules, len);
|
|
Packit |
13e616 |
for (i = 0; i < len; i++) {
|
|
Packit |
13e616 |
register_builtin_routing_engine(
|
|
Packit |
13e616 |
p_osm, &(static_routing_modules[i]));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void __free_routing_module(void *p_object, void *context)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
routing_engine_module_t *p_module;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_module = (routing_engine_module_t *) p_object;
|
|
Packit |
13e616 |
if (p_module) {
|
|
Packit |
13e616 |
if (p_module->name)
|
|
Packit |
13e616 |
free(p_module->name);
|
|
Packit |
13e616 |
free(p_module);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_routing_modules_destroy(IN osm_opensm_t *p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_apply_func(&routing_modules, __free_routing_module, p_osm);
|
|
Packit |
13e616 |
cl_list_remove_all(&routing_modules);
|
|
Packit |
13e616 |
cl_list_destroy(&routing_modules);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_opensm_construct(IN osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
memset(p_osm, 0, sizeof(*p_osm));
|
|
Packit |
13e616 |
p_osm->osm_version = OSM_VERSION;
|
|
Packit |
13e616 |
osm_routing_modules_construct(p_osm);
|
|
Packit |
13e616 |
osm_subn_construct(&p_osm->subn);
|
|
Packit |
13e616 |
osm_db_construct(&p_osm->db);
|
|
Packit |
13e616 |
osm_log_construct(&p_osm->log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_opensm_construct_finish(IN osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_sm_construct(&p_osm->sm);
|
|
Packit |
13e616 |
osm_sa_construct(&p_osm->sa);
|
|
Packit |
13e616 |
osm_mad_pool_construct(&p_osm->mad_pool);
|
|
Packit |
13e616 |
p_osm->mad_pool_constructed = TRUE;
|
|
Packit |
13e616 |
osm_vl15_construct(&p_osm->vl15);
|
|
Packit |
13e616 |
p_osm->vl15_constructed = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void destroy_routing_engines(osm_opensm_t *osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct osm_routing_engine *r, *next;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
next = osm->routing_engine_list;
|
|
Packit |
13e616 |
while (next) {
|
|
Packit |
13e616 |
r = next;
|
|
Packit |
13e616 |
next = r->next;
|
|
Packit |
13e616 |
if (r != osm->default_routing_engine) {
|
|
Packit |
13e616 |
if (r->destroy)
|
|
Packit |
13e616 |
r->destroy(r->context);
|
|
Packit |
13e616 |
free(r);
|
|
Packit |
13e616 |
} else /* do not free default_routing_engine */
|
|
Packit |
13e616 |
r->next = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
osm->routing_engine_list = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
r = osm->default_routing_engine;
|
|
Packit |
13e616 |
if (r) {
|
|
Packit |
13e616 |
if (r->destroy)
|
|
Packit |
13e616 |
r->destroy(r->context);
|
|
Packit |
13e616 |
free(r);
|
|
Packit |
13e616 |
osm->default_routing_engine = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void destroy_plugins(osm_opensm_t *osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_epi_plugin_t *p;
|
|
Packit |
13e616 |
/* remove from the list, and destroy it */
|
|
Packit |
13e616 |
while (!cl_is_qlist_empty(&osm->plugin_list)){
|
|
Packit |
13e616 |
p = (osm_epi_plugin_t *)cl_qlist_remove_head(&osm->plugin_list);
|
|
Packit |
13e616 |
/* plugin is responsible for freeing its own resources */
|
|
Packit |
13e616 |
osm_epi_destroy(p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_opensm_destroy(IN osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
/* in case of shutdown through exit proc - no ^C */
|
|
Packit |
13e616 |
osm_exit_flag = TRUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* First of all, clear the is_sm bit.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_osm->sm.mad_ctrl.h_bind)
|
|
Packit |
13e616 |
osm_vendor_set_sm(p_osm->sm.mad_ctrl.h_bind, FALSE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef ENABLE_OSM_PERF_MGR
|
|
Packit |
13e616 |
/* Shutdown the PerfMgr */
|
|
Packit |
13e616 |
osm_perfmgr_shutdown(&p_osm->perfmgr);
|
|
Packit |
13e616 |
#endif /* ENABLE_OSM_PERF_MGR */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_congestion_control_shutdown(&p_osm->cc);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* shut down the SM
|
|
Packit |
13e616 |
* - make sure the SM sweeper thread exited
|
|
Packit |
13e616 |
* - unbind from QP0 messages
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
osm_sm_shutdown(&p_osm->sm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* shut down the SA
|
|
Packit |
13e616 |
* - unbind from QP1 messages
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
osm_sa_shutdown(&p_osm->sa);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* cleanup all messages on VL15 fifo that were not sent yet */
|
|
Packit |
13e616 |
osm_vl15_shutdown(&p_osm->vl15, &p_osm->mad_pool);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* shut down the dispatcher - so no new messages cross */
|
|
Packit |
13e616 |
cl_disp_shutdown(&p_osm->disp);
|
|
Packit |
13e616 |
if (p_osm->sa_set_disp_initialized)
|
|
Packit |
13e616 |
cl_disp_shutdown(&p_osm->sa_set_disp);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* dump SA DB */
|
|
Packit |
13e616 |
if ((p_osm->sm.p_subn->sm_state == IB_SMINFO_STATE_MASTER) &&
|
|
Packit |
13e616 |
p_osm->subn.opt.sa_db_dump)
|
|
Packit |
13e616 |
osm_sa_db_file_dump(p_osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* do the destruction in reverse order as init */
|
|
Packit |
13e616 |
destroy_routing_engines(p_osm);
|
|
Packit |
13e616 |
destroy_plugins(p_osm);
|
|
Packit |
13e616 |
osm_sa_destroy(&p_osm->sa);
|
|
Packit |
13e616 |
osm_sm_destroy(&p_osm->sm);
|
|
Packit |
13e616 |
osm_routing_modules_destroy(p_osm);
|
|
Packit |
13e616 |
#ifdef ENABLE_OSM_PERF_MGR
|
|
Packit |
13e616 |
osm_perfmgr_destroy(&p_osm->perfmgr);
|
|
Packit |
13e616 |
#endif /* ENABLE_OSM_PERF_MGR */
|
|
Packit |
13e616 |
osm_congestion_control_destroy(&p_osm->cc);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_opensm_destroy_finish(IN osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_db_destroy(&p_osm->db);
|
|
Packit |
13e616 |
if (p_osm->vl15_constructed && p_osm->mad_pool_constructed)
|
|
Packit |
13e616 |
osm_vl15_destroy(&p_osm->vl15, &p_osm->mad_pool);
|
|
Packit |
13e616 |
if (p_osm->mad_pool_constructed)
|
|
Packit |
13e616 |
osm_mad_pool_destroy(&p_osm->mad_pool);
|
|
Packit |
13e616 |
p_osm->vl15_constructed = FALSE;
|
|
Packit |
13e616 |
p_osm->mad_pool_constructed = FALSE;
|
|
Packit |
13e616 |
osm_vendor_delete(&p_osm->p_vendor);
|
|
Packit |
13e616 |
osm_subn_destroy(&p_osm->subn);
|
|
Packit |
13e616 |
cl_disp_destroy(&p_osm->disp);
|
|
Packit |
13e616 |
if (p_osm->sa_set_disp_initialized)
|
|
Packit |
13e616 |
cl_disp_destroy(&p_osm->sa_set_disp);
|
|
Packit |
13e616 |
#ifdef HAVE_LIBPTHREAD
|
|
Packit |
13e616 |
pthread_cond_destroy(&p_osm->stats.cond);
|
|
Packit |
13e616 |
pthread_mutex_destroy(&p_osm->stats.mutex);
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
cl_event_destroy(&p_osm->stats.event);
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
if (p_osm->node_name_map)
|
|
Packit |
13e616 |
close_node_name_map(p_osm->node_name_map);
|
|
Packit |
13e616 |
cl_plock_destroy(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_log_destroy(&p_osm->log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void load_plugins(osm_opensm_t *osm, const char *plugin_names)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_epi_plugin_t *epi;
|
|
Packit |
13e616 |
char *p_names, *name, *p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_names = strdup(plugin_names);
|
|
Packit |
13e616 |
name = strtok_r(p_names, ", \t\n", &p);
|
|
Packit |
13e616 |
while (name && *name) {
|
|
Packit |
13e616 |
epi = osm_epi_construct(osm, name);
|
|
Packit |
13e616 |
if (!epi)
|
|
Packit |
13e616 |
osm_log_v2(&osm->log, OSM_LOG_ERROR, FILE_ID,
|
|
Packit |
13e616 |
"ERR 1000: cannot load plugin \'%s\'\n",
|
|
Packit |
13e616 |
name);
|
|
Packit |
13e616 |
else
|
|
Packit |
13e616 |
cl_qlist_insert_tail(&osm->plugin_list, &epi->list);
|
|
Packit |
13e616 |
name = strtok_r(NULL, " \t\n", &p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
free(p_names);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_opensm_init(IN osm_opensm_t * p_osm,
|
|
Packit |
13e616 |
IN const osm_subn_opt_t * p_opt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Can't use log macros here, since we're initializing the log */
|
|
Packit |
13e616 |
osm_opensm_construct(p_osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_opt->daemon)
|
|
Packit |
13e616 |
p_osm->log.daemon = 1;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_log_init_v2(&p_osm->log, p_opt->force_log_flush,
|
|
Packit |
13e616 |
p_opt->log_flags, p_opt->log_file,
|
|
Packit |
13e616 |
p_opt->log_max_size, p_opt->accum_log_file);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
p_osm->log.log_prefix = p_opt->log_prefix;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* If there is a log level defined - add the OSM_VERSION to it */
|
|
Packit |
13e616 |
osm_log_v2(&p_osm->log,
|
|
Packit |
13e616 |
osm_log_get_level(&p_osm->log) & (OSM_LOG_SYS ^ 0xFF),
|
|
Packit |
13e616 |
FILE_ID, "%s\n", p_osm->osm_version);
|
|
Packit |
13e616 |
/* Write the OSM_VERSION to the SYS_LOG */
|
|
Packit |
13e616 |
osm_log_v2(&p_osm->log, OSM_LOG_SYS, FILE_ID, "%s\n", p_osm->osm_version); /* Format Waived */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_FUNCS, "[\n"); /* Format Waived */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_plock_init(&p_osm->lock);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef HAVE_LIBPTHREAD
|
|
Packit |
13e616 |
pthread_mutex_init(&p_osm->stats.mutex, NULL);
|
|
Packit |
13e616 |
pthread_cond_init(&p_osm->stats.cond, NULL);
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
status = cl_event_init(&p_osm->stats.event, FALSE);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_opt->single_thread) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_INFO,
|
|
Packit |
13e616 |
"Forcing single threaded dispatcher\n");
|
|
Packit |
13e616 |
status = cl_disp_init(&p_osm->disp, 1, "opensm");
|
|
Packit |
13e616 |
} else {
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Normal behavior is to initialize the dispatcher with
|
|
Packit |
13e616 |
* one thread per CPU, as specified by a thread count of '0'.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
status = cl_disp_init(&p_osm->disp, 0, "opensm");
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Unless OpenSM runs in single threaded mode, we create new single
|
|
Packit |
13e616 |
* threaded dispatcher for SA Set and Delete requets.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
p_osm->sa_set_disp_initialized = FALSE;
|
|
Packit |
13e616 |
if (!p_opt->single_thread) {
|
|
Packit |
13e616 |
status = cl_disp_init(&p_osm->sa_set_disp, 1, "subnadmin_set");
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
p_osm->sa_set_disp_initialized = TRUE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* the DB is in use by subn so init before */
|
|
Packit |
13e616 |
status = osm_db_init(&p_osm->db, &p_osm->log);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_subn_init(&p_osm->subn, p_osm, p_opt);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_osm->p_vendor =
|
|
Packit |
13e616 |
osm_vendor_new(&p_osm->log, p_opt->transaction_timeout);
|
|
Packit |
13e616 |
if (p_osm->p_vendor == NULL)
|
|
Packit |
13e616 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_FUNCS, "]\n"); /* Format Waived */
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_opensm_init_finish(IN osm_opensm_t * p_osm,
|
|
Packit |
13e616 |
IN const osm_subn_opt_t * p_opt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_opensm_construct_finish(p_osm);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_osm->subn.sm_port_guid = p_opt->guid;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_mad_pool_init(&p_osm->mad_pool);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_vl15_init(&p_osm->vl15, p_osm->p_vendor,
|
|
Packit |
13e616 |
&p_osm->log, &p_osm->stats, &p_osm->subn,
|
|
Packit |
13e616 |
p_opt->max_wire_smps, p_opt->max_wire_smps2,
|
|
Packit |
13e616 |
p_opt->max_smps_timeout);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sm_init(&p_osm->sm, &p_osm->subn, &p_osm->db,
|
|
Packit |
13e616 |
p_osm->p_vendor, &p_osm->mad_pool, &p_osm->vl15,
|
|
Packit |
13e616 |
&p_osm->log, &p_osm->stats, &p_osm->disp,
|
|
Packit |
13e616 |
&p_osm->lock);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sa_init(&p_osm->sm, &p_osm->sa, &p_osm->subn,
|
|
Packit |
13e616 |
p_osm->p_vendor, &p_osm->mad_pool, &p_osm->log,
|
|
Packit |
13e616 |
&p_osm->stats, &p_osm->disp,
|
|
Packit |
13e616 |
p_opt->single_thread ? NULL : &p_osm->sa_set_disp,
|
|
Packit |
13e616 |
&p_osm->lock);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qlist_init(&p_osm->plugin_list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_opt->event_plugin_name)
|
|
Packit |
13e616 |
load_plugins(p_osm, p_opt->event_plugin_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef ENABLE_OSM_PERF_MGR
|
|
Packit |
13e616 |
status = osm_perfmgr_init(&p_osm->perfmgr, p_osm, p_opt);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
#endif /* ENABLE_OSM_PERF_MGR */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_congestion_control_init(&p_osm->cc,
|
|
Packit |
13e616 |
p_osm, p_opt);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_osm->no_fallback_routing_engine = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
setup_routing_engines(p_osm, p_opt->routing_engine_names);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_osm->routing_engine_used = NULL;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_osm->node_name_map = open_node_name_map(p_opt->node_name_map_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_FUNCS, "]\n"); /* Format Waived */
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_opensm_bind(IN osm_opensm_t * p_osm, IN ib_net64_t guid)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(&p_osm->log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sm_bind(&p_osm->sm, guid);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sa_bind(&p_osm->sa, guid);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifdef ENABLE_OSM_PERF_MGR
|
|
Packit |
13e616 |
status = osm_perfmgr_bind(&p_osm->perfmgr, guid);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
#endif /* ENABLE_OSM_PERF_MGR */
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_congestion_control_bind(&p_osm->cc, guid);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* setting IS_SM in capability mask */
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_INFO, "Setting IS_SM on port 0x%016" PRIx64 "\n",
|
|
Packit |
13e616 |
cl_ntoh64(guid));
|
|
Packit |
13e616 |
osm_vendor_set_sm(p_osm->sm.mad_ctrl.h_bind, TRUE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(&p_osm->log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_opensm_report_event(osm_opensm_t *osm, osm_epi_event_id_t event_id,
|
|
Packit |
13e616 |
void *event_data)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_item_t *item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (item = cl_qlist_head(&osm->plugin_list);
|
|
Packit |
13e616 |
!osm_exit_flag && item != cl_qlist_end(&osm->plugin_list);
|
|
Packit |
13e616 |
item = cl_qlist_next(item)) {
|
|
Packit |
13e616 |
osm_epi_plugin_t *p = (osm_epi_plugin_t *)item;
|
|
Packit |
13e616 |
if (p->impl->report)
|
|
Packit |
13e616 |
p->impl->report(p->plugin_data, event_id, event_data);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|