|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2002-2014 Mellanox Technologies LTD. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
|
|
Packit |
13e616 |
* Copyright (c) 2008 Xsigo Systems Inc. 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_sa_t.
|
|
Packit |
13e616 |
* This object represents the Subnet Administration 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 <string.h>
|
|
Packit |
13e616 |
#include <ctype.h>
|
|
Packit |
13e616 |
#include <errno.h>
|
|
Packit |
13e616 |
#include <stdlib.h>
|
|
Packit |
13e616 |
#include <unistd.h>
|
|
Packit |
13e616 |
#include <sys/types.h>
|
|
Packit |
13e616 |
#include <sys/stat.h>
|
|
Packit |
13e616 |
#include <complib/cl_qmap.h>
|
|
Packit |
13e616 |
#include <complib/cl_passivelock.h>
|
|
Packit |
13e616 |
#include <complib/cl_debug.h>
|
|
Packit |
13e616 |
#include <iba/ib_types.h>
|
|
Packit |
13e616 |
#include <opensm/osm_file_ids.h>
|
|
Packit |
13e616 |
#define FILE_ID OSM_FILE_SA_C
|
|
Packit |
13e616 |
#include <opensm/osm_sa.h>
|
|
Packit |
13e616 |
#include <opensm/osm_madw.h>
|
|
Packit |
13e616 |
#include <opensm/osm_log.h>
|
|
Packit |
13e616 |
#include <opensm/osm_subnet.h>
|
|
Packit |
13e616 |
#include <opensm/osm_mad_pool.h>
|
|
Packit |
13e616 |
#include <opensm/osm_msgdef.h>
|
|
Packit |
13e616 |
#include <opensm/osm_opensm.h>
|
|
Packit |
13e616 |
#include <opensm/osm_multicast.h>
|
|
Packit |
13e616 |
#include <opensm/osm_inform.h>
|
|
Packit |
13e616 |
#include <opensm/osm_service.h>
|
|
Packit |
13e616 |
#include <opensm/osm_guid.h>
|
|
Packit |
13e616 |
#include <opensm/osm_helper.h>
|
|
Packit |
13e616 |
#include <vendor/osm_vendor_api.h>
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#define OSM_SA_INITIAL_TID_VALUE 0xabc
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
extern void osm_cpi_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_gir_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_infr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_infir_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_lftr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_lr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_mcmr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_mftr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_mpr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_nr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_pr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_pkey_rec_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_pir_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_sr_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_slvl_rec_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_smir_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_sir_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_vlarb_rec_rcv_process(IN void *context, IN void *data);
|
|
Packit |
13e616 |
extern void osm_sr_rcv_lease_cb(IN void *context);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_construct(IN osm_sa_t * p_sa)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
memset(p_sa, 0, sizeof(*p_sa));
|
|
Packit |
13e616 |
p_sa->state = OSM_SA_STATE_INIT;
|
|
Packit |
13e616 |
p_sa->sa_trans_id = OSM_SA_INITIAL_TID_VALUE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_timer_construct(&p_sa->sr_timer);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_shutdown(IN osm_sa_t * p_sa)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_sa->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_timer_stop(&p_sa->sr_timer);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* unbind from the mad service */
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_unbind(&p_sa->mad_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* remove any registered dispatcher message */
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->nr_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->pir_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->gir_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->lr_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->pr_disp_h);
|
|
Packit |
13e616 |
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->mpr_disp_h);
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->smir_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->mcmr_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->sr_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->infr_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->infir_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->vlarb_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->slvl_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->pkey_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->lft_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->sir_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->mft_disp_h);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_sa->p_set_disp) {
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->mcmr_set_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->infr_set_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->sr_set_disp_h);
|
|
Packit |
13e616 |
cl_disp_unregister(p_sa->gir_set_disp_h);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_sa_mad_ctrl_destroy(&p_sa->mad_ctrl);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_sa->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_destroy(IN osm_sa_t * p_sa)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_sa->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->state = OSM_SA_STATE_INIT;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_timer_destroy(&p_sa->sr_timer);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_sa->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
|
|
Packit |
13e616 |
IN osm_subn_t * p_subn, IN osm_vendor_t * p_vendor,
|
|
Packit |
13e616 |
IN osm_mad_pool_t * p_mad_pool,
|
|
Packit |
13e616 |
IN osm_log_t * p_log, IN osm_stats_t * p_stats,
|
|
Packit |
13e616 |
IN cl_dispatcher_t * p_disp,
|
|
Packit |
13e616 |
IN cl_dispatcher_t * p_set_disp,
|
|
Packit |
13e616 |
IN cl_plock_t * p_lock)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->sm = p_sm;
|
|
Packit |
13e616 |
p_sa->p_subn = p_subn;
|
|
Packit |
13e616 |
p_sa->p_vendor = p_vendor;
|
|
Packit |
13e616 |
p_sa->p_mad_pool = p_mad_pool;
|
|
Packit |
13e616 |
p_sa->p_log = p_log;
|
|
Packit |
13e616 |
p_sa->p_disp = p_disp;
|
|
Packit |
13e616 |
p_sa->p_set_disp = p_set_disp;
|
|
Packit |
13e616 |
p_sa->p_lock = p_lock;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->state = OSM_SA_STATE_READY;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sa_mad_ctrl_init(&p_sa->mad_ctrl, p_sa, p_sa->p_mad_pool,
|
|
Packit |
13e616 |
p_sa->p_vendor, p_subn, p_log, p_stats,
|
|
Packit |
13e616 |
p_disp, p_set_disp);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = cl_timer_init(&p_sa->sr_timer, osm_sr_rcv_lease_cb, p_sa);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = IB_INSUFFICIENT_RESOURCES;
|
|
Packit |
13e616 |
p_sa->cpi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_CLASS_PORT_INFO,
|
|
Packit |
13e616 |
osm_cpi_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->cpi_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->nr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_RECORD,
|
|
Packit |
13e616 |
osm_nr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->nr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->pir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PORTINFO_RECORD,
|
|
Packit |
13e616 |
osm_pir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->pir_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->gir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_GUIDINFO_RECORD,
|
|
Packit |
13e616 |
osm_gir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->gir_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->lr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LINK_RECORD,
|
|
Packit |
13e616 |
osm_lr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->lr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->pr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PATH_RECORD,
|
|
Packit |
13e616 |
osm_pr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->pr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
|
|
Packit |
13e616 |
p_sa->mpr_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_MULTIPATH_RECORD,
|
|
Packit |
13e616 |
osm_mpr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->mpr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->smir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SMINFO_RECORD,
|
|
Packit |
13e616 |
osm_smir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->smir_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->mcmr_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_MCMEMBER_RECORD,
|
|
Packit |
13e616 |
osm_mcmr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->mcmr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->sr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SERVICE_RECORD,
|
|
Packit |
13e616 |
osm_sr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->sr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->infr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO,
|
|
Packit |
13e616 |
osm_infr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->infr_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->infir_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO_RECORD,
|
|
Packit |
13e616 |
osm_infir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->infir_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->vlarb_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_VL_ARB_RECORD,
|
|
Packit |
13e616 |
osm_vlarb_rec_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->vlarb_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->slvl_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_SLVL_TBL_RECORD,
|
|
Packit |
13e616 |
osm_slvl_rec_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->slvl_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->pkey_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_PKEY_TBL_RECORD,
|
|
Packit |
13e616 |
osm_pkey_rec_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->pkey_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->lft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LFT_RECORD,
|
|
Packit |
13e616 |
osm_lftr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->lft_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->sir_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_disp, OSM_MSG_MAD_SWITCH_INFO_RECORD,
|
|
Packit |
13e616 |
osm_sir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->sir_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->mft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_MFT_RECORD,
|
|
Packit |
13e616 |
osm_mftr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->mft_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* When p_set_disp is defined, it means that we use different dispatcher
|
|
Packit |
13e616 |
* for SA Set requests, and we need to register handlers for it.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_set_disp) {
|
|
Packit |
13e616 |
p_sa->gir_set_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_set_disp, OSM_MSG_MAD_GUIDINFO_RECORD,
|
|
Packit |
13e616 |
osm_gir_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->gir_set_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->mcmr_set_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_set_disp, OSM_MSG_MAD_MCMEMBER_RECORD,
|
|
Packit |
13e616 |
osm_mcmr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->mcmr_set_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->sr_set_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_set_disp, OSM_MSG_MAD_SERVICE_RECORD,
|
|
Packit |
13e616 |
osm_sr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->sr_set_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_sa->infr_set_disp_h =
|
|
Packit |
13e616 |
cl_disp_register(p_set_disp, OSM_MSG_MAD_INFORM_INFO,
|
|
Packit |
13e616 |
osm_infr_rcv_process, p_sa);
|
|
Packit |
13e616 |
if (p_sa->infr_set_disp_h == CL_DISP_INVALID_HANDLE)
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = IB_SUCCESS;
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_bind(IN osm_sa_t * p_sa, IN ib_net64_t port_guid)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(p_sa->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = osm_sa_mad_ctrl_bind(&p_sa->mad_ctrl, port_guid);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (status != IB_SUCCESS) {
|
|
Packit |
13e616 |
OSM_LOG(p_sa->p_log, OSM_LOG_ERROR, "ERR 4C03: "
|
|
Packit |
13e616 |
"SA MAD Controller bind failed (%s)\n",
|
|
Packit |
13e616 |
ib_get_err_str(status));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_EXIT(p_sa->p_log);
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
ib_api_status_t osm_sa_send(osm_sa_t *sa, IN osm_madw_t * p_madw,
|
|
Packit |
13e616 |
IN boolean_t resp_expected)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_api_status_t status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_atomic_inc(&sa->p_subn->p_osm->stats.sa_mads_sent);
|
|
Packit |
13e616 |
status = osm_vendor_send(p_madw->h_bind, p_madw, resp_expected);
|
|
Packit |
13e616 |
if (status != IB_SUCCESS) {
|
|
Packit |
13e616 |
cl_atomic_dec(&sa->p_subn->p_osm->stats.sa_mads_sent);
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C04: "
|
|
Packit |
13e616 |
"osm_vendor_send failed, status = %s\n",
|
|
Packit |
13e616 |
ib_get_err_str(status));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_send_error(IN osm_sa_t * sa, IN const osm_madw_t * p_madw,
|
|
Packit |
13e616 |
IN ib_net16_t sa_status)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_madw_t *p_resp_madw;
|
|
Packit |
13e616 |
ib_sa_mad_t *p_resp_sa_mad;
|
|
Packit |
13e616 |
ib_sa_mad_t *p_sa_mad;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG_ENTER(sa->p_log);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* avoid races - if we are exiting - exit */
|
|
Packit |
13e616 |
if (osm_exit_flag) {
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"Ignoring requested send after exit\n");
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_resp_madw = osm_mad_pool_get(sa->p_mad_pool,
|
|
Packit |
13e616 |
p_madw->h_bind, MAD_BLOCK_SIZE,
|
|
Packit |
13e616 |
&p_madw->mad_addr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_resp_madw == NULL) {
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C07: "
|
|
Packit |
13e616 |
"Unable to acquire response MAD\n");
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
|
|
Packit |
13e616 |
p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Copy the MAD header back into the response mad */
|
|
Packit |
13e616 |
*p_resp_sa_mad = *p_sa_mad;
|
|
Packit |
13e616 |
p_resp_sa_mad->status = sa_status;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_resp_sa_mad->method == IB_MAD_METHOD_SET)
|
|
Packit |
13e616 |
p_resp_sa_mad->method = IB_MAD_METHOD_GET;
|
|
Packit |
13e616 |
else if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE)
|
|
Packit |
13e616 |
p_resp_sa_mad->attr_offset = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
p_resp_sa_mad->sm_key = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* o15-0.2.7 - The PathRecord Attribute ID shall be used in
|
|
Packit |
13e616 |
* the response (to a SubnAdmGetMulti(MultiPathRecord)
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_resp_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD)
|
|
Packit |
13e616 |
p_resp_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES))
|
|
Packit |
13e616 |
osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_sa_send(sa, p_resp_madw, FALSE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
OSM_LOG_EXIT(sa->p_log);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
|
|
Packit |
13e616 |
cl_qlist_t *list)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
cl_list_item_t *item;
|
|
Packit |
13e616 |
osm_madw_t *resp_madw;
|
|
Packit |
13e616 |
ib_sa_mad_t *sa_mad, *resp_sa_mad;
|
|
Packit |
13e616 |
unsigned num_rec, i;
|
|
Packit |
13e616 |
#ifndef VENDOR_RMPP_SUPPORT
|
|
Packit |
13e616 |
unsigned trim_num_rec;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
unsigned char *p;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
sa_mad = osm_madw_get_sa_mad_ptr(madw);
|
|
Packit |
13e616 |
num_rec = cl_qlist_count(list);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* C15-0.1.30:
|
|
Packit |
13e616 |
* If we do a SubnAdmGet and got more than one record it is an error!
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (sa_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C05: "
|
|
Packit |
13e616 |
"Got %u records for SubnAdmGet(%s) comp_mask 0x%016" PRIx64
|
|
Packit |
13e616 |
" from requester LID %u\n",
|
|
Packit |
13e616 |
num_rec, ib_get_sa_attr_str(sa_mad->attr_id),
|
|
Packit |
13e616 |
cl_ntoh64(sa_mad->comp_mask),
|
|
Packit |
13e616 |
cl_ntoh16(madw->mad_addr.dest_lid));
|
|
Packit |
13e616 |
osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifndef VENDOR_RMPP_SUPPORT
|
|
Packit |
13e616 |
trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / attr_size;
|
|
Packit |
13e616 |
if (trim_num_rec < num_rec) {
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Number of records:%u trimmed to:%u to fit in one MAD\n",
|
|
Packit |
13e616 |
num_rec, trim_num_rec);
|
|
Packit |
13e616 |
num_rec = trim_num_rec;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (sa_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
|
|
Packit |
13e616 |
osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RECORDS);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* Get a MAD to reply. Address of Mad is in the received mad_wrapper
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
resp_madw = osm_mad_pool_get(sa->p_mad_pool, madw->h_bind,
|
|
Packit |
13e616 |
num_rec * attr_size + IB_SA_MAD_HDR_SIZE,
|
|
Packit |
13e616 |
&madw->mad_addr);
|
|
Packit |
13e616 |
if (!resp_madw) {
|
|
Packit |
13e616 |
OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C06: "
|
|
Packit |
13e616 |
"osm_mad_pool_get failed\n");
|
|
Packit |
13e616 |
osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RESOURCES);
|
|
Packit |
13e616 |
goto Exit;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
resp_sa_mad = osm_madw_get_sa_mad_ptr(resp_madw);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
Copy the MAD header back into the response mad.
|
|
Packit |
13e616 |
Set the 'R' bit and the payload length,
|
|
Packit |
13e616 |
Then copy all records from the list into the response payload.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memcpy(resp_sa_mad, sa_mad, IB_SA_MAD_HDR_SIZE);
|
|
Packit |
13e616 |
if (resp_sa_mad->method == IB_MAD_METHOD_SET)
|
|
Packit |
13e616 |
resp_sa_mad->method = IB_MAD_METHOD_GET;
|
|
Packit |
13e616 |
resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
|
|
Packit |
13e616 |
/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
|
|
Packit |
13e616 |
resp_sa_mad->sm_key = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* Fill in the offset (paylen will be done by the rmpp SAR) */
|
|
Packit |
13e616 |
resp_sa_mad->attr_offset = num_rec ? ib_get_attr_offset(attr_size) : 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p = ib_sa_mad_get_payload_ptr(resp_sa_mad);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#ifndef VENDOR_RMPP_SUPPORT
|
|
Packit |
13e616 |
/* we support only one packet RMPP - so we will set the first and
|
|
Packit |
13e616 |
last flags for gettable */
|
|
Packit |
13e616 |
if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
|
|
Packit |
13e616 |
resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
|
|
Packit |
13e616 |
resp_sa_mad->rmpp_flags =
|
|
Packit |
13e616 |
IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
|
|
Packit |
13e616 |
IB_RMPP_FLAG_ACTIVE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
#else
|
|
Packit |
13e616 |
/* forcefully define the packet as RMPP one */
|
|
Packit |
13e616 |
if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
|
|
Packit |
13e616 |
resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
|
|
Packit |
13e616 |
#endif
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (i = 0; i < num_rec; i++) {
|
|
Packit |
13e616 |
item = cl_qlist_remove_head(list);
|
|
Packit |
13e616 |
memcpy(p, ((osm_sa_item_t *)item)->resp.data, attr_size);
|
|
Packit |
13e616 |
p += attr_size;
|
|
Packit |
13e616 |
free(item);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_dump_sa_mad_v2(sa->p_log, resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
|
|
Packit |
13e616 |
osm_sa_send(sa, resp_madw, FALSE);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
Exit:
|
|
Packit |
13e616 |
/* need to set the mem free ... */
|
|
Packit |
13e616 |
item = cl_qlist_remove_head(list);
|
|
Packit |
13e616 |
while (item != cl_qlist_end(list)) {
|
|
Packit |
13e616 |
free(item);
|
|
Packit |
13e616 |
item = cl_qlist_remove_head(list);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* SA DB Dumper
|
|
Packit |
13e616 |
*
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
struct opensm_dump_context {
|
|
Packit |
13e616 |
osm_opensm_t *p_osm;
|
|
Packit |
13e616 |
FILE *file;
|
|
Packit |
13e616 |
};
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int
|
|
Packit |
13e616 |
opensm_dump_to_file(osm_opensm_t * p_osm, const char *file_name,
|
|
Packit |
13e616 |
void (*dump_func) (osm_opensm_t * p_osm, FILE * file))
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char path[1024];
|
|
Packit |
13e616 |
char path_tmp[1032];
|
|
Packit |
13e616 |
FILE *file;
|
|
Packit |
13e616 |
int fd, status = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
snprintf(path, sizeof(path), "%s/%s",
|
|
Packit |
13e616 |
p_osm->subn.opt.dump_files_dir, file_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
snprintf(path_tmp, sizeof(path_tmp), "%s.tmp", path);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
file = fopen(path_tmp, "w");
|
|
Packit |
13e616 |
if (!file) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C01: "
|
|
Packit |
13e616 |
"cannot open file \'%s\': %s\n",
|
|
Packit |
13e616 |
path_tmp, strerror(errno));
|
|
Packit |
13e616 |
return -1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (chmod(path_tmp, S_IRUSR | S_IWUSR)) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0C: "
|
|
Packit |
13e616 |
"cannot change access permissions of file "
|
|
Packit |
13e616 |
"\'%s\' : %s\n",
|
|
Packit |
13e616 |
path_tmp, strerror(errno));
|
|
Packit |
13e616 |
fclose(file);
|
|
Packit |
13e616 |
return -1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
dump_func(p_osm, file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_osm->subn.opt.fsync_high_avail_files) {
|
|
Packit |
13e616 |
if (fflush(file) == 0) {
|
|
Packit |
13e616 |
fd = fileno(file);
|
|
Packit |
13e616 |
if (fd != -1) {
|
|
Packit |
13e616 |
if (fsync(fd) == -1)
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"ERR 4C08: fsync() failed (%s) for %s\n",
|
|
Packit |
13e616 |
strerror(errno), path_tmp);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C09: "
|
|
Packit |
13e616 |
"fileno() failed for %s\n", path_tmp);
|
|
Packit |
13e616 |
} else
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0A: "
|
|
Packit |
13e616 |
"fflush() failed (%s) for %s\n",
|
|
Packit |
13e616 |
strerror(errno), path_tmp);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fclose(file);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
status = rename(path_tmp, path);
|
|
Packit |
13e616 |
if (status) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0B: "
|
|
Packit |
13e616 |
"Failed to rename file:%s (err:%s)\n",
|
|
Packit |
13e616 |
path_tmp, strerror(errno));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return status;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void mcast_mgr_dump_one_port(cl_map_item_t * p_map_item, void *cxt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FILE *file = ((struct opensm_dump_context *)cxt)->file;
|
|
Packit |
13e616 |
osm_mcm_alias_guid_t *p_mcm_alias_guid = (osm_mcm_alias_guid_t *) p_map_item;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fprintf(file, "mcm_port: "
|
|
Packit |
13e616 |
"port_gid=0x%016" PRIx64 ":0x%016" PRIx64 " "
|
|
Packit |
13e616 |
"scope_state=0x%02x proxy_join=0x%x" "\n\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_mcm_alias_guid->port_gid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_mcm_alias_guid->port_gid.unicast.interface_id),
|
|
Packit |
13e616 |
p_mcm_alias_guid->scope_state, p_mcm_alias_guid->proxy_join);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_dump_one_mgrp(osm_mgrp_t *p_mgrp, void *cxt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct opensm_dump_context dump_context;
|
|
Packit |
13e616 |
osm_opensm_t *p_osm = ((struct opensm_dump_context *)cxt)->p_osm;
|
|
Packit |
13e616 |
FILE *file = ((struct opensm_dump_context *)cxt)->file;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fprintf(file, "MC Group 0x%04x %s:"
|
|
Packit |
13e616 |
" mgid=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" port_gid=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" qkey=0x%08x mlid=0x%04x mtu=0x%02x tclass=0x%02x"
|
|
Packit |
13e616 |
" pkey=0x%04x rate=0x%02x pkt_life=0x%02x sl_flow_hop=0x%08x"
|
|
Packit |
13e616 |
" scope_state=0x%02x proxy_join=0x%x" "\n\n",
|
|
Packit |
13e616 |
cl_ntoh16(p_mgrp->mlid),
|
|
Packit |
13e616 |
p_mgrp->well_known ? " (well known)" : "",
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id),
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.interface_id),
|
|
Packit |
13e616 |
cl_ntoh32(p_mgrp->mcmember_rec.qkey),
|
|
Packit |
13e616 |
cl_ntoh16(p_mgrp->mcmember_rec.mlid),
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.mtu,
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.tclass,
|
|
Packit |
13e616 |
cl_ntoh16(p_mgrp->mcmember_rec.pkey),
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.rate,
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.pkt_life,
|
|
Packit |
13e616 |
cl_ntoh32(p_mgrp->mcmember_rec.sl_flow_hop),
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.scope_state,
|
|
Packit |
13e616 |
p_mgrp->mcmember_rec.proxy_join);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
dump_context.p_osm = p_osm;
|
|
Packit |
13e616 |
dump_context.file = file;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_qmap_apply_func(&p_mgrp->mcm_alias_port_tbl,
|
|
Packit |
13e616 |
mcast_mgr_dump_one_port, &dump_context);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_dump_one_inform(cl_list_item_t * p_list_item, void *cxt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FILE *file = ((struct opensm_dump_context *)cxt)->file;
|
|
Packit |
13e616 |
osm_infr_t *p_infr = (osm_infr_t *) p_list_item;
|
|
Packit |
13e616 |
ib_inform_info_record_t *p_iir = &p_infr->inform_record;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fprintf(file, "InformInfo Record:"
|
|
Packit |
13e616 |
" subscriber_gid=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" subscriber_enum=0x%x"
|
|
Packit |
13e616 |
" InformInfo:"
|
|
Packit |
13e616 |
" gid=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" lid_range_begin=0x%x"
|
|
Packit |
13e616 |
" lid_range_end=0x%x"
|
|
Packit |
13e616 |
" is_generic=0x%x"
|
|
Packit |
13e616 |
" subscribe=0x%x"
|
|
Packit |
13e616 |
" trap_type=0x%x"
|
|
Packit |
13e616 |
" trap_num=0x%x"
|
|
Packit |
13e616 |
" qpn_resp_time_val=0x%x"
|
|
Packit |
13e616 |
" node_type=0x%06x"
|
|
Packit |
13e616 |
" rep_addr: lid=0x%04x path_bits=0x%02x static_rate=0x%02x"
|
|
Packit |
13e616 |
" remote_qp=0x%08x remote_qkey=0x%08x pkey_ix=0x%04x sl=0x%02x"
|
|
Packit |
13e616 |
"\n\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_iir->subscriber_gid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_iir->subscriber_gid.unicast.interface_id),
|
|
Packit |
13e616 |
cl_ntoh16(p_iir->subscriber_enum),
|
|
Packit |
13e616 |
cl_ntoh64(p_iir->inform_info.gid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_iir->inform_info.gid.unicast.interface_id),
|
|
Packit |
13e616 |
cl_ntoh16(p_iir->inform_info.lid_range_begin),
|
|
Packit |
13e616 |
cl_ntoh16(p_iir->inform_info.lid_range_end),
|
|
Packit |
13e616 |
p_iir->inform_info.is_generic,
|
|
Packit |
13e616 |
p_iir->inform_info.subscribe,
|
|
Packit |
13e616 |
cl_ntoh16(p_iir->inform_info.trap_type),
|
|
Packit |
13e616 |
cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num),
|
|
Packit |
13e616 |
cl_ntoh32(p_iir->inform_info.g_or_v.generic.qpn_resp_time_val),
|
|
Packit |
13e616 |
cl_ntoh32(ib_inform_info_get_prod_type(&p_iir->inform_info)),
|
|
Packit |
13e616 |
cl_ntoh16(p_infr->report_addr.dest_lid),
|
|
Packit |
13e616 |
p_infr->report_addr.path_bits,
|
|
Packit |
13e616 |
p_infr->report_addr.static_rate,
|
|
Packit |
13e616 |
cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qp),
|
|
Packit |
13e616 |
cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qkey),
|
|
Packit |
13e616 |
p_infr->report_addr.addr_type.gsi.pkey_ix,
|
|
Packit |
13e616 |
p_infr->report_addr.addr_type.gsi.service_level);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_dump_one_service(cl_list_item_t * p_list_item, void *cxt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FILE *file = ((struct opensm_dump_context *)cxt)->file;
|
|
Packit |
13e616 |
osm_svcr_t *p_svcr = (osm_svcr_t *) p_list_item;
|
|
Packit |
13e616 |
ib_service_record_t *p_sr = &p_svcr->service_record;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
fprintf(file, "Service Record: id=0x%016" PRIx64
|
|
Packit |
13e616 |
" gid=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" pkey=0x%x"
|
|
Packit |
13e616 |
" lease=0x%x"
|
|
Packit |
13e616 |
" key=0x%02x%02x%02x%02x%02x%02x%02x%02x"
|
|
Packit |
13e616 |
":0x%02x%02x%02x%02x%02x%02x%02x%02x"
|
|
Packit |
13e616 |
" name=\'%s\'"
|
|
Packit |
13e616 |
" data8=0x%02x%02x%02x%02x%02x%02x%02x%02x"
|
|
Packit |
13e616 |
":0x%02x%02x%02x%02x%02x%02x%02x%02x"
|
|
Packit |
13e616 |
" data16=0x%04x%04x%04x%04x:0x%04x%04x%04x%04x"
|
|
Packit |
13e616 |
" data32=0x%08x%08x:0x%08x%08x"
|
|
Packit |
13e616 |
" data64=0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" modified_time=0x%x lease_period=0x%x\n\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_sr->service_id),
|
|
Packit |
13e616 |
cl_ntoh64(p_sr->service_gid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_sr->service_gid.unicast.interface_id),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_pkey),
|
|
Packit |
13e616 |
cl_ntoh32(p_sr->service_lease),
|
|
Packit |
13e616 |
p_sr->service_key[0], p_sr->service_key[1],
|
|
Packit |
13e616 |
p_sr->service_key[2], p_sr->service_key[3],
|
|
Packit |
13e616 |
p_sr->service_key[4], p_sr->service_key[5],
|
|
Packit |
13e616 |
p_sr->service_key[6], p_sr->service_key[7],
|
|
Packit |
13e616 |
p_sr->service_key[8], p_sr->service_key[9],
|
|
Packit |
13e616 |
p_sr->service_key[10], p_sr->service_key[11],
|
|
Packit |
13e616 |
p_sr->service_key[12], p_sr->service_key[13],
|
|
Packit |
13e616 |
p_sr->service_key[14], p_sr->service_key[15],
|
|
Packit |
13e616 |
p_sr->service_name,
|
|
Packit |
13e616 |
p_sr->service_data8[0], p_sr->service_data8[1],
|
|
Packit |
13e616 |
p_sr->service_data8[2], p_sr->service_data8[3],
|
|
Packit |
13e616 |
p_sr->service_data8[4], p_sr->service_data8[5],
|
|
Packit |
13e616 |
p_sr->service_data8[6], p_sr->service_data8[7],
|
|
Packit |
13e616 |
p_sr->service_data8[8], p_sr->service_data8[9],
|
|
Packit |
13e616 |
p_sr->service_data8[10], p_sr->service_data8[11],
|
|
Packit |
13e616 |
p_sr->service_data8[12], p_sr->service_data8[13],
|
|
Packit |
13e616 |
p_sr->service_data8[14], p_sr->service_data8[15],
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[0]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[1]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[2]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[3]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[4]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[5]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[6]),
|
|
Packit |
13e616 |
cl_ntoh16(p_sr->service_data16[7]),
|
|
Packit |
13e616 |
cl_ntoh32(p_sr->service_data32[0]),
|
|
Packit |
13e616 |
cl_ntoh32(p_sr->service_data32[1]),
|
|
Packit |
13e616 |
cl_ntoh32(p_sr->service_data32[2]),
|
|
Packit |
13e616 |
cl_ntoh32(p_sr->service_data32[3]),
|
|
Packit |
13e616 |
cl_ntoh64(p_sr->service_data64[0]),
|
|
Packit |
13e616 |
cl_ntoh64(p_sr->service_data64[1]),
|
|
Packit |
13e616 |
p_svcr->modified_time, p_svcr->lease_period);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_dump_one_port_guidinfo(cl_map_item_t * p_map_item, void *cxt)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
FILE *file = ((struct opensm_dump_context *)cxt)->file;
|
|
Packit |
13e616 |
osm_port_t *p_port = (osm_port_t *) p_map_item;
|
|
Packit |
13e616 |
uint32_t max_block;
|
|
Packit |
13e616 |
int block_num;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_port->p_physp->p_guids)
|
|
Packit |
13e616 |
return;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
|
|
Packit |
13e616 |
GUID_TABLE_MAX_ENTRIES;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (block_num = 0; block_num < max_block; block_num++) {
|
|
Packit |
13e616 |
fprintf(file, "GUIDInfo Record:"
|
|
Packit |
13e616 |
" base_guid=0x%016" PRIx64 " lid=0x%04x block_num=0x%x"
|
|
Packit |
13e616 |
" guid0=0x%016" PRIx64 " guid1=0x%016" PRIx64
|
|
Packit |
13e616 |
" guid2=0x%016" PRIx64 " guid3=0x%016" PRIx64
|
|
Packit |
13e616 |
" guid4=0x%016" PRIx64 " guid5=0x%016" PRIx64
|
|
Packit |
13e616 |
" guid6=0x%016" PRIx64 " guid7=0x%016" PRIx64
|
|
Packit |
13e616 |
"\n\n",
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[0]),
|
|
Packit |
13e616 |
cl_ntoh16(osm_port_get_base_lid(p_port)), block_num,
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 1]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 2]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 3]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 4]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 5]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 6]),
|
|
Packit |
13e616 |
cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 7]));
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
struct opensm_dump_context dump_context;
|
|
Packit |
13e616 |
osm_mgrp_t *p_mgrp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
dump_context.p_osm = p_osm;
|
|
Packit |
13e616 |
dump_context.file = file;
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump guidinfo\n");
|
|
Packit |
13e616 |
cl_qmap_apply_func(&p_osm->subn.port_guid_tbl,
|
|
Packit |
13e616 |
sa_dump_one_port_guidinfo, &dump_context);
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n");
|
|
Packit |
13e616 |
for (p_mgrp = (osm_mgrp_t *) cl_fmap_head(&p_osm->subn.mgrp_mgid_tbl);
|
|
Packit |
13e616 |
p_mgrp != (osm_mgrp_t *) cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl);
|
|
Packit |
13e616 |
p_mgrp = (osm_mgrp_t *) cl_fmap_next(&p_mgrp->map_item))
|
|
Packit |
13e616 |
sa_dump_one_mgrp(p_mgrp, &dump_context);
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n");
|
|
Packit |
13e616 |
cl_qlist_apply_func(&p_osm->subn.sa_infr_list,
|
|
Packit |
13e616 |
sa_dump_one_inform, &dump_context);
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services\n");
|
|
Packit |
13e616 |
cl_qlist_apply_func(&p_osm->subn.sa_sr_list,
|
|
Packit |
13e616 |
sa_dump_one_service, &dump_context);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_sa_db_file_dump(osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
int res = 1;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_plock_acquire(&p_osm->lock);
|
|
Packit |
13e616 |
if (p_osm->sa.dirty) {
|
|
Packit |
13e616 |
res = opensm_dump_to_file(
|
|
Packit |
13e616 |
p_osm, "opensm-sa.dump", sa_dump_all_sa);
|
|
Packit |
13e616 |
if (!res)
|
|
Packit |
13e616 |
p_osm->sa.dirty = FALSE;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
cl_plock_release(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return res;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* SA DB Loader
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
|
|
Packit |
13e616 |
ib_member_rec_t * p_mcm_rec)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
ib_net64_t comp_mask;
|
|
Packit |
13e616 |
osm_mgrp_t *p_mgrp;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_plock_excl_acquire(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_mgrp = osm_get_mgrp_by_mgid(&p_osm->subn, &p_mcm_rec->mgid);
|
|
Packit |
13e616 |
if (p_mgrp) {
|
|
Packit |
13e616 |
if (p_mgrp->mlid == mlid) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
|
|
Packit |
13e616 |
"mgrp %04x is already here.", cl_ntoh16(mlid));
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"mlid %04x is already used by another MC group. Will "
|
|
Packit |
13e616 |
"request clients reregistration.\n", cl_ntoh16(mlid));
|
|
Packit |
13e616 |
p_mgrp = NULL;
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL
|
|
Packit |
13e616 |
| IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
|
|
Packit |
13e616 |
if (!(p_mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa,
|
|
Packit |
13e616 |
comp_mask,
|
|
Packit |
13e616 |
p_mcm_rec)) ||
|
|
Packit |
13e616 |
p_mgrp->mlid != mlid) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"cannot create MC group with mlid 0x%04x and mgid "
|
|
Packit |
13e616 |
"0x%016" PRIx64 ":0x%016" PRIx64 "\n", cl_ntoh16(mlid),
|
|
Packit |
13e616 |
cl_ntoh64(p_mcm_rec->mgid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id));
|
|
Packit |
13e616 |
p_mgrp = NULL;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_out:
|
|
Packit |
13e616 |
cl_plock_release(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return p_mgrp;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int load_svcr(osm_opensm_t * p_osm, ib_service_record_t * sr,
|
|
Packit |
13e616 |
uint32_t modified_time, uint32_t lease_period)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_svcr_t *p_svcr;
|
|
Packit |
13e616 |
int ret = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_plock_excl_acquire(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (osm_svcr_get_by_rid(&p_osm->subn, &p_osm->log, sr)) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"ServiceRecord already exists\n");
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!(p_svcr = osm_svcr_new(sr))) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"cannot allocate new service struct\n");
|
|
Packit |
13e616 |
ret = -1;
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_svcr->modified_time = modified_time;
|
|
Packit |
13e616 |
p_svcr->lease_period = lease_period;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding ServiceRecord...\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_svcr_insert_to_db(&p_osm->subn, &p_osm->log, p_svcr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (lease_period != 0xffffffff)
|
|
Packit |
13e616 |
cl_timer_trim(&p_osm->sa.sr_timer, 1000);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_out:
|
|
Packit |
13e616 |
cl_plock_release(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int load_infr(osm_opensm_t * p_osm, ib_inform_info_record_t * iir,
|
|
Packit |
13e616 |
osm_mad_addr_t * addr)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_infr_t infr, *p_infr;
|
|
Packit |
13e616 |
int ret = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
infr.h_bind = p_osm->sa.mad_ctrl.h_bind;
|
|
Packit |
13e616 |
infr.sa = &p_osm->sa;
|
|
Packit |
13e616 |
/* other possible way to restore mad_addr partially is
|
|
Packit |
13e616 |
to extract qpn from InformInfo and to find lid by gid */
|
|
Packit |
13e616 |
infr.report_addr = *addr;
|
|
Packit |
13e616 |
infr.inform_record = *iir;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_plock_excl_acquire(&p_osm->lock);
|
|
Packit |
13e616 |
if (osm_infr_get_by_rec(&p_osm->subn, &p_osm->log, &infr)) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"InformInfo Record already exists\n");
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!(p_infr = osm_infr_new(&infr))) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"cannot allocate new infr struct\n");
|
|
Packit |
13e616 |
ret = -1;
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding InformInfo Record...\n");
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_infr_insert_to_db(&p_osm->subn, &p_osm->log, p_infr);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_out:
|
|
Packit |
13e616 |
cl_plock_release(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int load_guidinfo(osm_opensm_t * p_osm, ib_net64_t base_guid,
|
|
Packit |
13e616 |
ib_guidinfo_record_t *gir)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
osm_port_t *p_port;
|
|
Packit |
13e616 |
uint32_t max_block;
|
|
Packit |
13e616 |
int i, ret = 0;
|
|
Packit |
13e616 |
osm_alias_guid_t *p_alias_guid, *p_alias_guid_check;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
cl_plock_excl_acquire(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_port = osm_get_port_by_guid(&p_osm->subn, base_guid);
|
|
Packit |
13e616 |
if (!p_port)
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_port->p_physp->p_guids) {
|
|
Packit |
13e616 |
max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
|
|
Packit |
13e616 |
GUID_TABLE_MAX_ENTRIES;
|
|
Packit |
13e616 |
p_port->p_physp->p_guids = calloc(max_block * GUID_TABLE_MAX_ENTRIES,
|
|
Packit |
13e616 |
sizeof(ib_net64_t));
|
|
Packit |
13e616 |
if (!p_port->p_physp->p_guids) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"cannot allocate GUID table for port "
|
|
Packit |
13e616 |
"GUID 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_port->p_physp->port_guid));
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
for (i = 0; i < GUID_TABLE_MAX_ENTRIES; i++) {
|
|
Packit |
13e616 |
if (!gir->guid_info.guid[i])
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
/* skip block 0 index 0 */
|
|
Packit |
13e616 |
if (gir->block_num == 0 && i == 0)
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
if (gir->block_num * GUID_TABLE_MAX_ENTRIES + i >
|
|
Packit |
13e616 |
p_port->p_physp->port_info.guid_cap)
|
|
Packit |
13e616 |
break;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_alias_guid = osm_alias_guid_new(gir->guid_info.guid[i],
|
|
Packit |
13e616 |
p_port);
|
|
Packit |
13e616 |
if (!p_alias_guid) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Alias guid %d memory allocation failed"
|
|
Packit |
13e616 |
" for port GUID 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
gir->block_num * GUID_TABLE_MAX_ENTRIES + i,
|
|
Packit |
13e616 |
cl_ntoh64(p_port->p_physp->port_guid));
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_alias_guid_check =
|
|
Packit |
13e616 |
(osm_alias_guid_t *) cl_qmap_insert(&p_osm->subn.alias_port_guid_tbl,
|
|
Packit |
13e616 |
p_alias_guid->alias_guid,
|
|
Packit |
13e616 |
&p_alias_guid->map_item);
|
|
Packit |
13e616 |
if (p_alias_guid_check != p_alias_guid) {
|
|
Packit |
13e616 |
/* alias GUID is a duplicate */
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
|
|
Packit |
13e616 |
"Duplicate alias port GUID 0x%" PRIx64
|
|
Packit |
13e616 |
" index %d base port GUID 0x%" PRIx64 "\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_alias_guid->alias_guid),
|
|
Packit |
13e616 |
gir->block_num * GUID_TABLE_MAX_ENTRIES + i,
|
|
Packit |
13e616 |
cl_ntoh64(p_alias_guid->p_base_port->guid));
|
|
Packit |
13e616 |
osm_alias_guid_delete(&p_alias_guid);
|
|
Packit |
13e616 |
goto _out;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
memcpy(&(*p_port->p_physp->p_guids)[gir->block_num * GUID_TABLE_MAX_ENTRIES],
|
|
Packit |
13e616 |
&gir->guid_info, sizeof(ib_guid_info_t));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
osm_queue_guidinfo(&p_osm->sa, p_port, gir->block_num);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_out:
|
|
Packit |
13e616 |
cl_plock_release(&p_osm->lock);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#define UNPACK_FUNC(name,x) \
|
|
Packit |
13e616 |
static int unpack_##name##x(char *p, uint##x##_t *val_ptr) \
|
|
Packit |
13e616 |
{ \
|
|
Packit |
13e616 |
char *q; \
|
|
Packit |
13e616 |
unsigned long long num; \
|
|
Packit |
13e616 |
num = strtoull(p, &q, 16); \
|
|
Packit |
13e616 |
if (num > ~((uint##x##_t)0x0) \
|
|
Packit |
13e616 |
|| q == p || (!isspace(*q) && *q != ':')) { \
|
|
Packit |
13e616 |
*val_ptr = 0; \
|
|
Packit |
13e616 |
return -1; \
|
|
Packit |
13e616 |
} \
|
|
Packit |
13e616 |
*val_ptr = cl_hton##x((uint##x##_t)num); \
|
|
Packit |
13e616 |
return (int)(q - p); \
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#define cl_hton8(x) (x)
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
UNPACK_FUNC(net, 8);
|
|
Packit |
13e616 |
UNPACK_FUNC(net, 16);
|
|
Packit |
13e616 |
UNPACK_FUNC(net, 32);
|
|
Packit |
13e616 |
UNPACK_FUNC(net, 64);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int unpack_string(char *p, uint8_t * buf, unsigned len)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char *q = p;
|
|
Packit |
13e616 |
char delim = ' ';
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (*q == '\'' || *q == '\"')
|
|
Packit |
13e616 |
delim = *q++;
|
|
Packit |
13e616 |
while (--len && *q && *q != delim)
|
|
Packit |
13e616 |
*buf++ = *q++;
|
|
Packit |
13e616 |
*buf = '\0';
|
|
Packit |
13e616 |
if (*q == delim && delim != ' ')
|
|
Packit |
13e616 |
q++;
|
|
Packit |
13e616 |
return (int)(q - p);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static int unpack_string64(char *p, uint8_t * buf)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
return unpack_string(p, buf, 64);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
#define PARSE_AHEAD(p, x, name, val_ptr) { int _ret; \
|
|
Packit |
13e616 |
p = strstr(p, name); \
|
|
Packit |
13e616 |
if (!p) { \
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \
|
|
Packit |
13e616 |
"PARSE ERROR: %s:%u: cannot find \"%s\" string\n", \
|
|
Packit |
13e616 |
file_name, lineno, (name)); \
|
|
Packit |
13e616 |
ret = -2; \
|
|
Packit |
13e616 |
goto _error; \
|
|
Packit |
13e616 |
} \
|
|
Packit |
13e616 |
p += strlen(name); \
|
|
Packit |
13e616 |
_ret = unpack_##x(p, (val_ptr)); \
|
|
Packit |
13e616 |
if (_ret < 0) { \
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \
|
|
Packit |
13e616 |
"PARSE ERROR: %s:%u: cannot parse "#x" value " \
|
|
Packit |
13e616 |
"after \"%s\"\n", file_name, lineno, (name)); \
|
|
Packit |
13e616 |
ret = _ret; \
|
|
Packit |
13e616 |
goto _error; \
|
|
Packit |
13e616 |
} \
|
|
Packit |
13e616 |
p += _ret; \
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
static void sa_db_file_load_handle_mgrp(osm_opensm_t * p_osm,
|
|
Packit |
13e616 |
osm_mgrp_t * p_mgrp)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
/* decide whether to delete the mgrp object or not */
|
|
Packit |
13e616 |
if (p_mgrp->full_members == 0 && !p_mgrp->well_known) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Closing MC group 0x%016" PRIx64 ":0x%016" PRIx64
|
|
Packit |
13e616 |
" - no full members were added to not well known "
|
|
Packit |
13e616 |
"group\n",
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix),
|
|
Packit |
13e616 |
cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id));
|
|
Packit |
13e616 |
osm_mgrp_cleanup(&p_osm->subn, p_mgrp);
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
int osm_sa_db_file_load(osm_opensm_t * p_osm)
|
|
Packit |
13e616 |
{
|
|
Packit |
13e616 |
char line[1024];
|
|
Packit |
13e616 |
char *file_name;
|
|
Packit |
13e616 |
FILE *file;
|
|
Packit |
13e616 |
int ret = 0;
|
|
Packit |
13e616 |
osm_mgrp_t *p_next_mgrp = NULL;
|
|
Packit |
13e616 |
osm_mgrp_t *p_prev_mgrp = NULL;
|
|
Packit |
13e616 |
unsigned rereg_clients = 0;
|
|
Packit |
13e616 |
unsigned lineno;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!p_osm->subn.first_time_master_sweep) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Not first sweep - skip SA DB restore\n");
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
file_name = p_osm->subn.opt.sa_db_file;
|
|
Packit |
13e616 |
if (!file_name) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"sa db file name is not specified. Skip restore\n");
|
|
Packit |
13e616 |
return 0;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
file = fopen(file_name, "r");
|
|
Packit |
13e616 |
if (!file) {
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS, "ERR 4C02: "
|
|
Packit |
13e616 |
"Can't open sa db file \'%s\'. Skip restoring\n",
|
|
Packit |
13e616 |
file_name);
|
|
Packit |
13e616 |
return -1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
|
|
Packit |
13e616 |
"Restoring SA DB from file \'%s\'\n",
|
|
Packit |
13e616 |
file_name);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
lineno = 0;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
while (fgets(line, sizeof(line) - 1, file) != NULL) {
|
|
Packit |
13e616 |
char *p;
|
|
Packit |
13e616 |
uint8_t val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
lineno++;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p = line;
|
|
Packit |
13e616 |
while (isspace(*p))
|
|
Packit |
13e616 |
p++;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (*p == '#')
|
|
Packit |
13e616 |
continue;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (!strncmp(p, "MC Group", 8)) {
|
|
Packit |
13e616 |
ib_member_rec_t mcm_rec;
|
|
Packit |
13e616 |
ib_net16_t mlid;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_mgrp = NULL;
|
|
Packit |
13e616 |
memset(&mcm_rec, 0, sizeof(mcm_rec));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " 0x", &mlid);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " mgid=0x",
|
|
Packit |
13e616 |
&mcm_rec.mgid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&mcm_rec.mgid.unicast.interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " port_gid=0x",
|
|
Packit |
13e616 |
&mcm_rec.port_gid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&mcm_rec.port_gid.unicast.interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " qkey=0x", &mcm_rec.qkey);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " mlid=0x", &mcm_rec.mlid);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " mtu=0x", &mcm_rec.mtu);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " tclass=0x", &mcm_rec.tclass);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " pkey=0x", &mcm_rec.pkey);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " rate=0x", &mcm_rec.rate);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " pkt_life=0x", &mcm_rec.pkt_life);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " sl_flow_hop=0x",
|
|
Packit |
13e616 |
&mcm_rec.sl_flow_hop);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " scope_state=0x",
|
|
Packit |
13e616 |
&mcm_rec.scope_state);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " proxy_join=0x", &val;;
|
|
Packit |
13e616 |
mcm_rec.proxy_join = val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_mgrp = load_mcgroup(p_osm, mlid, &mcm_rec);
|
|
Packit |
13e616 |
if (!p_next_mgrp)
|
|
Packit |
13e616 |
rereg_clients = 1;
|
|
Packit |
13e616 |
if (cl_ntoh16(mlid) > p_osm->sm.mlids_init_max)
|
|
Packit |
13e616 |
p_osm->sm.mlids_init_max = cl_ntoh16(mlid);
|
|
Packit |
13e616 |
} else if (p_next_mgrp && !strncmp(p, "mcm_port", 8)) {
|
|
Packit |
13e616 |
ib_member_rec_t mcmr;
|
|
Packit |
13e616 |
ib_net64_t guid;
|
|
Packit |
13e616 |
osm_port_t *port;
|
|
Packit |
13e616 |
boolean_t proxy;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " port_gid=0x",
|
|
Packit |
13e616 |
&mcmr.port_gid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&mcmr.port_gid.unicast.interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " scope_state=0x", &mcmr.scope_state);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " proxy_join=0x", &val;;
|
|
Packit |
13e616 |
proxy = val;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
guid = mcmr.port_gid.unicast.interface_id;
|
|
Packit |
13e616 |
port = osm_get_port_by_alias_guid(&p_osm->subn, guid);
|
|
Packit |
13e616 |
if (port &&
|
|
Packit |
13e616 |
cl_qmap_get(&p_next_mgrp->mcm_port_tbl, guid) ==
|
|
Packit |
13e616 |
cl_qmap_end(&p_next_mgrp->mcm_port_tbl) &&
|
|
Packit |
13e616 |
!osm_mgrp_add_port(&p_osm->subn, &p_osm->log,
|
|
Packit |
13e616 |
p_next_mgrp, port, &mcmr, proxy))
|
|
Packit |
13e616 |
rereg_clients = 1;
|
|
Packit |
13e616 |
} else if (!strncmp(p, "Service Record:", 15)) {
|
|
Packit |
13e616 |
ib_service_record_t s_rec;
|
|
Packit |
13e616 |
uint32_t modified_time, lease_period;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_mgrp = NULL;
|
|
Packit |
13e616 |
memset(&s_rec, 0, sizeof(s_rec));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " id=0x", &s_rec.service_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " gid=0x",
|
|
Packit |
13e616 |
&s_rec.service_gid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&s_rec.service_gid.unicast.interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " pkey=0x", &s_rec.service_pkey);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " lease=0x",
|
|
Packit |
13e616 |
&s_rec.service_lease);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " key=0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_key[0]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_key[8]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, string64, " name=", s_rec.service_name);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " data8=0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data8[0]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data8[8]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " data16=0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data16[0]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data16[4]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " data32=0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data32[0]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
(ib_net64_t *) (&s_rec.service_data32[2]));
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " data64=0x",
|
|
Packit |
13e616 |
&s_rec.service_data64[0]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x", &s_rec.service_data64[1]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " modified_time=0x",
|
|
Packit |
13e616 |
&modified_time);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " lease_period=0x",
|
|
Packit |
13e616 |
&lease_period);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (load_svcr(p_osm, &s_rec, cl_ntoh32(modified_time),
|
|
Packit |
13e616 |
cl_ntoh32(lease_period)))
|
|
Packit |
13e616 |
rereg_clients = 1;
|
|
Packit |
13e616 |
} else if (!strncmp(p, "InformInfo Record:", 18)) {
|
|
Packit |
13e616 |
ib_inform_info_record_t i_rec;
|
|
Packit |
13e616 |
osm_mad_addr_t rep_addr;
|
|
Packit |
13e616 |
ib_net16_t val16;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_mgrp = NULL;
|
|
Packit |
13e616 |
memset(&i_rec, 0, sizeof(i_rec));
|
|
Packit |
13e616 |
memset(&rep_addr, 0, sizeof(rep_addr));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " subscriber_gid=0x",
|
|
Packit |
13e616 |
&i_rec.subscriber_gid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&i_rec.subscriber_gid.unicast.interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " subscriber_enum=0x",
|
|
Packit |
13e616 |
&i_rec.subscriber_enum);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " gid=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.gid.unicast.prefix);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, ":0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.gid.unicast.
|
|
Packit |
13e616 |
interface_id);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " lid_range_begin=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.lid_range_begin);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " lid_range_end=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.lid_range_end);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " is_generic=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.is_generic);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " subscribe=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.subscribe);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " trap_type=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.trap_type);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " trap_num=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.g_or_v.generic.trap_num);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " qpn_resp_time_val=0x",
|
|
Packit |
13e616 |
&i_rec.inform_info.g_or_v.generic.
|
|
Packit |
13e616 |
qpn_resp_time_val);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " node_type=0x",
|
|
Packit |
13e616 |
(uint32_t *) & i_rec.inform_info.g_or_v.
|
|
Packit |
13e616 |
generic.reserved2);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " rep_addr: lid=0x",
|
|
Packit |
13e616 |
&rep_addr.dest_lid);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " path_bits=0x",
|
|
Packit |
13e616 |
&rep_addr.path_bits);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " static_rate=0x",
|
|
Packit |
13e616 |
&rep_addr.static_rate);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " remote_qp=0x",
|
|
Packit |
13e616 |
&rep_addr.addr_type.gsi.remote_qp);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net32, " remote_qkey=0x",
|
|
Packit |
13e616 |
&rep_addr.addr_type.gsi.remote_qkey);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " pkey_ix=0x", &val16);
|
|
Packit |
13e616 |
rep_addr.addr_type.gsi.pkey_ix = cl_ntoh16(val16);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " sl=0x",
|
|
Packit |
13e616 |
&rep_addr.addr_type.gsi.service_level);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (load_infr(p_osm, &i_rec, &rep_addr))
|
|
Packit |
13e616 |
rereg_clients = 1;
|
|
Packit |
13e616 |
} else if (!strncmp(p, "GUIDInfo Record:", 16)) {
|
|
Packit |
13e616 |
ib_guidinfo_record_t gi_rec;
|
|
Packit |
13e616 |
ib_net64_t base_guid;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
p_next_mgrp = NULL;
|
|
Packit |
13e616 |
memset(&gi_rec, 0, sizeof(gi_rec));
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " base_guid=0x", &base_guid);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net16, " lid=0x", &gi_rec.lid);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net8, " block_num=0x",
|
|
Packit |
13e616 |
&gi_rec.block_num);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid0=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[0]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid1=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[1]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid2=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[2]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid3=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[3]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid4=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[4]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid5=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[5]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid6=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[6]);
|
|
Packit |
13e616 |
PARSE_AHEAD(p, net64, " guid7=0x",
|
|
Packit |
13e616 |
&gi_rec.guid_info.guid[7]);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (load_guidinfo(p_osm, base_guid, &gi_rec))
|
|
Packit |
13e616 |
rereg_clients = 1;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* p_next_mgrp points to the multicast group now being parsed.
|
|
Packit |
13e616 |
* p_prev_mgrp points to the last multicast group we parsed.
|
|
Packit |
13e616 |
* We decide whether to keep or delete each multicast group
|
|
Packit |
13e616 |
* only when we finish parsing it's member records. if the
|
|
Packit |
13e616 |
* group has full members, or it is a "well known group" we
|
|
Packit |
13e616 |
* keep it.
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (p_prev_mgrp != p_next_mgrp) {
|
|
Packit |
13e616 |
if (p_prev_mgrp)
|
|
Packit |
13e616 |
sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
|
|
Packit |
13e616 |
p_prev_mgrp = p_next_mgrp;
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
}
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
if (p_next_mgrp)
|
|
Packit |
13e616 |
sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/*
|
|
Packit |
13e616 |
* If loading succeeded, do whatever 'no_clients_rereg' says.
|
|
Packit |
13e616 |
* If loading failed at some point, turn off the 'no_clients_rereg'
|
|
Packit |
13e616 |
* option (turn on re-registration requests).
|
|
Packit |
13e616 |
*/
|
|
Packit |
13e616 |
if (rereg_clients)
|
|
Packit |
13e616 |
p_osm->subn.opt.no_clients_rereg = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
/* We've just finished loading SA DB file - clear the "dirty" flag */
|
|
Packit |
13e616 |
p_osm->sa.dirty = FALSE;
|
|
Packit |
13e616 |
|
|
Packit |
13e616 |
_error:
|
|
Packit |
13e616 |
fclose(file);
|
|
Packit |
13e616 |
return ret;
|
|
Packit |
13e616 |
}
|