Blame opensm/osm_sa.c

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
}