xref: /freebsd-src/contrib/ofed/opensm/opensm/osm_sa.c (revision 87181516ef48be852d5e5fee53c6e0dbfc62f21e)
1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2014 Mellanox Technologies LTD. All rights reserved.
4*d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5*d6b92ffaSHans Petter Selasky  * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
6*d6b92ffaSHans Petter Selasky  *
7*d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
8*d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
9*d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
10*d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
11*d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
12*d6b92ffaSHans Petter Selasky  *
13*d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
14*d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
15*d6b92ffaSHans Petter Selasky  *     conditions are met:
16*d6b92ffaSHans Petter Selasky  *
17*d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
18*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
19*d6b92ffaSHans Petter Selasky  *        disclaimer.
20*d6b92ffaSHans Petter Selasky  *
21*d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
22*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
23*d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
24*d6b92ffaSHans Petter Selasky  *        provided with the distribution.
25*d6b92ffaSHans Petter Selasky  *
26*d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27*d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28*d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29*d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30*d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31*d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32*d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33*d6b92ffaSHans Petter Selasky  * SOFTWARE.
34*d6b92ffaSHans Petter Selasky  *
35*d6b92ffaSHans Petter Selasky  */
36*d6b92ffaSHans Petter Selasky 
37*d6b92ffaSHans Petter Selasky /*
38*d6b92ffaSHans Petter Selasky  * Abstract:
39*d6b92ffaSHans Petter Selasky  *    Implementation of osm_sa_t.
40*d6b92ffaSHans Petter Selasky  * This object represents the Subnet Administration object.
41*d6b92ffaSHans Petter Selasky  * This object is part of the opensm family of objects.
42*d6b92ffaSHans Petter Selasky  */
43*d6b92ffaSHans Petter Selasky 
44*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
45*d6b92ffaSHans Petter Selasky #  include <config.h>
46*d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
47*d6b92ffaSHans Petter Selasky 
48*d6b92ffaSHans Petter Selasky #include <string.h>
49*d6b92ffaSHans Petter Selasky #include <ctype.h>
50*d6b92ffaSHans Petter Selasky #include <errno.h>
51*d6b92ffaSHans Petter Selasky #include <stdlib.h>
52*d6b92ffaSHans Petter Selasky #include <unistd.h>
53*d6b92ffaSHans Petter Selasky #include <sys/types.h>
54*d6b92ffaSHans Petter Selasky #include <sys/stat.h>
55*d6b92ffaSHans Petter Selasky #include <complib/cl_qmap.h>
56*d6b92ffaSHans Petter Selasky #include <complib/cl_passivelock.h>
57*d6b92ffaSHans Petter Selasky #include <complib/cl_debug.h>
58*d6b92ffaSHans Petter Selasky #include <iba/ib_types.h>
59*d6b92ffaSHans Petter Selasky #include <opensm/osm_file_ids.h>
60*d6b92ffaSHans Petter Selasky #define FILE_ID OSM_FILE_SA_C
61*d6b92ffaSHans Petter Selasky #include <opensm/osm_sa.h>
62*d6b92ffaSHans Petter Selasky #include <opensm/osm_madw.h>
63*d6b92ffaSHans Petter Selasky #include <opensm/osm_log.h>
64*d6b92ffaSHans Petter Selasky #include <opensm/osm_subnet.h>
65*d6b92ffaSHans Petter Selasky #include <opensm/osm_mad_pool.h>
66*d6b92ffaSHans Petter Selasky #include <opensm/osm_msgdef.h>
67*d6b92ffaSHans Petter Selasky #include <opensm/osm_opensm.h>
68*d6b92ffaSHans Petter Selasky #include <opensm/osm_multicast.h>
69*d6b92ffaSHans Petter Selasky #include <opensm/osm_inform.h>
70*d6b92ffaSHans Petter Selasky #include <opensm/osm_service.h>
71*d6b92ffaSHans Petter Selasky #include <opensm/osm_guid.h>
72*d6b92ffaSHans Petter Selasky #include <opensm/osm_helper.h>
73*d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
74*d6b92ffaSHans Petter Selasky 
75*d6b92ffaSHans Petter Selasky #define  OSM_SA_INITIAL_TID_VALUE 0xabc
76*d6b92ffaSHans Petter Selasky 
77*d6b92ffaSHans Petter Selasky extern void osm_cpi_rcv_process(IN void *context, IN void *data);
78*d6b92ffaSHans Petter Selasky extern void osm_gir_rcv_process(IN void *context, IN void *data);
79*d6b92ffaSHans Petter Selasky extern void osm_infr_rcv_process(IN void *context, IN void *data);
80*d6b92ffaSHans Petter Selasky extern void osm_infir_rcv_process(IN void *context, IN void *data);
81*d6b92ffaSHans Petter Selasky extern void osm_lftr_rcv_process(IN void *context, IN void *data);
82*d6b92ffaSHans Petter Selasky extern void osm_lr_rcv_process(IN void *context, IN void *data);
83*d6b92ffaSHans Petter Selasky extern void osm_mcmr_rcv_process(IN void *context, IN void *data);
84*d6b92ffaSHans Petter Selasky extern void osm_mftr_rcv_process(IN void *context, IN void *data);
85*d6b92ffaSHans Petter Selasky extern void osm_mpr_rcv_process(IN void *context, IN void *data);
86*d6b92ffaSHans Petter Selasky extern void osm_nr_rcv_process(IN void *context, IN void *data);
87*d6b92ffaSHans Petter Selasky extern void osm_pr_rcv_process(IN void *context, IN void *data);
88*d6b92ffaSHans Petter Selasky extern void osm_pkey_rec_rcv_process(IN void *context, IN void *data);
89*d6b92ffaSHans Petter Selasky extern void osm_pir_rcv_process(IN void *context, IN void *data);
90*d6b92ffaSHans Petter Selasky extern void osm_sr_rcv_process(IN void *context, IN void *data);
91*d6b92ffaSHans Petter Selasky extern void osm_slvl_rec_rcv_process(IN void *context, IN void *data);
92*d6b92ffaSHans Petter Selasky extern void osm_smir_rcv_process(IN void *context, IN void *data);
93*d6b92ffaSHans Petter Selasky extern void osm_sir_rcv_process(IN void *context, IN void *data);
94*d6b92ffaSHans Petter Selasky extern void osm_vlarb_rec_rcv_process(IN void *context, IN void *data);
95*d6b92ffaSHans Petter Selasky extern void osm_sr_rcv_lease_cb(IN void *context);
96*d6b92ffaSHans Petter Selasky 
osm_sa_construct(IN osm_sa_t * p_sa)97*d6b92ffaSHans Petter Selasky void osm_sa_construct(IN osm_sa_t * p_sa)
98*d6b92ffaSHans Petter Selasky {
99*d6b92ffaSHans Petter Selasky 	memset(p_sa, 0, sizeof(*p_sa));
100*d6b92ffaSHans Petter Selasky 	p_sa->state = OSM_SA_STATE_INIT;
101*d6b92ffaSHans Petter Selasky 	p_sa->sa_trans_id = OSM_SA_INITIAL_TID_VALUE;
102*d6b92ffaSHans Petter Selasky 
103*d6b92ffaSHans Petter Selasky 	cl_timer_construct(&p_sa->sr_timer);
104*d6b92ffaSHans Petter Selasky }
105*d6b92ffaSHans Petter Selasky 
osm_sa_shutdown(IN osm_sa_t * p_sa)106*d6b92ffaSHans Petter Selasky void osm_sa_shutdown(IN osm_sa_t * p_sa)
107*d6b92ffaSHans Petter Selasky {
108*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_sa->p_log);
109*d6b92ffaSHans Petter Selasky 
110*d6b92ffaSHans Petter Selasky 	cl_timer_stop(&p_sa->sr_timer);
111*d6b92ffaSHans Petter Selasky 
112*d6b92ffaSHans Petter Selasky 	/* unbind from the mad service */
113*d6b92ffaSHans Petter Selasky 	osm_sa_mad_ctrl_unbind(&p_sa->mad_ctrl);
114*d6b92ffaSHans Petter Selasky 
115*d6b92ffaSHans Petter Selasky 	/* remove any registered dispatcher message */
116*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->nr_disp_h);
117*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->pir_disp_h);
118*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->gir_disp_h);
119*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->lr_disp_h);
120*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->pr_disp_h);
121*d6b92ffaSHans Petter Selasky #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
122*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->mpr_disp_h);
123*d6b92ffaSHans Petter Selasky #endif
124*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->smir_disp_h);
125*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->mcmr_disp_h);
126*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->sr_disp_h);
127*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->infr_disp_h);
128*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->infir_disp_h);
129*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->vlarb_disp_h);
130*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->slvl_disp_h);
131*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->pkey_disp_h);
132*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->lft_disp_h);
133*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->sir_disp_h);
134*d6b92ffaSHans Petter Selasky 	cl_disp_unregister(p_sa->mft_disp_h);
135*d6b92ffaSHans Petter Selasky 
136*d6b92ffaSHans Petter Selasky 	if (p_sa->p_set_disp) {
137*d6b92ffaSHans Petter Selasky 		cl_disp_unregister(p_sa->mcmr_set_disp_h);
138*d6b92ffaSHans Petter Selasky 		cl_disp_unregister(p_sa->infr_set_disp_h);
139*d6b92ffaSHans Petter Selasky 		cl_disp_unregister(p_sa->sr_set_disp_h);
140*d6b92ffaSHans Petter Selasky 		cl_disp_unregister(p_sa->gir_set_disp_h);
141*d6b92ffaSHans Petter Selasky 	}
142*d6b92ffaSHans Petter Selasky 
143*d6b92ffaSHans Petter Selasky 	osm_sa_mad_ctrl_destroy(&p_sa->mad_ctrl);
144*d6b92ffaSHans Petter Selasky 
145*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_sa->p_log);
146*d6b92ffaSHans Petter Selasky }
147*d6b92ffaSHans Petter Selasky 
osm_sa_destroy(IN osm_sa_t * p_sa)148*d6b92ffaSHans Petter Selasky void osm_sa_destroy(IN osm_sa_t * p_sa)
149*d6b92ffaSHans Petter Selasky {
150*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_sa->p_log);
151*d6b92ffaSHans Petter Selasky 
152*d6b92ffaSHans Petter Selasky 	p_sa->state = OSM_SA_STATE_INIT;
153*d6b92ffaSHans Petter Selasky 
154*d6b92ffaSHans Petter Selasky 	cl_timer_destroy(&p_sa->sr_timer);
155*d6b92ffaSHans Petter Selasky 
156*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_sa->p_log);
157*d6b92ffaSHans Petter Selasky }
158*d6b92ffaSHans Petter Selasky 
osm_sa_init(IN osm_sm_t * p_sm,IN osm_sa_t * p_sa,IN osm_subn_t * p_subn,IN osm_vendor_t * p_vendor,IN osm_mad_pool_t * p_mad_pool,IN osm_log_t * p_log,IN osm_stats_t * p_stats,IN cl_dispatcher_t * p_disp,IN cl_dispatcher_t * p_set_disp,IN cl_plock_t * p_lock)159*d6b92ffaSHans Petter Selasky ib_api_status_t osm_sa_init(IN osm_sm_t * p_sm, IN osm_sa_t * p_sa,
160*d6b92ffaSHans Petter Selasky 			    IN osm_subn_t * p_subn, IN osm_vendor_t * p_vendor,
161*d6b92ffaSHans Petter Selasky 			    IN osm_mad_pool_t * p_mad_pool,
162*d6b92ffaSHans Petter Selasky 			    IN osm_log_t * p_log, IN osm_stats_t * p_stats,
163*d6b92ffaSHans Petter Selasky 			    IN cl_dispatcher_t * p_disp,
164*d6b92ffaSHans Petter Selasky 			    IN cl_dispatcher_t * p_set_disp,
165*d6b92ffaSHans Petter Selasky 			    IN cl_plock_t * p_lock)
166*d6b92ffaSHans Petter Selasky {
167*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
168*d6b92ffaSHans Petter Selasky 
169*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_log);
170*d6b92ffaSHans Petter Selasky 
171*d6b92ffaSHans Petter Selasky 	p_sa->sm = p_sm;
172*d6b92ffaSHans Petter Selasky 	p_sa->p_subn = p_subn;
173*d6b92ffaSHans Petter Selasky 	p_sa->p_vendor = p_vendor;
174*d6b92ffaSHans Petter Selasky 	p_sa->p_mad_pool = p_mad_pool;
175*d6b92ffaSHans Petter Selasky 	p_sa->p_log = p_log;
176*d6b92ffaSHans Petter Selasky 	p_sa->p_disp = p_disp;
177*d6b92ffaSHans Petter Selasky 	p_sa->p_set_disp = p_set_disp;
178*d6b92ffaSHans Petter Selasky 	p_sa->p_lock = p_lock;
179*d6b92ffaSHans Petter Selasky 
180*d6b92ffaSHans Petter Selasky 	p_sa->state = OSM_SA_STATE_READY;
181*d6b92ffaSHans Petter Selasky 
182*d6b92ffaSHans Petter Selasky 	status = osm_sa_mad_ctrl_init(&p_sa->mad_ctrl, p_sa, p_sa->p_mad_pool,
183*d6b92ffaSHans Petter Selasky 				      p_sa->p_vendor, p_subn, p_log, p_stats,
184*d6b92ffaSHans Petter Selasky 				      p_disp, p_set_disp);
185*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
186*d6b92ffaSHans Petter Selasky 		goto Exit;
187*d6b92ffaSHans Petter Selasky 
188*d6b92ffaSHans Petter Selasky 	status = cl_timer_init(&p_sa->sr_timer, osm_sr_rcv_lease_cb, p_sa);
189*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
190*d6b92ffaSHans Petter Selasky 		goto Exit;
191*d6b92ffaSHans Petter Selasky 
192*d6b92ffaSHans Petter Selasky 	status = IB_INSUFFICIENT_RESOURCES;
193*d6b92ffaSHans Petter Selasky 	p_sa->cpi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_CLASS_PORT_INFO,
194*d6b92ffaSHans Petter Selasky 					    osm_cpi_rcv_process, p_sa);
195*d6b92ffaSHans Petter Selasky 	if (p_sa->cpi_disp_h == CL_DISP_INVALID_HANDLE)
196*d6b92ffaSHans Petter Selasky 		goto Exit;
197*d6b92ffaSHans Petter Selasky 
198*d6b92ffaSHans Petter Selasky 	p_sa->nr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_RECORD,
199*d6b92ffaSHans Petter Selasky 					   osm_nr_rcv_process, p_sa);
200*d6b92ffaSHans Petter Selasky 	if (p_sa->nr_disp_h == CL_DISP_INVALID_HANDLE)
201*d6b92ffaSHans Petter Selasky 		goto Exit;
202*d6b92ffaSHans Petter Selasky 
203*d6b92ffaSHans Petter Selasky 	p_sa->pir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PORTINFO_RECORD,
204*d6b92ffaSHans Petter Selasky 					    osm_pir_rcv_process, p_sa);
205*d6b92ffaSHans Petter Selasky 	if (p_sa->pir_disp_h == CL_DISP_INVALID_HANDLE)
206*d6b92ffaSHans Petter Selasky 		goto Exit;
207*d6b92ffaSHans Petter Selasky 
208*d6b92ffaSHans Petter Selasky 	p_sa->gir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_GUIDINFO_RECORD,
209*d6b92ffaSHans Petter Selasky 					    osm_gir_rcv_process, p_sa);
210*d6b92ffaSHans Petter Selasky 	if (p_sa->gir_disp_h == CL_DISP_INVALID_HANDLE)
211*d6b92ffaSHans Petter Selasky 		goto Exit;
212*d6b92ffaSHans Petter Selasky 
213*d6b92ffaSHans Petter Selasky 	p_sa->lr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LINK_RECORD,
214*d6b92ffaSHans Petter Selasky 					   osm_lr_rcv_process, p_sa);
215*d6b92ffaSHans Petter Selasky 	if (p_sa->lr_disp_h == CL_DISP_INVALID_HANDLE)
216*d6b92ffaSHans Petter Selasky 		goto Exit;
217*d6b92ffaSHans Petter Selasky 
218*d6b92ffaSHans Petter Selasky 	p_sa->pr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PATH_RECORD,
219*d6b92ffaSHans Petter Selasky 					   osm_pr_rcv_process, p_sa);
220*d6b92ffaSHans Petter Selasky 	if (p_sa->pr_disp_h == CL_DISP_INVALID_HANDLE)
221*d6b92ffaSHans Petter Selasky 		goto Exit;
222*d6b92ffaSHans Petter Selasky 
223*d6b92ffaSHans Petter Selasky #if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
224*d6b92ffaSHans Petter Selasky 	p_sa->mpr_disp_h =
225*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_MULTIPATH_RECORD,
226*d6b92ffaSHans Petter Selasky 			     osm_mpr_rcv_process, p_sa);
227*d6b92ffaSHans Petter Selasky 	if (p_sa->mpr_disp_h == CL_DISP_INVALID_HANDLE)
228*d6b92ffaSHans Petter Selasky 		goto Exit;
229*d6b92ffaSHans Petter Selasky #endif
230*d6b92ffaSHans Petter Selasky 
231*d6b92ffaSHans Petter Selasky 	p_sa->smir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SMINFO_RECORD,
232*d6b92ffaSHans Petter Selasky 					     osm_smir_rcv_process, p_sa);
233*d6b92ffaSHans Petter Selasky 	if (p_sa->smir_disp_h == CL_DISP_INVALID_HANDLE)
234*d6b92ffaSHans Petter Selasky 		goto Exit;
235*d6b92ffaSHans Petter Selasky 
236*d6b92ffaSHans Petter Selasky 	p_sa->mcmr_disp_h =
237*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_MCMEMBER_RECORD,
238*d6b92ffaSHans Petter Selasky 			     osm_mcmr_rcv_process, p_sa);
239*d6b92ffaSHans Petter Selasky 	if (p_sa->mcmr_disp_h == CL_DISP_INVALID_HANDLE)
240*d6b92ffaSHans Petter Selasky 		goto Exit;
241*d6b92ffaSHans Petter Selasky 
242*d6b92ffaSHans Petter Selasky 	p_sa->sr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SERVICE_RECORD,
243*d6b92ffaSHans Petter Selasky 					   osm_sr_rcv_process, p_sa);
244*d6b92ffaSHans Petter Selasky 	if (p_sa->sr_disp_h == CL_DISP_INVALID_HANDLE)
245*d6b92ffaSHans Petter Selasky 		goto Exit;
246*d6b92ffaSHans Petter Selasky 
247*d6b92ffaSHans Petter Selasky 	p_sa->infr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO,
248*d6b92ffaSHans Petter Selasky 					     osm_infr_rcv_process, p_sa);
249*d6b92ffaSHans Petter Selasky 	if (p_sa->infr_disp_h == CL_DISP_INVALID_HANDLE)
250*d6b92ffaSHans Petter Selasky 		goto Exit;
251*d6b92ffaSHans Petter Selasky 
252*d6b92ffaSHans Petter Selasky 	p_sa->infir_disp_h =
253*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO_RECORD,
254*d6b92ffaSHans Petter Selasky 			     osm_infir_rcv_process, p_sa);
255*d6b92ffaSHans Petter Selasky 	if (p_sa->infir_disp_h == CL_DISP_INVALID_HANDLE)
256*d6b92ffaSHans Petter Selasky 		goto Exit;
257*d6b92ffaSHans Petter Selasky 
258*d6b92ffaSHans Petter Selasky 	p_sa->vlarb_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_VL_ARB_RECORD,
259*d6b92ffaSHans Petter Selasky 					      osm_vlarb_rec_rcv_process, p_sa);
260*d6b92ffaSHans Petter Selasky 	if (p_sa->vlarb_disp_h == CL_DISP_INVALID_HANDLE)
261*d6b92ffaSHans Petter Selasky 		goto Exit;
262*d6b92ffaSHans Petter Selasky 
263*d6b92ffaSHans Petter Selasky 	p_sa->slvl_disp_h =
264*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_SLVL_TBL_RECORD,
265*d6b92ffaSHans Petter Selasky 			     osm_slvl_rec_rcv_process, p_sa);
266*d6b92ffaSHans Petter Selasky 	if (p_sa->slvl_disp_h == CL_DISP_INVALID_HANDLE)
267*d6b92ffaSHans Petter Selasky 		goto Exit;
268*d6b92ffaSHans Petter Selasky 
269*d6b92ffaSHans Petter Selasky 	p_sa->pkey_disp_h =
270*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_PKEY_TBL_RECORD,
271*d6b92ffaSHans Petter Selasky 			     osm_pkey_rec_rcv_process, p_sa);
272*d6b92ffaSHans Petter Selasky 	if (p_sa->pkey_disp_h == CL_DISP_INVALID_HANDLE)
273*d6b92ffaSHans Petter Selasky 		goto Exit;
274*d6b92ffaSHans Petter Selasky 
275*d6b92ffaSHans Petter Selasky 	p_sa->lft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LFT_RECORD,
276*d6b92ffaSHans Petter Selasky 					    osm_lftr_rcv_process, p_sa);
277*d6b92ffaSHans Petter Selasky 	if (p_sa->lft_disp_h == CL_DISP_INVALID_HANDLE)
278*d6b92ffaSHans Petter Selasky 		goto Exit;
279*d6b92ffaSHans Petter Selasky 
280*d6b92ffaSHans Petter Selasky 	p_sa->sir_disp_h =
281*d6b92ffaSHans Petter Selasky 	    cl_disp_register(p_disp, OSM_MSG_MAD_SWITCH_INFO_RECORD,
282*d6b92ffaSHans Petter Selasky 			     osm_sir_rcv_process, p_sa);
283*d6b92ffaSHans Petter Selasky 	if (p_sa->sir_disp_h == CL_DISP_INVALID_HANDLE)
284*d6b92ffaSHans Petter Selasky 		goto Exit;
285*d6b92ffaSHans Petter Selasky 
286*d6b92ffaSHans Petter Selasky 	p_sa->mft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_MFT_RECORD,
287*d6b92ffaSHans Petter Selasky 					    osm_mftr_rcv_process, p_sa);
288*d6b92ffaSHans Petter Selasky 	if (p_sa->mft_disp_h == CL_DISP_INVALID_HANDLE)
289*d6b92ffaSHans Petter Selasky 		goto Exit;
290*d6b92ffaSHans Petter Selasky 
291*d6b92ffaSHans Petter Selasky 	/*
292*d6b92ffaSHans Petter Selasky 	 * When p_set_disp is defined, it means that we use different dispatcher
293*d6b92ffaSHans Petter Selasky 	 * for SA Set requests, and we need to register handlers for it.
294*d6b92ffaSHans Petter Selasky 	 */
295*d6b92ffaSHans Petter Selasky 	if (p_set_disp) {
296*d6b92ffaSHans Petter Selasky 		p_sa->gir_set_disp_h =
297*d6b92ffaSHans Petter Selasky 		    cl_disp_register(p_set_disp, OSM_MSG_MAD_GUIDINFO_RECORD,
298*d6b92ffaSHans Petter Selasky 				     osm_gir_rcv_process, p_sa);
299*d6b92ffaSHans Petter Selasky 		if (p_sa->gir_set_disp_h == CL_DISP_INVALID_HANDLE)
300*d6b92ffaSHans Petter Selasky 			goto Exit;
301*d6b92ffaSHans Petter Selasky 
302*d6b92ffaSHans Petter Selasky 		p_sa->mcmr_set_disp_h =
303*d6b92ffaSHans Petter Selasky 		    cl_disp_register(p_set_disp, OSM_MSG_MAD_MCMEMBER_RECORD,
304*d6b92ffaSHans Petter Selasky 				     osm_mcmr_rcv_process, p_sa);
305*d6b92ffaSHans Petter Selasky 		if (p_sa->mcmr_set_disp_h == CL_DISP_INVALID_HANDLE)
306*d6b92ffaSHans Petter Selasky 			goto Exit;
307*d6b92ffaSHans Petter Selasky 
308*d6b92ffaSHans Petter Selasky 		p_sa->sr_set_disp_h =
309*d6b92ffaSHans Petter Selasky 		    cl_disp_register(p_set_disp, OSM_MSG_MAD_SERVICE_RECORD,
310*d6b92ffaSHans Petter Selasky 				     osm_sr_rcv_process, p_sa);
311*d6b92ffaSHans Petter Selasky 		if (p_sa->sr_set_disp_h == CL_DISP_INVALID_HANDLE)
312*d6b92ffaSHans Petter Selasky 			goto Exit;
313*d6b92ffaSHans Petter Selasky 
314*d6b92ffaSHans Petter Selasky 		p_sa->infr_set_disp_h =
315*d6b92ffaSHans Petter Selasky 		    cl_disp_register(p_set_disp, OSM_MSG_MAD_INFORM_INFO,
316*d6b92ffaSHans Petter Selasky 				     osm_infr_rcv_process, p_sa);
317*d6b92ffaSHans Petter Selasky 		if (p_sa->infr_set_disp_h == CL_DISP_INVALID_HANDLE)
318*d6b92ffaSHans Petter Selasky 			goto Exit;
319*d6b92ffaSHans Petter Selasky 	}
320*d6b92ffaSHans Petter Selasky 
321*d6b92ffaSHans Petter Selasky 	status = IB_SUCCESS;
322*d6b92ffaSHans Petter Selasky Exit:
323*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_log);
324*d6b92ffaSHans Petter Selasky 	return status;
325*d6b92ffaSHans Petter Selasky }
326*d6b92ffaSHans Petter Selasky 
osm_sa_bind(IN osm_sa_t * p_sa,IN ib_net64_t port_guid)327*d6b92ffaSHans Petter Selasky ib_api_status_t osm_sa_bind(IN osm_sa_t * p_sa, IN ib_net64_t port_guid)
328*d6b92ffaSHans Petter Selasky {
329*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
330*d6b92ffaSHans Petter Selasky 
331*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(p_sa->p_log);
332*d6b92ffaSHans Petter Selasky 
333*d6b92ffaSHans Petter Selasky 	status = osm_sa_mad_ctrl_bind(&p_sa->mad_ctrl, port_guid);
334*d6b92ffaSHans Petter Selasky 
335*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
336*d6b92ffaSHans Petter Selasky 		OSM_LOG(p_sa->p_log, OSM_LOG_ERROR, "ERR 4C03: "
337*d6b92ffaSHans Petter Selasky 			"SA MAD Controller bind failed (%s)\n",
338*d6b92ffaSHans Petter Selasky 			ib_get_err_str(status));
339*d6b92ffaSHans Petter Selasky 		goto Exit;
340*d6b92ffaSHans Petter Selasky 	}
341*d6b92ffaSHans Petter Selasky 
342*d6b92ffaSHans Petter Selasky Exit:
343*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(p_sa->p_log);
344*d6b92ffaSHans Petter Selasky 	return status;
345*d6b92ffaSHans Petter Selasky }
346*d6b92ffaSHans Petter Selasky 
osm_sa_send(osm_sa_t * sa,IN osm_madw_t * p_madw,IN boolean_t resp_expected)347*d6b92ffaSHans Petter Selasky ib_api_status_t osm_sa_send(osm_sa_t *sa, IN osm_madw_t * p_madw,
348*d6b92ffaSHans Petter Selasky 			    IN boolean_t resp_expected)
349*d6b92ffaSHans Petter Selasky {
350*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
351*d6b92ffaSHans Petter Selasky 
352*d6b92ffaSHans Petter Selasky 	cl_atomic_inc(&sa->p_subn->p_osm->stats.sa_mads_sent);
353*d6b92ffaSHans Petter Selasky 	status = osm_vendor_send(p_madw->h_bind, p_madw, resp_expected);
354*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
355*d6b92ffaSHans Petter Selasky 		cl_atomic_dec(&sa->p_subn->p_osm->stats.sa_mads_sent);
356*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C04: "
357*d6b92ffaSHans Petter Selasky 			"osm_vendor_send failed, status = %s\n",
358*d6b92ffaSHans Petter Selasky 			ib_get_err_str(status));
359*d6b92ffaSHans Petter Selasky 	}
360*d6b92ffaSHans Petter Selasky 	return status;
361*d6b92ffaSHans Petter Selasky }
362*d6b92ffaSHans Petter Selasky 
osm_sa_send_error(IN osm_sa_t * sa,IN const osm_madw_t * p_madw,IN ib_net16_t sa_status)363*d6b92ffaSHans Petter Selasky void osm_sa_send_error(IN osm_sa_t * sa, IN const osm_madw_t * p_madw,
364*d6b92ffaSHans Petter Selasky 		       IN ib_net16_t sa_status)
365*d6b92ffaSHans Petter Selasky {
366*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_resp_madw;
367*d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_resp_sa_mad;
368*d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
369*d6b92ffaSHans Petter Selasky 
370*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
371*d6b92ffaSHans Petter Selasky 
372*d6b92ffaSHans Petter Selasky 	/* avoid races - if we are exiting - exit */
373*d6b92ffaSHans Petter Selasky 	if (osm_exit_flag) {
374*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
375*d6b92ffaSHans Petter Selasky 			"Ignoring requested send after exit\n");
376*d6b92ffaSHans Petter Selasky 		goto Exit;
377*d6b92ffaSHans Petter Selasky 	}
378*d6b92ffaSHans Petter Selasky 
379*d6b92ffaSHans Petter Selasky 	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool,
380*d6b92ffaSHans Petter Selasky 				       p_madw->h_bind, MAD_BLOCK_SIZE,
381*d6b92ffaSHans Petter Selasky 				       &p_madw->mad_addr);
382*d6b92ffaSHans Petter Selasky 
383*d6b92ffaSHans Petter Selasky 	if (p_resp_madw == NULL) {
384*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C07: "
385*d6b92ffaSHans Petter Selasky 			"Unable to acquire response MAD\n");
386*d6b92ffaSHans Petter Selasky 		goto Exit;
387*d6b92ffaSHans Petter Selasky 	}
388*d6b92ffaSHans Petter Selasky 
389*d6b92ffaSHans Petter Selasky 	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);
390*d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
391*d6b92ffaSHans Petter Selasky 
392*d6b92ffaSHans Petter Selasky 	/*  Copy the MAD header back into the response mad */
393*d6b92ffaSHans Petter Selasky 	*p_resp_sa_mad = *p_sa_mad;
394*d6b92ffaSHans Petter Selasky 	p_resp_sa_mad->status = sa_status;
395*d6b92ffaSHans Petter Selasky 
396*d6b92ffaSHans Petter Selasky 	if (p_resp_sa_mad->method == IB_MAD_METHOD_SET)
397*d6b92ffaSHans Petter Selasky 		p_resp_sa_mad->method = IB_MAD_METHOD_GET;
398*d6b92ffaSHans Petter Selasky 	else if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE)
399*d6b92ffaSHans Petter Selasky 		p_resp_sa_mad->attr_offset = 0;
400*d6b92ffaSHans Petter Selasky 
401*d6b92ffaSHans Petter Selasky 	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
402*d6b92ffaSHans Petter Selasky 
403*d6b92ffaSHans Petter Selasky 	/*
404*d6b92ffaSHans Petter Selasky 	 * C15-0.1.5 - always return SM_Key = 0 (table 185 p 884)
405*d6b92ffaSHans Petter Selasky 	 */
406*d6b92ffaSHans Petter Selasky 	p_resp_sa_mad->sm_key = 0;
407*d6b92ffaSHans Petter Selasky 
408*d6b92ffaSHans Petter Selasky 	/*
409*d6b92ffaSHans Petter Selasky 	 * o15-0.2.7 - The PathRecord Attribute ID shall be used in
410*d6b92ffaSHans Petter Selasky 	 * the response (to a SubnAdmGetMulti(MultiPathRecord)
411*d6b92ffaSHans Petter Selasky 	 */
412*d6b92ffaSHans Petter Selasky 	if (p_resp_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD)
413*d6b92ffaSHans Petter Selasky 		p_resp_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
414*d6b92ffaSHans Petter Selasky 
415*d6b92ffaSHans Petter Selasky 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES))
416*d6b92ffaSHans Petter Selasky 		osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
417*d6b92ffaSHans Petter Selasky 
418*d6b92ffaSHans Petter Selasky 	osm_sa_send(sa, p_resp_madw, FALSE);
419*d6b92ffaSHans Petter Selasky 
420*d6b92ffaSHans Petter Selasky Exit:
421*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
422*d6b92ffaSHans Petter Selasky }
423*d6b92ffaSHans Petter Selasky 
osm_sa_respond(osm_sa_t * sa,osm_madw_t * madw,size_t attr_size,cl_qlist_t * list)424*d6b92ffaSHans Petter Selasky void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size,
425*d6b92ffaSHans Petter Selasky 		    cl_qlist_t *list)
426*d6b92ffaSHans Petter Selasky {
427*d6b92ffaSHans Petter Selasky 	cl_list_item_t *item;
428*d6b92ffaSHans Petter Selasky 	osm_madw_t *resp_madw;
429*d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *sa_mad, *resp_sa_mad;
430*d6b92ffaSHans Petter Selasky 	unsigned num_rec, i;
431*d6b92ffaSHans Petter Selasky #ifndef VENDOR_RMPP_SUPPORT
432*d6b92ffaSHans Petter Selasky 	unsigned trim_num_rec;
433*d6b92ffaSHans Petter Selasky #endif
434*d6b92ffaSHans Petter Selasky 	unsigned char *p;
435*d6b92ffaSHans Petter Selasky 
436*d6b92ffaSHans Petter Selasky 	sa_mad = osm_madw_get_sa_mad_ptr(madw);
437*d6b92ffaSHans Petter Selasky 	num_rec = cl_qlist_count(list);
438*d6b92ffaSHans Petter Selasky 
439*d6b92ffaSHans Petter Selasky 	/*
440*d6b92ffaSHans Petter Selasky 	 * C15-0.1.30:
441*d6b92ffaSHans Petter Selasky 	 * If we do a SubnAdmGet and got more than one record it is an error!
442*d6b92ffaSHans Petter Selasky 	 */
443*d6b92ffaSHans Petter Selasky 	if (sa_mad->method == IB_MAD_METHOD_GET && num_rec > 1) {
444*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C05: "
445*d6b92ffaSHans Petter Selasky 			"Got %u records for SubnAdmGet(%s) comp_mask 0x%016" PRIx64
446*d6b92ffaSHans Petter Selasky 			"from requester LID %u\n",
447*d6b92ffaSHans Petter Selasky 			num_rec, ib_get_sa_attr_str(sa_mad->attr_id),
448*d6b92ffaSHans Petter Selasky 			cl_ntoh64(sa_mad->comp_mask),
449*d6b92ffaSHans Petter Selasky 			cl_ntoh16(madw->mad_addr.dest_lid));
450*d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
451*d6b92ffaSHans Petter Selasky 		goto Exit;
452*d6b92ffaSHans Petter Selasky 	}
453*d6b92ffaSHans Petter Selasky 
454*d6b92ffaSHans Petter Selasky #ifndef VENDOR_RMPP_SUPPORT
455*d6b92ffaSHans Petter Selasky 	trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / attr_size;
456*d6b92ffaSHans Petter Selasky 	if (trim_num_rec < num_rec) {
457*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
458*d6b92ffaSHans Petter Selasky 			"Number of records:%u trimmed to:%u to fit in one MAD\n",
459*d6b92ffaSHans Petter Selasky 			num_rec, trim_num_rec);
460*d6b92ffaSHans Petter Selasky 		num_rec = trim_num_rec;
461*d6b92ffaSHans Petter Selasky 	}
462*d6b92ffaSHans Petter Selasky #endif
463*d6b92ffaSHans Petter Selasky 
464*d6b92ffaSHans Petter Selasky 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec);
465*d6b92ffaSHans Petter Selasky 
466*d6b92ffaSHans Petter Selasky 	if (sa_mad->method == IB_MAD_METHOD_GET && num_rec == 0) {
467*d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RECORDS);
468*d6b92ffaSHans Petter Selasky 		goto Exit;
469*d6b92ffaSHans Petter Selasky 	}
470*d6b92ffaSHans Petter Selasky 
471*d6b92ffaSHans Petter Selasky 	/*
472*d6b92ffaSHans Petter Selasky 	 * Get a MAD to reply. Address of Mad is in the received mad_wrapper
473*d6b92ffaSHans Petter Selasky 	 */
474*d6b92ffaSHans Petter Selasky 	resp_madw = osm_mad_pool_get(sa->p_mad_pool, madw->h_bind,
475*d6b92ffaSHans Petter Selasky 				     num_rec * attr_size + IB_SA_MAD_HDR_SIZE,
476*d6b92ffaSHans Petter Selasky 				     &madw->mad_addr);
477*d6b92ffaSHans Petter Selasky 	if (!resp_madw) {
478*d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C06: "
479*d6b92ffaSHans Petter Selasky 			"osm_mad_pool_get failed\n");
480*d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RESOURCES);
481*d6b92ffaSHans Petter Selasky 		goto Exit;
482*d6b92ffaSHans Petter Selasky 	}
483*d6b92ffaSHans Petter Selasky 
484*d6b92ffaSHans Petter Selasky 	resp_sa_mad = osm_madw_get_sa_mad_ptr(resp_madw);
485*d6b92ffaSHans Petter Selasky 
486*d6b92ffaSHans Petter Selasky 	/*
487*d6b92ffaSHans Petter Selasky 	   Copy the MAD header back into the response mad.
488*d6b92ffaSHans Petter Selasky 	   Set the 'R' bit and the payload length,
489*d6b92ffaSHans Petter Selasky 	   Then copy all records from the list into the response payload.
490*d6b92ffaSHans Petter Selasky 	 */
491*d6b92ffaSHans Petter Selasky 
492*d6b92ffaSHans Petter Selasky 	memcpy(resp_sa_mad, sa_mad, IB_SA_MAD_HDR_SIZE);
493*d6b92ffaSHans Petter Selasky 	if (resp_sa_mad->method == IB_MAD_METHOD_SET)
494*d6b92ffaSHans Petter Selasky 		resp_sa_mad->method = IB_MAD_METHOD_GET;
495*d6b92ffaSHans Petter Selasky 	resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
496*d6b92ffaSHans Petter Selasky 	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
497*d6b92ffaSHans Petter Selasky 	resp_sa_mad->sm_key = 0;
498*d6b92ffaSHans Petter Selasky 
499*d6b92ffaSHans Petter Selasky 	/* Fill in the offset (paylen will be done by the rmpp SAR) */
500*d6b92ffaSHans Petter Selasky 	resp_sa_mad->attr_offset = num_rec ? ib_get_attr_offset(attr_size) : 0;
501*d6b92ffaSHans Petter Selasky 
502*d6b92ffaSHans Petter Selasky 	p = ib_sa_mad_get_payload_ptr(resp_sa_mad);
503*d6b92ffaSHans Petter Selasky 
504*d6b92ffaSHans Petter Selasky #ifndef VENDOR_RMPP_SUPPORT
505*d6b92ffaSHans Petter Selasky 	/* we support only one packet RMPP - so we will set the first and
506*d6b92ffaSHans Petter Selasky 	   last flags for gettable */
507*d6b92ffaSHans Petter Selasky 	if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) {
508*d6b92ffaSHans Petter Selasky 		resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
509*d6b92ffaSHans Petter Selasky 		resp_sa_mad->rmpp_flags =
510*d6b92ffaSHans Petter Selasky 		    IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST |
511*d6b92ffaSHans Petter Selasky 		    IB_RMPP_FLAG_ACTIVE;
512*d6b92ffaSHans Petter Selasky 	}
513*d6b92ffaSHans Petter Selasky #else
514*d6b92ffaSHans Petter Selasky 	/* forcefully define the packet as RMPP one */
515*d6b92ffaSHans Petter Selasky 	if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
516*d6b92ffaSHans Petter Selasky 		resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
517*d6b92ffaSHans Petter Selasky #endif
518*d6b92ffaSHans Petter Selasky 
519*d6b92ffaSHans Petter Selasky 	for (i = 0; i < num_rec; i++) {
520*d6b92ffaSHans Petter Selasky 		item = cl_qlist_remove_head(list);
521*d6b92ffaSHans Petter Selasky 		memcpy(p, ((osm_sa_item_t *)item)->resp.data, attr_size);
522*d6b92ffaSHans Petter Selasky 		p += attr_size;
523*d6b92ffaSHans Petter Selasky 		free(item);
524*d6b92ffaSHans Petter Selasky 	}
525*d6b92ffaSHans Petter Selasky 
526*d6b92ffaSHans Petter Selasky 	osm_dump_sa_mad_v2(sa->p_log, resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);
527*d6b92ffaSHans Petter Selasky 	osm_sa_send(sa, resp_madw, FALSE);
528*d6b92ffaSHans Petter Selasky 
529*d6b92ffaSHans Petter Selasky Exit:
530*d6b92ffaSHans Petter Selasky 	/* need to set the mem free ... */
531*d6b92ffaSHans Petter Selasky 	item = cl_qlist_remove_head(list);
532*d6b92ffaSHans Petter Selasky 	while (item != cl_qlist_end(list)) {
533*d6b92ffaSHans Petter Selasky 		free(item);
534*d6b92ffaSHans Petter Selasky 		item = cl_qlist_remove_head(list);
535*d6b92ffaSHans Petter Selasky 	}
536*d6b92ffaSHans Petter Selasky }
537*d6b92ffaSHans Petter Selasky 
538*d6b92ffaSHans Petter Selasky /*
539*d6b92ffaSHans Petter Selasky  *  SA DB Dumper
540*d6b92ffaSHans Petter Selasky  *
541*d6b92ffaSHans Petter Selasky  */
542*d6b92ffaSHans Petter Selasky 
543*d6b92ffaSHans Petter Selasky struct opensm_dump_context {
544*d6b92ffaSHans Petter Selasky 	osm_opensm_t *p_osm;
545*d6b92ffaSHans Petter Selasky 	FILE *file;
546*d6b92ffaSHans Petter Selasky };
547*d6b92ffaSHans Petter Selasky 
548*d6b92ffaSHans Petter Selasky static int
opensm_dump_to_file(osm_opensm_t * p_osm,const char * file_name,void (* dump_func)(osm_opensm_t * p_osm,FILE * file))549*d6b92ffaSHans Petter Selasky opensm_dump_to_file(osm_opensm_t * p_osm, const char *file_name,
550*d6b92ffaSHans Petter Selasky 		    void (*dump_func) (osm_opensm_t * p_osm, FILE * file))
551*d6b92ffaSHans Petter Selasky {
552*d6b92ffaSHans Petter Selasky 	char path[1024];
553*d6b92ffaSHans Petter Selasky 	char path_tmp[1032];
554*d6b92ffaSHans Petter Selasky 	FILE *file;
555*d6b92ffaSHans Petter Selasky 	int fd, status = 0;
556*d6b92ffaSHans Petter Selasky 
557*d6b92ffaSHans Petter Selasky 	snprintf(path, sizeof(path), "%s/%s",
558*d6b92ffaSHans Petter Selasky 		 p_osm->subn.opt.dump_files_dir, file_name);
559*d6b92ffaSHans Petter Selasky 
560*d6b92ffaSHans Petter Selasky 	snprintf(path_tmp, sizeof(path_tmp), "%s.tmp", path);
561*d6b92ffaSHans Petter Selasky 
562*d6b92ffaSHans Petter Selasky 	file = fopen(path_tmp, "w");
563*d6b92ffaSHans Petter Selasky 	if (!file) {
564*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C01: "
565*d6b92ffaSHans Petter Selasky 			"cannot open file \'%s\': %s\n",
566*d6b92ffaSHans Petter Selasky 			path_tmp, strerror(errno));
567*d6b92ffaSHans Petter Selasky 		return -1;
568*d6b92ffaSHans Petter Selasky 	}
569*d6b92ffaSHans Petter Selasky 
570*d6b92ffaSHans Petter Selasky 	if (chmod(path_tmp, S_IRUSR | S_IWUSR)) {
571*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0C: "
572*d6b92ffaSHans Petter Selasky 			"cannot change access permissions of file "
573*d6b92ffaSHans Petter Selasky 			"\'%s\' : %s\n",
574*d6b92ffaSHans Petter Selasky 			path_tmp, strerror(errno));
575*d6b92ffaSHans Petter Selasky 		fclose(file);
576*d6b92ffaSHans Petter Selasky 		return -1;
577*d6b92ffaSHans Petter Selasky 	}
578*d6b92ffaSHans Petter Selasky 
579*d6b92ffaSHans Petter Selasky 	dump_func(p_osm, file);
580*d6b92ffaSHans Petter Selasky 
581*d6b92ffaSHans Petter Selasky 	if (p_osm->subn.opt.fsync_high_avail_files) {
582*d6b92ffaSHans Petter Selasky 		if (fflush(file) == 0) {
583*d6b92ffaSHans Petter Selasky 			fd = fileno(file);
584*d6b92ffaSHans Petter Selasky 			if (fd != -1) {
585*d6b92ffaSHans Petter Selasky 				if (fsync(fd) == -1)
586*d6b92ffaSHans Petter Selasky 					OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
587*d6b92ffaSHans Petter Selasky 						"ERR 4C08: fsync() failed (%s) for %s\n",
588*d6b92ffaSHans Petter Selasky 						strerror(errno), path_tmp);
589*d6b92ffaSHans Petter Selasky 			} else
590*d6b92ffaSHans Petter Selasky 				OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C09: "
591*d6b92ffaSHans Petter Selasky 					"fileno() failed for %s\n", path_tmp);
592*d6b92ffaSHans Petter Selasky 		} else
593*d6b92ffaSHans Petter Selasky 			OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0A: "
594*d6b92ffaSHans Petter Selasky 				"fflush() failed (%s) for %s\n",
595*d6b92ffaSHans Petter Selasky 				strerror(errno), path_tmp);
596*d6b92ffaSHans Petter Selasky 	}
597*d6b92ffaSHans Petter Selasky 
598*d6b92ffaSHans Petter Selasky 	fclose(file);
599*d6b92ffaSHans Petter Selasky 
600*d6b92ffaSHans Petter Selasky 	status = rename(path_tmp, path);
601*d6b92ffaSHans Petter Selasky 	if (status) {
602*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C0B: "
603*d6b92ffaSHans Petter Selasky 			"Failed to rename file:%s (err:%s)\n",
604*d6b92ffaSHans Petter Selasky 			path_tmp, strerror(errno));
605*d6b92ffaSHans Petter Selasky 	}
606*d6b92ffaSHans Petter Selasky 
607*d6b92ffaSHans Petter Selasky 	return status;
608*d6b92ffaSHans Petter Selasky }
609*d6b92ffaSHans Petter Selasky 
mcast_mgr_dump_one_port(cl_map_item_t * p_map_item,void * cxt)610*d6b92ffaSHans Petter Selasky static void mcast_mgr_dump_one_port(cl_map_item_t * p_map_item, void *cxt)
611*d6b92ffaSHans Petter Selasky {
612*d6b92ffaSHans Petter Selasky 	FILE *file = ((struct opensm_dump_context *)cxt)->file;
613*d6b92ffaSHans Petter Selasky 	osm_mcm_alias_guid_t *p_mcm_alias_guid = (osm_mcm_alias_guid_t *) p_map_item;
614*d6b92ffaSHans Petter Selasky 
615*d6b92ffaSHans Petter Selasky 	fprintf(file, "mcm_port: "
616*d6b92ffaSHans Petter Selasky 		"port_gid=0x%016" PRIx64 ":0x%016" PRIx64 " "
617*d6b92ffaSHans Petter Selasky 		"scope_state=0x%02x proxy_join=0x%x" "\n\n",
618*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mcm_alias_guid->port_gid.unicast.prefix),
619*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mcm_alias_guid->port_gid.unicast.interface_id),
620*d6b92ffaSHans Petter Selasky 		p_mcm_alias_guid->scope_state, p_mcm_alias_guid->proxy_join);
621*d6b92ffaSHans Petter Selasky }
622*d6b92ffaSHans Petter Selasky 
sa_dump_one_mgrp(osm_mgrp_t * p_mgrp,void * cxt)623*d6b92ffaSHans Petter Selasky static void sa_dump_one_mgrp(osm_mgrp_t *p_mgrp, void *cxt)
624*d6b92ffaSHans Petter Selasky {
625*d6b92ffaSHans Petter Selasky 	struct opensm_dump_context dump_context;
626*d6b92ffaSHans Petter Selasky 	osm_opensm_t *p_osm = ((struct opensm_dump_context *)cxt)->p_osm;
627*d6b92ffaSHans Petter Selasky 	FILE *file = ((struct opensm_dump_context *)cxt)->file;
628*d6b92ffaSHans Petter Selasky 
629*d6b92ffaSHans Petter Selasky 	fprintf(file, "MC Group 0x%04x %s:"
630*d6b92ffaSHans Petter Selasky 		" mgid=0x%016" PRIx64 ":0x%016" PRIx64
631*d6b92ffaSHans Petter Selasky 		" port_gid=0x%016" PRIx64 ":0x%016" PRIx64
632*d6b92ffaSHans Petter Selasky 		" qkey=0x%08x mlid=0x%04x mtu=0x%02x tclass=0x%02x"
633*d6b92ffaSHans Petter Selasky 		" pkey=0x%04x rate=0x%02x pkt_life=0x%02x sl_flow_hop=0x%08x"
634*d6b92ffaSHans Petter Selasky 		" scope_state=0x%02x proxy_join=0x%x" "\n\n",
635*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_mgrp->mlid),
636*d6b92ffaSHans Petter Selasky 		p_mgrp->well_known ? " (well known)" : "",
637*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix),
638*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id),
639*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.prefix),
640*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.interface_id),
641*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_mgrp->mcmember_rec.qkey),
642*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_mgrp->mcmember_rec.mlid),
643*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.mtu,
644*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.tclass,
645*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_mgrp->mcmember_rec.pkey),
646*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.rate,
647*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.pkt_life,
648*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_mgrp->mcmember_rec.sl_flow_hop),
649*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.scope_state,
650*d6b92ffaSHans Petter Selasky 		p_mgrp->mcmember_rec.proxy_join);
651*d6b92ffaSHans Petter Selasky 
652*d6b92ffaSHans Petter Selasky 	dump_context.p_osm = p_osm;
653*d6b92ffaSHans Petter Selasky 	dump_context.file = file;
654*d6b92ffaSHans Petter Selasky 
655*d6b92ffaSHans Petter Selasky 	cl_qmap_apply_func(&p_mgrp->mcm_alias_port_tbl,
656*d6b92ffaSHans Petter Selasky 			   mcast_mgr_dump_one_port, &dump_context);
657*d6b92ffaSHans Petter Selasky }
658*d6b92ffaSHans Petter Selasky 
sa_dump_one_inform(cl_list_item_t * p_list_item,void * cxt)659*d6b92ffaSHans Petter Selasky static void sa_dump_one_inform(cl_list_item_t * p_list_item, void *cxt)
660*d6b92ffaSHans Petter Selasky {
661*d6b92ffaSHans Petter Selasky 	FILE *file = ((struct opensm_dump_context *)cxt)->file;
662*d6b92ffaSHans Petter Selasky 	osm_infr_t *p_infr = (osm_infr_t *) p_list_item;
663*d6b92ffaSHans Petter Selasky 	ib_inform_info_record_t *p_iir = &p_infr->inform_record;
664*d6b92ffaSHans Petter Selasky 
665*d6b92ffaSHans Petter Selasky 	fprintf(file, "InformInfo Record:"
666*d6b92ffaSHans Petter Selasky 		" subscriber_gid=0x%016" PRIx64 ":0x%016" PRIx64
667*d6b92ffaSHans Petter Selasky 		" subscriber_enum=0x%x"
668*d6b92ffaSHans Petter Selasky 		" InformInfo:"
669*d6b92ffaSHans Petter Selasky 		" gid=0x%016" PRIx64 ":0x%016" PRIx64
670*d6b92ffaSHans Petter Selasky 		" lid_range_begin=0x%x"
671*d6b92ffaSHans Petter Selasky 		" lid_range_end=0x%x"
672*d6b92ffaSHans Petter Selasky 		" is_generic=0x%x"
673*d6b92ffaSHans Petter Selasky 		" subscribe=0x%x"
674*d6b92ffaSHans Petter Selasky 		" trap_type=0x%x"
675*d6b92ffaSHans Petter Selasky 		" trap_num=0x%x"
676*d6b92ffaSHans Petter Selasky 		" qpn_resp_time_val=0x%x"
677*d6b92ffaSHans Petter Selasky 		" node_type=0x%06x"
678*d6b92ffaSHans Petter Selasky 		" rep_addr: lid=0x%04x path_bits=0x%02x static_rate=0x%02x"
679*d6b92ffaSHans Petter Selasky 		" remote_qp=0x%08x remote_qkey=0x%08x pkey_ix=0x%04x sl=0x%02x"
680*d6b92ffaSHans Petter Selasky 		"\n\n",
681*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_iir->subscriber_gid.unicast.prefix),
682*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_iir->subscriber_gid.unicast.interface_id),
683*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_iir->subscriber_enum),
684*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_iir->inform_info.gid.unicast.prefix),
685*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_iir->inform_info.gid.unicast.interface_id),
686*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_iir->inform_info.lid_range_begin),
687*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_iir->inform_info.lid_range_end),
688*d6b92ffaSHans Petter Selasky 		p_iir->inform_info.is_generic,
689*d6b92ffaSHans Petter Selasky 		p_iir->inform_info.subscribe,
690*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_iir->inform_info.trap_type),
691*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num),
692*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_iir->inform_info.g_or_v.generic.qpn_resp_time_val),
693*d6b92ffaSHans Petter Selasky 		cl_ntoh32(ib_inform_info_get_prod_type(&p_iir->inform_info)),
694*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_infr->report_addr.dest_lid),
695*d6b92ffaSHans Petter Selasky 		p_infr->report_addr.path_bits,
696*d6b92ffaSHans Petter Selasky 		p_infr->report_addr.static_rate,
697*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qp),
698*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qkey),
699*d6b92ffaSHans Petter Selasky 		p_infr->report_addr.addr_type.gsi.pkey_ix,
700*d6b92ffaSHans Petter Selasky 		p_infr->report_addr.addr_type.gsi.service_level);
701*d6b92ffaSHans Petter Selasky }
702*d6b92ffaSHans Petter Selasky 
sa_dump_one_service(cl_list_item_t * p_list_item,void * cxt)703*d6b92ffaSHans Petter Selasky static void sa_dump_one_service(cl_list_item_t * p_list_item, void *cxt)
704*d6b92ffaSHans Petter Selasky {
705*d6b92ffaSHans Petter Selasky 	FILE *file = ((struct opensm_dump_context *)cxt)->file;
706*d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr = (osm_svcr_t *) p_list_item;
707*d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_sr = &p_svcr->service_record;
708*d6b92ffaSHans Petter Selasky 
709*d6b92ffaSHans Petter Selasky 	fprintf(file, "Service Record: id=0x%016" PRIx64
710*d6b92ffaSHans Petter Selasky 		" gid=0x%016" PRIx64 ":0x%016" PRIx64
711*d6b92ffaSHans Petter Selasky 		" pkey=0x%x"
712*d6b92ffaSHans Petter Selasky 		" lease=0x%x"
713*d6b92ffaSHans Petter Selasky 		" key=0x%02x%02x%02x%02x%02x%02x%02x%02x"
714*d6b92ffaSHans Petter Selasky 		":0x%02x%02x%02x%02x%02x%02x%02x%02x"
715*d6b92ffaSHans Petter Selasky 		" name=\'%s\'"
716*d6b92ffaSHans Petter Selasky 		" data8=0x%02x%02x%02x%02x%02x%02x%02x%02x"
717*d6b92ffaSHans Petter Selasky 		":0x%02x%02x%02x%02x%02x%02x%02x%02x"
718*d6b92ffaSHans Petter Selasky 		" data16=0x%04x%04x%04x%04x:0x%04x%04x%04x%04x"
719*d6b92ffaSHans Petter Selasky 		" data32=0x%08x%08x:0x%08x%08x"
720*d6b92ffaSHans Petter Selasky 		" data64=0x%016" PRIx64 ":0x%016" PRIx64
721*d6b92ffaSHans Petter Selasky 		" modified_time=0x%x lease_period=0x%x\n\n",
722*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_sr->service_id),
723*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_sr->service_gid.unicast.prefix),
724*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_sr->service_gid.unicast.interface_id),
725*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_pkey),
726*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_sr->service_lease),
727*d6b92ffaSHans Petter Selasky 		p_sr->service_key[0], p_sr->service_key[1],
728*d6b92ffaSHans Petter Selasky 		p_sr->service_key[2], p_sr->service_key[3],
729*d6b92ffaSHans Petter Selasky 		p_sr->service_key[4], p_sr->service_key[5],
730*d6b92ffaSHans Petter Selasky 		p_sr->service_key[6], p_sr->service_key[7],
731*d6b92ffaSHans Petter Selasky 		p_sr->service_key[8], p_sr->service_key[9],
732*d6b92ffaSHans Petter Selasky 		p_sr->service_key[10], p_sr->service_key[11],
733*d6b92ffaSHans Petter Selasky 		p_sr->service_key[12], p_sr->service_key[13],
734*d6b92ffaSHans Petter Selasky 		p_sr->service_key[14], p_sr->service_key[15],
735*d6b92ffaSHans Petter Selasky 		p_sr->service_name,
736*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[0], p_sr->service_data8[1],
737*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[2], p_sr->service_data8[3],
738*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[4], p_sr->service_data8[5],
739*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[6], p_sr->service_data8[7],
740*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[8], p_sr->service_data8[9],
741*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[10], p_sr->service_data8[11],
742*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[12], p_sr->service_data8[13],
743*d6b92ffaSHans Petter Selasky 		p_sr->service_data8[14], p_sr->service_data8[15],
744*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[0]),
745*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[1]),
746*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[2]),
747*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[3]),
748*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[4]),
749*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[5]),
750*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[6]),
751*d6b92ffaSHans Petter Selasky 		cl_ntoh16(p_sr->service_data16[7]),
752*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_sr->service_data32[0]),
753*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_sr->service_data32[1]),
754*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_sr->service_data32[2]),
755*d6b92ffaSHans Petter Selasky 		cl_ntoh32(p_sr->service_data32[3]),
756*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_sr->service_data64[0]),
757*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_sr->service_data64[1]),
758*d6b92ffaSHans Petter Selasky 		p_svcr->modified_time, p_svcr->lease_period);
759*d6b92ffaSHans Petter Selasky }
760*d6b92ffaSHans Petter Selasky 
sa_dump_one_port_guidinfo(cl_map_item_t * p_map_item,void * cxt)761*d6b92ffaSHans Petter Selasky static void sa_dump_one_port_guidinfo(cl_map_item_t * p_map_item, void *cxt)
762*d6b92ffaSHans Petter Selasky {
763*d6b92ffaSHans Petter Selasky 	FILE *file = ((struct opensm_dump_context *)cxt)->file;
764*d6b92ffaSHans Petter Selasky 	osm_port_t *p_port = (osm_port_t *) p_map_item;
765*d6b92ffaSHans Petter Selasky 	uint32_t max_block;
766*d6b92ffaSHans Petter Selasky 	int block_num;
767*d6b92ffaSHans Petter Selasky 
768*d6b92ffaSHans Petter Selasky 	if (!p_port->p_physp->p_guids)
769*d6b92ffaSHans Petter Selasky 		return;
770*d6b92ffaSHans Petter Selasky 
771*d6b92ffaSHans Petter Selasky 	max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
772*d6b92ffaSHans Petter Selasky 		     GUID_TABLE_MAX_ENTRIES;
773*d6b92ffaSHans Petter Selasky 
774*d6b92ffaSHans Petter Selasky 	for (block_num = 0; block_num < max_block; block_num++) {
775*d6b92ffaSHans Petter Selasky 		fprintf(file, "GUIDInfo Record:"
776*d6b92ffaSHans Petter Selasky 			" base_guid=0x%016" PRIx64 " lid=0x%04x block_num=0x%x"
777*d6b92ffaSHans Petter Selasky 			" guid0=0x%016" PRIx64 " guid1=0x%016" PRIx64
778*d6b92ffaSHans Petter Selasky 			" guid2=0x%016" PRIx64 " guid3=0x%016" PRIx64
779*d6b92ffaSHans Petter Selasky 			" guid4=0x%016" PRIx64 " guid5=0x%016" PRIx64
780*d6b92ffaSHans Petter Selasky 			" guid6=0x%016" PRIx64 " guid7=0x%016" PRIx64
781*d6b92ffaSHans Petter Selasky 			"\n\n",
782*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[0]),
783*d6b92ffaSHans Petter Selasky 			cl_ntoh16(osm_port_get_base_lid(p_port)), block_num,
784*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES]),
785*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 1]),
786*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 2]),
787*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 3]),
788*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 4]),
789*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 5]),
790*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 6]),
791*d6b92ffaSHans Petter Selasky 			cl_ntoh64((*p_port->p_physp->p_guids)[block_num * GUID_TABLE_MAX_ENTRIES + 7]));
792*d6b92ffaSHans Petter Selasky 	}
793*d6b92ffaSHans Petter Selasky }
794*d6b92ffaSHans Petter Selasky 
sa_dump_all_sa(osm_opensm_t * p_osm,FILE * file)795*d6b92ffaSHans Petter Selasky static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
796*d6b92ffaSHans Petter Selasky {
797*d6b92ffaSHans Petter Selasky 	struct opensm_dump_context dump_context;
798*d6b92ffaSHans Petter Selasky 	osm_mgrp_t *p_mgrp;
799*d6b92ffaSHans Petter Selasky 
800*d6b92ffaSHans Petter Selasky 	dump_context.p_osm = p_osm;
801*d6b92ffaSHans Petter Selasky 	dump_context.file = file;
802*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump guidinfo\n");
803*d6b92ffaSHans Petter Selasky 	cl_qmap_apply_func(&p_osm->subn.port_guid_tbl,
804*d6b92ffaSHans Petter Selasky 			   sa_dump_one_port_guidinfo, &dump_context);
805*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n");
806*d6b92ffaSHans Petter Selasky 	for (p_mgrp = (osm_mgrp_t *) cl_fmap_head(&p_osm->subn.mgrp_mgid_tbl);
807*d6b92ffaSHans Petter Selasky 	     p_mgrp != (osm_mgrp_t *) cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl);
808*d6b92ffaSHans Petter Selasky 	     p_mgrp = (osm_mgrp_t *) cl_fmap_next(&p_mgrp->map_item))
809*d6b92ffaSHans Petter Selasky 		sa_dump_one_mgrp(p_mgrp, &dump_context);
810*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n");
811*d6b92ffaSHans Petter Selasky 	cl_qlist_apply_func(&p_osm->subn.sa_infr_list,
812*d6b92ffaSHans Petter Selasky 			    sa_dump_one_inform, &dump_context);
813*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services\n");
814*d6b92ffaSHans Petter Selasky 	cl_qlist_apply_func(&p_osm->subn.sa_sr_list,
815*d6b92ffaSHans Petter Selasky 			    sa_dump_one_service, &dump_context);
816*d6b92ffaSHans Petter Selasky }
817*d6b92ffaSHans Petter Selasky 
osm_sa_db_file_dump(osm_opensm_t * p_osm)818*d6b92ffaSHans Petter Selasky int osm_sa_db_file_dump(osm_opensm_t * p_osm)
819*d6b92ffaSHans Petter Selasky {
820*d6b92ffaSHans Petter Selasky 	int res = 1;
821*d6b92ffaSHans Petter Selasky 
822*d6b92ffaSHans Petter Selasky 	cl_plock_acquire(&p_osm->lock);
823*d6b92ffaSHans Petter Selasky 	if (p_osm->sa.dirty) {
824*d6b92ffaSHans Petter Selasky 		res = opensm_dump_to_file(
825*d6b92ffaSHans Petter Selasky 			p_osm, "opensm-sa.dump", sa_dump_all_sa);
826*d6b92ffaSHans Petter Selasky 		if (!res)
827*d6b92ffaSHans Petter Selasky 			p_osm->sa.dirty = FALSE;
828*d6b92ffaSHans Petter Selasky 	}
829*d6b92ffaSHans Petter Selasky 	cl_plock_release(&p_osm->lock);
830*d6b92ffaSHans Petter Selasky 
831*d6b92ffaSHans Petter Selasky 	return res;
832*d6b92ffaSHans Petter Selasky }
833*d6b92ffaSHans Petter Selasky 
834*d6b92ffaSHans Petter Selasky /*
835*d6b92ffaSHans Petter Selasky  *  SA DB Loader
836*d6b92ffaSHans Petter Selasky  */
load_mcgroup(osm_opensm_t * p_osm,ib_net16_t mlid,ib_member_rec_t * p_mcm_rec)837*d6b92ffaSHans Petter Selasky static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
838*d6b92ffaSHans Petter Selasky 				ib_member_rec_t * p_mcm_rec)
839*d6b92ffaSHans Petter Selasky {
840*d6b92ffaSHans Petter Selasky 	ib_net64_t comp_mask;
841*d6b92ffaSHans Petter Selasky 	osm_mgrp_t *p_mgrp;
842*d6b92ffaSHans Petter Selasky 
843*d6b92ffaSHans Petter Selasky 	cl_plock_excl_acquire(&p_osm->lock);
844*d6b92ffaSHans Petter Selasky 
845*d6b92ffaSHans Petter Selasky 	p_mgrp = osm_get_mgrp_by_mgid(&p_osm->subn, &p_mcm_rec->mgid);
846*d6b92ffaSHans Petter Selasky 	if (p_mgrp) {
847*d6b92ffaSHans Petter Selasky 		if (p_mgrp->mlid == mlid) {
848*d6b92ffaSHans Petter Selasky 			OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
849*d6b92ffaSHans Petter Selasky 				"mgrp %04x is already here.", cl_ntoh16(mlid));
850*d6b92ffaSHans Petter Selasky 			goto _out;
851*d6b92ffaSHans Petter Selasky 		}
852*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
853*d6b92ffaSHans Petter Selasky 			"mlid %04x is already used by another MC group. Will "
854*d6b92ffaSHans Petter Selasky 			"request clients reregistration.\n", cl_ntoh16(mlid));
855*d6b92ffaSHans Petter Selasky 		p_mgrp = NULL;
856*d6b92ffaSHans Petter Selasky 		goto _out;
857*d6b92ffaSHans Petter Selasky 	}
858*d6b92ffaSHans Petter Selasky 
859*d6b92ffaSHans Petter Selasky 	comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL
860*d6b92ffaSHans Petter Selasky 	    | IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
861*d6b92ffaSHans Petter Selasky 	if (!(p_mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa,
862*d6b92ffaSHans Petter Selasky 							    comp_mask,
863*d6b92ffaSHans Petter Selasky 							    p_mcm_rec)) ||
864*d6b92ffaSHans Petter Selasky 	    p_mgrp->mlid != mlid) {
865*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
866*d6b92ffaSHans Petter Selasky 			"cannot create MC group with mlid 0x%04x and mgid "
867*d6b92ffaSHans Petter Selasky 			"0x%016" PRIx64 ":0x%016" PRIx64 "\n", cl_ntoh16(mlid),
868*d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_mcm_rec->mgid.unicast.prefix),
869*d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id));
870*d6b92ffaSHans Petter Selasky 		p_mgrp = NULL;
871*d6b92ffaSHans Petter Selasky 	}
872*d6b92ffaSHans Petter Selasky 
873*d6b92ffaSHans Petter Selasky _out:
874*d6b92ffaSHans Petter Selasky 	cl_plock_release(&p_osm->lock);
875*d6b92ffaSHans Petter Selasky 
876*d6b92ffaSHans Petter Selasky 	return p_mgrp;
877*d6b92ffaSHans Petter Selasky }
878*d6b92ffaSHans Petter Selasky 
load_svcr(osm_opensm_t * p_osm,ib_service_record_t * sr,uint32_t modified_time,uint32_t lease_period)879*d6b92ffaSHans Petter Selasky static int load_svcr(osm_opensm_t * p_osm, ib_service_record_t * sr,
880*d6b92ffaSHans Petter Selasky 		     uint32_t modified_time, uint32_t lease_period)
881*d6b92ffaSHans Petter Selasky {
882*d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr;
883*d6b92ffaSHans Petter Selasky 	int ret = 0;
884*d6b92ffaSHans Petter Selasky 
885*d6b92ffaSHans Petter Selasky 	cl_plock_excl_acquire(&p_osm->lock);
886*d6b92ffaSHans Petter Selasky 
887*d6b92ffaSHans Petter Selasky 	if (osm_svcr_get_by_rid(&p_osm->subn, &p_osm->log, sr)) {
888*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
889*d6b92ffaSHans Petter Selasky 			"ServiceRecord already exists\n");
890*d6b92ffaSHans Petter Selasky 		goto _out;
891*d6b92ffaSHans Petter Selasky 	}
892*d6b92ffaSHans Petter Selasky 
893*d6b92ffaSHans Petter Selasky 	if (!(p_svcr = osm_svcr_new(sr))) {
894*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
895*d6b92ffaSHans Petter Selasky 			"cannot allocate new service struct\n");
896*d6b92ffaSHans Petter Selasky 		ret = -1;
897*d6b92ffaSHans Petter Selasky 		goto _out;
898*d6b92ffaSHans Petter Selasky 	}
899*d6b92ffaSHans Petter Selasky 
900*d6b92ffaSHans Petter Selasky 	p_svcr->modified_time = modified_time;
901*d6b92ffaSHans Petter Selasky 	p_svcr->lease_period = lease_period;
902*d6b92ffaSHans Petter Selasky 
903*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding ServiceRecord...\n");
904*d6b92ffaSHans Petter Selasky 
905*d6b92ffaSHans Petter Selasky 	osm_svcr_insert_to_db(&p_osm->subn, &p_osm->log, p_svcr);
906*d6b92ffaSHans Petter Selasky 
907*d6b92ffaSHans Petter Selasky 	if (lease_period != 0xffffffff)
908*d6b92ffaSHans Petter Selasky 		cl_timer_trim(&p_osm->sa.sr_timer, 1000);
909*d6b92ffaSHans Petter Selasky 
910*d6b92ffaSHans Petter Selasky _out:
911*d6b92ffaSHans Petter Selasky 	cl_plock_release(&p_osm->lock);
912*d6b92ffaSHans Petter Selasky 
913*d6b92ffaSHans Petter Selasky 	return ret;
914*d6b92ffaSHans Petter Selasky }
915*d6b92ffaSHans Petter Selasky 
load_infr(osm_opensm_t * p_osm,ib_inform_info_record_t * iir,osm_mad_addr_t * addr)916*d6b92ffaSHans Petter Selasky static int load_infr(osm_opensm_t * p_osm, ib_inform_info_record_t * iir,
917*d6b92ffaSHans Petter Selasky 		     osm_mad_addr_t * addr)
918*d6b92ffaSHans Petter Selasky {
919*d6b92ffaSHans Petter Selasky 	osm_infr_t infr, *p_infr;
920*d6b92ffaSHans Petter Selasky 	int ret = 0;
921*d6b92ffaSHans Petter Selasky 
922*d6b92ffaSHans Petter Selasky 	infr.h_bind = p_osm->sa.mad_ctrl.h_bind;
923*d6b92ffaSHans Petter Selasky 	infr.sa = &p_osm->sa;
924*d6b92ffaSHans Petter Selasky 	/* other possible way to restore mad_addr partially is
925*d6b92ffaSHans Petter Selasky 	   to extract qpn from InformInfo and to find lid by gid */
926*d6b92ffaSHans Petter Selasky 	infr.report_addr = *addr;
927*d6b92ffaSHans Petter Selasky 	infr.inform_record = *iir;
928*d6b92ffaSHans Petter Selasky 
929*d6b92ffaSHans Petter Selasky 	cl_plock_excl_acquire(&p_osm->lock);
930*d6b92ffaSHans Petter Selasky 	if (osm_infr_get_by_rec(&p_osm->subn, &p_osm->log, &infr)) {
931*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
932*d6b92ffaSHans Petter Selasky 			"InformInfo Record already exists\n");
933*d6b92ffaSHans Petter Selasky 		goto _out;
934*d6b92ffaSHans Petter Selasky 	}
935*d6b92ffaSHans Petter Selasky 
936*d6b92ffaSHans Petter Selasky 	if (!(p_infr = osm_infr_new(&infr))) {
937*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
938*d6b92ffaSHans Petter Selasky 			"cannot allocate new infr struct\n");
939*d6b92ffaSHans Petter Selasky 		ret = -1;
940*d6b92ffaSHans Petter Selasky 		goto _out;
941*d6b92ffaSHans Petter Selasky 	}
942*d6b92ffaSHans Petter Selasky 
943*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding InformInfo Record...\n");
944*d6b92ffaSHans Petter Selasky 
945*d6b92ffaSHans Petter Selasky 	osm_infr_insert_to_db(&p_osm->subn, &p_osm->log, p_infr);
946*d6b92ffaSHans Petter Selasky 
947*d6b92ffaSHans Petter Selasky _out:
948*d6b92ffaSHans Petter Selasky 	cl_plock_release(&p_osm->lock);
949*d6b92ffaSHans Petter Selasky 
950*d6b92ffaSHans Petter Selasky 	return ret;
951*d6b92ffaSHans Petter Selasky }
952*d6b92ffaSHans Petter Selasky 
load_guidinfo(osm_opensm_t * p_osm,ib_net64_t base_guid,ib_guidinfo_record_t * gir)953*d6b92ffaSHans Petter Selasky static int load_guidinfo(osm_opensm_t * p_osm, ib_net64_t base_guid,
954*d6b92ffaSHans Petter Selasky 			 ib_guidinfo_record_t *gir)
955*d6b92ffaSHans Petter Selasky {
956*d6b92ffaSHans Petter Selasky 	osm_port_t *p_port;
957*d6b92ffaSHans Petter Selasky 	uint32_t max_block;
958*d6b92ffaSHans Petter Selasky 	int i, ret = 0;
959*d6b92ffaSHans Petter Selasky 	osm_alias_guid_t *p_alias_guid, *p_alias_guid_check;
960*d6b92ffaSHans Petter Selasky 
961*d6b92ffaSHans Petter Selasky 	cl_plock_excl_acquire(&p_osm->lock);
962*d6b92ffaSHans Petter Selasky 
963*d6b92ffaSHans Petter Selasky 	p_port = osm_get_port_by_guid(&p_osm->subn, base_guid);
964*d6b92ffaSHans Petter Selasky 	if (!p_port)
965*d6b92ffaSHans Petter Selasky 		goto _out;
966*d6b92ffaSHans Petter Selasky 
967*d6b92ffaSHans Petter Selasky 	if (!p_port->p_physp->p_guids) {
968*d6b92ffaSHans Petter Selasky 		max_block = (p_port->p_physp->port_info.guid_cap + GUID_TABLE_MAX_ENTRIES - 1) /
969*d6b92ffaSHans Petter Selasky 			     GUID_TABLE_MAX_ENTRIES;
970*d6b92ffaSHans Petter Selasky 		p_port->p_physp->p_guids = calloc(max_block * GUID_TABLE_MAX_ENTRIES,
971*d6b92ffaSHans Petter Selasky 						  sizeof(ib_net64_t));
972*d6b92ffaSHans Petter Selasky 		if (!p_port->p_physp->p_guids) {
973*d6b92ffaSHans Petter Selasky 			OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
974*d6b92ffaSHans Petter Selasky 				"cannot allocate GUID table for port "
975*d6b92ffaSHans Petter Selasky 				"GUID 0x%" PRIx64 "\n",
976*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_port->p_physp->port_guid));
977*d6b92ffaSHans Petter Selasky 			goto _out;
978*d6b92ffaSHans Petter Selasky 		}
979*d6b92ffaSHans Petter Selasky 	}
980*d6b92ffaSHans Petter Selasky 
981*d6b92ffaSHans Petter Selasky 	for (i = 0; i < GUID_TABLE_MAX_ENTRIES; i++) {
982*d6b92ffaSHans Petter Selasky 		if (!gir->guid_info.guid[i])
983*d6b92ffaSHans Petter Selasky 			continue;
984*d6b92ffaSHans Petter Selasky 		/* skip block 0 index 0 */
985*d6b92ffaSHans Petter Selasky 		if (gir->block_num == 0 && i == 0)
986*d6b92ffaSHans Petter Selasky 			continue;
987*d6b92ffaSHans Petter Selasky 		if (gir->block_num * GUID_TABLE_MAX_ENTRIES + i >
988*d6b92ffaSHans Petter Selasky 		    p_port->p_physp->port_info.guid_cap)
989*d6b92ffaSHans Petter Selasky 			break;
990*d6b92ffaSHans Petter Selasky 
991*d6b92ffaSHans Petter Selasky 		p_alias_guid = osm_alias_guid_new(gir->guid_info.guid[i],
992*d6b92ffaSHans Petter Selasky 						  p_port);
993*d6b92ffaSHans Petter Selasky 		if (!p_alias_guid) {
994*d6b92ffaSHans Petter Selasky 			OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
995*d6b92ffaSHans Petter Selasky 				"Alias guid %d memory allocation failed"
996*d6b92ffaSHans Petter Selasky 				" for port GUID 0x%" PRIx64 "\n",
997*d6b92ffaSHans Petter Selasky 				gir->block_num * GUID_TABLE_MAX_ENTRIES + i,
998*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_port->p_physp->port_guid));
999*d6b92ffaSHans Petter Selasky 			goto _out;
1000*d6b92ffaSHans Petter Selasky 		}
1001*d6b92ffaSHans Petter Selasky 
1002*d6b92ffaSHans Petter Selasky 		p_alias_guid_check =
1003*d6b92ffaSHans Petter Selasky 			(osm_alias_guid_t *) cl_qmap_insert(&p_osm->subn.alias_port_guid_tbl,
1004*d6b92ffaSHans Petter Selasky 							    p_alias_guid->alias_guid,
1005*d6b92ffaSHans Petter Selasky 							    &p_alias_guid->map_item);
1006*d6b92ffaSHans Petter Selasky 		if (p_alias_guid_check != p_alias_guid) {
1007*d6b92ffaSHans Petter Selasky 			/* alias GUID is a duplicate */
1008*d6b92ffaSHans Petter Selasky 			OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
1009*d6b92ffaSHans Petter Selasky 				"Duplicate alias port GUID 0x%" PRIx64
1010*d6b92ffaSHans Petter Selasky 				" index %d base port GUID 0x%" PRIx64 "\n",
1011*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_alias_guid->alias_guid),
1012*d6b92ffaSHans Petter Selasky 				gir->block_num * GUID_TABLE_MAX_ENTRIES + i,
1013*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_alias_guid->p_base_port->guid));
1014*d6b92ffaSHans Petter Selasky 			osm_alias_guid_delete(&p_alias_guid);
1015*d6b92ffaSHans Petter Selasky 			goto _out;
1016*d6b92ffaSHans Petter Selasky 		}
1017*d6b92ffaSHans Petter Selasky 	}
1018*d6b92ffaSHans Petter Selasky 
1019*d6b92ffaSHans Petter Selasky 	memcpy(&(*p_port->p_physp->p_guids)[gir->block_num * GUID_TABLE_MAX_ENTRIES],
1020*d6b92ffaSHans Petter Selasky 	       &gir->guid_info, sizeof(ib_guid_info_t));
1021*d6b92ffaSHans Petter Selasky 
1022*d6b92ffaSHans Petter Selasky 	osm_queue_guidinfo(&p_osm->sa, p_port, gir->block_num);
1023*d6b92ffaSHans Petter Selasky 
1024*d6b92ffaSHans Petter Selasky _out:
1025*d6b92ffaSHans Petter Selasky 	cl_plock_release(&p_osm->lock);
1026*d6b92ffaSHans Petter Selasky 
1027*d6b92ffaSHans Petter Selasky 	return ret;
1028*d6b92ffaSHans Petter Selasky }
1029*d6b92ffaSHans Petter Selasky 
1030*d6b92ffaSHans Petter Selasky #define UNPACK_FUNC(name,x) \
1031*d6b92ffaSHans Petter Selasky static int unpack_##name##x(char *p, uint##x##_t *val_ptr) \
1032*d6b92ffaSHans Petter Selasky { \
1033*d6b92ffaSHans Petter Selasky 	char *q; \
1034*d6b92ffaSHans Petter Selasky 	unsigned long long num; \
1035*d6b92ffaSHans Petter Selasky 	num = strtoull(p, &q, 16); \
1036*d6b92ffaSHans Petter Selasky 	if (num > ~((uint##x##_t)0x0) \
1037*d6b92ffaSHans Petter Selasky 	    || q == p || (!isspace(*q) && *q != ':')) { \
1038*d6b92ffaSHans Petter Selasky 		*val_ptr = 0; \
1039*d6b92ffaSHans Petter Selasky 		return -1; \
1040*d6b92ffaSHans Petter Selasky 	} \
1041*d6b92ffaSHans Petter Selasky 	*val_ptr = cl_hton##x((uint##x##_t)num); \
1042*d6b92ffaSHans Petter Selasky 	return (int)(q - p); \
1043*d6b92ffaSHans Petter Selasky }
1044*d6b92ffaSHans Petter Selasky 
1045*d6b92ffaSHans Petter Selasky #define cl_hton8(x) (x)
1046*d6b92ffaSHans Petter Selasky 
1047*d6b92ffaSHans Petter Selasky UNPACK_FUNC(net, 8);
1048*d6b92ffaSHans Petter Selasky UNPACK_FUNC(net, 16);
1049*d6b92ffaSHans Petter Selasky UNPACK_FUNC(net, 32);
1050*d6b92ffaSHans Petter Selasky UNPACK_FUNC(net, 64);
1051*d6b92ffaSHans Petter Selasky 
unpack_string(char * p,uint8_t * buf,unsigned len)1052*d6b92ffaSHans Petter Selasky static int unpack_string(char *p, uint8_t * buf, unsigned len)
1053*d6b92ffaSHans Petter Selasky {
1054*d6b92ffaSHans Petter Selasky 	char *q = p;
1055*d6b92ffaSHans Petter Selasky 	char delim = ' ';
1056*d6b92ffaSHans Petter Selasky 
1057*d6b92ffaSHans Petter Selasky 	if (*q == '\'' || *q == '\"')
1058*d6b92ffaSHans Petter Selasky 		delim = *q++;
1059*d6b92ffaSHans Petter Selasky 	while (--len && *q && *q != delim)
1060*d6b92ffaSHans Petter Selasky 		*buf++ = *q++;
1061*d6b92ffaSHans Petter Selasky 	*buf = '\0';
1062*d6b92ffaSHans Petter Selasky 	if (*q == delim && delim != ' ')
1063*d6b92ffaSHans Petter Selasky 		q++;
1064*d6b92ffaSHans Petter Selasky 	return (int)(q - p);
1065*d6b92ffaSHans Petter Selasky }
1066*d6b92ffaSHans Petter Selasky 
unpack_string64(char * p,uint8_t * buf)1067*d6b92ffaSHans Petter Selasky static int unpack_string64(char *p, uint8_t * buf)
1068*d6b92ffaSHans Petter Selasky {
1069*d6b92ffaSHans Petter Selasky 	return unpack_string(p, buf, 64);
1070*d6b92ffaSHans Petter Selasky }
1071*d6b92ffaSHans Petter Selasky 
1072*d6b92ffaSHans Petter Selasky #define PARSE_AHEAD(p, x, name, val_ptr) { int _ret; \
1073*d6b92ffaSHans Petter Selasky 	p = strstr(p, name); \
1074*d6b92ffaSHans Petter Selasky 	if (!p) { \
1075*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \
1076*d6b92ffaSHans Petter Selasky 			"PARSE ERROR: %s:%u: cannot find \"%s\" string\n", \
1077*d6b92ffaSHans Petter Selasky 			file_name, lineno, (name)); \
1078*d6b92ffaSHans Petter Selasky 		ret = -2; \
1079*d6b92ffaSHans Petter Selasky 		goto _error; \
1080*d6b92ffaSHans Petter Selasky 	} \
1081*d6b92ffaSHans Petter Selasky 	p += strlen(name); \
1082*d6b92ffaSHans Petter Selasky 	_ret = unpack_##x(p, (val_ptr)); \
1083*d6b92ffaSHans Petter Selasky 	if (_ret < 0) { \
1084*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \
1085*d6b92ffaSHans Petter Selasky 			"PARSE ERROR: %s:%u: cannot parse "#x" value " \
1086*d6b92ffaSHans Petter Selasky 			"after \"%s\"\n", file_name, lineno, (name)); \
1087*d6b92ffaSHans Petter Selasky 		ret = _ret; \
1088*d6b92ffaSHans Petter Selasky 		goto _error; \
1089*d6b92ffaSHans Petter Selasky 	} \
1090*d6b92ffaSHans Petter Selasky 	p += _ret; \
1091*d6b92ffaSHans Petter Selasky }
1092*d6b92ffaSHans Petter Selasky 
sa_db_file_load_handle_mgrp(osm_opensm_t * p_osm,osm_mgrp_t * p_mgrp)1093*d6b92ffaSHans Petter Selasky static void sa_db_file_load_handle_mgrp(osm_opensm_t * p_osm,
1094*d6b92ffaSHans Petter Selasky 					osm_mgrp_t * p_mgrp)
1095*d6b92ffaSHans Petter Selasky {
1096*d6b92ffaSHans Petter Selasky 	/* decide whether to delete the mgrp object or not */
1097*d6b92ffaSHans Petter Selasky 	if (p_mgrp->full_members == 0 && !p_mgrp->well_known) {
1098*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
1099*d6b92ffaSHans Petter Selasky 			"Closing MC group 0x%016" PRIx64 ":0x%016" PRIx64
1100*d6b92ffaSHans Petter Selasky 			" - no full members were added to not well known "
1101*d6b92ffaSHans Petter Selasky 			"group\n",
1102*d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix),
1103*d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id));
1104*d6b92ffaSHans Petter Selasky 		osm_mgrp_cleanup(&p_osm->subn, p_mgrp);
1105*d6b92ffaSHans Petter Selasky 	}
1106*d6b92ffaSHans Petter Selasky }
1107*d6b92ffaSHans Petter Selasky 
osm_sa_db_file_load(osm_opensm_t * p_osm)1108*d6b92ffaSHans Petter Selasky int osm_sa_db_file_load(osm_opensm_t * p_osm)
1109*d6b92ffaSHans Petter Selasky {
1110*d6b92ffaSHans Petter Selasky 	char line[1024];
1111*d6b92ffaSHans Petter Selasky 	char *file_name;
1112*d6b92ffaSHans Petter Selasky 	FILE *file;
1113*d6b92ffaSHans Petter Selasky 	int ret = 0;
1114*d6b92ffaSHans Petter Selasky 	osm_mgrp_t *p_next_mgrp = NULL;
1115*d6b92ffaSHans Petter Selasky 	osm_mgrp_t *p_prev_mgrp = NULL;
1116*d6b92ffaSHans Petter Selasky 	unsigned rereg_clients = 0;
1117*d6b92ffaSHans Petter Selasky 	unsigned lineno;
1118*d6b92ffaSHans Petter Selasky 
1119*d6b92ffaSHans Petter Selasky 	if (!p_osm->subn.first_time_master_sweep) {
1120*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
1121*d6b92ffaSHans Petter Selasky 			"Not first sweep - skip SA DB restore\n");
1122*d6b92ffaSHans Petter Selasky 		return 0;
1123*d6b92ffaSHans Petter Selasky 	}
1124*d6b92ffaSHans Petter Selasky 
1125*d6b92ffaSHans Petter Selasky 	file_name = p_osm->subn.opt.sa_db_file;
1126*d6b92ffaSHans Petter Selasky 	if (!file_name) {
1127*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
1128*d6b92ffaSHans Petter Selasky 			"sa db file name is not specified. Skip restore\n");
1129*d6b92ffaSHans Petter Selasky 		return 0;
1130*d6b92ffaSHans Petter Selasky 	}
1131*d6b92ffaSHans Petter Selasky 
1132*d6b92ffaSHans Petter Selasky 	file = fopen(file_name, "r");
1133*d6b92ffaSHans Petter Selasky 	if (!file) {
1134*d6b92ffaSHans Petter Selasky 		OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS, "ERR 4C02: "
1135*d6b92ffaSHans Petter Selasky 			"Can't open sa db file \'%s\'. Skip restoring\n",
1136*d6b92ffaSHans Petter Selasky 			file_name);
1137*d6b92ffaSHans Petter Selasky 		return -1;
1138*d6b92ffaSHans Petter Selasky 	}
1139*d6b92ffaSHans Petter Selasky 
1140*d6b92ffaSHans Petter Selasky 	OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
1141*d6b92ffaSHans Petter Selasky 		"Restoring SA DB from file \'%s\'\n",
1142*d6b92ffaSHans Petter Selasky 		file_name);
1143*d6b92ffaSHans Petter Selasky 
1144*d6b92ffaSHans Petter Selasky 	lineno = 0;
1145*d6b92ffaSHans Petter Selasky 
1146*d6b92ffaSHans Petter Selasky 	while (fgets(line, sizeof(line) - 1, file) != NULL) {
1147*d6b92ffaSHans Petter Selasky 		char *p;
1148*d6b92ffaSHans Petter Selasky 		uint8_t val;
1149*d6b92ffaSHans Petter Selasky 
1150*d6b92ffaSHans Petter Selasky 		lineno++;
1151*d6b92ffaSHans Petter Selasky 
1152*d6b92ffaSHans Petter Selasky 		p = line;
1153*d6b92ffaSHans Petter Selasky 		while (isspace(*p))
1154*d6b92ffaSHans Petter Selasky 			p++;
1155*d6b92ffaSHans Petter Selasky 
1156*d6b92ffaSHans Petter Selasky 		if (*p == '#')
1157*d6b92ffaSHans Petter Selasky 			continue;
1158*d6b92ffaSHans Petter Selasky 
1159*d6b92ffaSHans Petter Selasky 		if (!strncmp(p, "MC Group", 8)) {
1160*d6b92ffaSHans Petter Selasky 			ib_member_rec_t mcm_rec;
1161*d6b92ffaSHans Petter Selasky 			ib_net16_t mlid;
1162*d6b92ffaSHans Petter Selasky 
1163*d6b92ffaSHans Petter Selasky 			p_next_mgrp = NULL;
1164*d6b92ffaSHans Petter Selasky 			memset(&mcm_rec, 0, sizeof(mcm_rec));
1165*d6b92ffaSHans Petter Selasky 
1166*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " 0x", &mlid);
1167*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " mgid=0x",
1168*d6b92ffaSHans Petter Selasky 				    &mcm_rec.mgid.unicast.prefix);
1169*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1170*d6b92ffaSHans Petter Selasky 				    &mcm_rec.mgid.unicast.interface_id);
1171*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " port_gid=0x",
1172*d6b92ffaSHans Petter Selasky 				    &mcm_rec.port_gid.unicast.prefix);
1173*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1174*d6b92ffaSHans Petter Selasky 				    &mcm_rec.port_gid.unicast.interface_id);
1175*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " qkey=0x", &mcm_rec.qkey);
1176*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " mlid=0x", &mcm_rec.mlid);
1177*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " mtu=0x", &mcm_rec.mtu);
1178*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " tclass=0x", &mcm_rec.tclass);
1179*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " pkey=0x", &mcm_rec.pkey);
1180*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " rate=0x", &mcm_rec.rate);
1181*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " pkt_life=0x", &mcm_rec.pkt_life);
1182*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " sl_flow_hop=0x",
1183*d6b92ffaSHans Petter Selasky 				    &mcm_rec.sl_flow_hop);
1184*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " scope_state=0x",
1185*d6b92ffaSHans Petter Selasky 				    &mcm_rec.scope_state);
1186*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " proxy_join=0x", &val);
1187*d6b92ffaSHans Petter Selasky 			mcm_rec.proxy_join = val;
1188*d6b92ffaSHans Petter Selasky 
1189*d6b92ffaSHans Petter Selasky 			p_next_mgrp = load_mcgroup(p_osm, mlid, &mcm_rec);
1190*d6b92ffaSHans Petter Selasky 			if (!p_next_mgrp)
1191*d6b92ffaSHans Petter Selasky 				rereg_clients = 1;
1192*d6b92ffaSHans Petter Selasky 			if (cl_ntoh16(mlid) > p_osm->sm.mlids_init_max)
1193*d6b92ffaSHans Petter Selasky 				p_osm->sm.mlids_init_max = cl_ntoh16(mlid);
1194*d6b92ffaSHans Petter Selasky 		} else if (p_next_mgrp && !strncmp(p, "mcm_port", 8)) {
1195*d6b92ffaSHans Petter Selasky 			ib_member_rec_t mcmr;
1196*d6b92ffaSHans Petter Selasky 			ib_net64_t guid;
1197*d6b92ffaSHans Petter Selasky 			osm_port_t *port;
1198*d6b92ffaSHans Petter Selasky 			boolean_t proxy;
1199*d6b92ffaSHans Petter Selasky 
1200*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " port_gid=0x",
1201*d6b92ffaSHans Petter Selasky 				    &mcmr.port_gid.unicast.prefix);
1202*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1203*d6b92ffaSHans Petter Selasky 				    &mcmr.port_gid.unicast.interface_id);
1204*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " scope_state=0x", &mcmr.scope_state);
1205*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " proxy_join=0x", &val);
1206*d6b92ffaSHans Petter Selasky 			proxy = val;
1207*d6b92ffaSHans Petter Selasky 
1208*d6b92ffaSHans Petter Selasky 			guid = mcmr.port_gid.unicast.interface_id;
1209*d6b92ffaSHans Petter Selasky 			port = osm_get_port_by_alias_guid(&p_osm->subn, guid);
1210*d6b92ffaSHans Petter Selasky 			if (port &&
1211*d6b92ffaSHans Petter Selasky 			    cl_qmap_get(&p_next_mgrp->mcm_port_tbl, guid) ==
1212*d6b92ffaSHans Petter Selasky 			    cl_qmap_end(&p_next_mgrp->mcm_port_tbl) &&
1213*d6b92ffaSHans Petter Selasky 			    !osm_mgrp_add_port(&p_osm->subn, &p_osm->log,
1214*d6b92ffaSHans Petter Selasky 						p_next_mgrp, port, &mcmr, proxy))
1215*d6b92ffaSHans Petter Selasky 				rereg_clients = 1;
1216*d6b92ffaSHans Petter Selasky 		} else if (!strncmp(p, "Service Record:", 15)) {
1217*d6b92ffaSHans Petter Selasky 			ib_service_record_t s_rec;
1218*d6b92ffaSHans Petter Selasky 			uint32_t modified_time, lease_period;
1219*d6b92ffaSHans Petter Selasky 
1220*d6b92ffaSHans Petter Selasky 			p_next_mgrp = NULL;
1221*d6b92ffaSHans Petter Selasky 			memset(&s_rec, 0, sizeof(s_rec));
1222*d6b92ffaSHans Petter Selasky 
1223*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " id=0x", &s_rec.service_id);
1224*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " gid=0x",
1225*d6b92ffaSHans Petter Selasky 				    &s_rec.service_gid.unicast.prefix);
1226*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1227*d6b92ffaSHans Petter Selasky 				    &s_rec.service_gid.unicast.interface_id);
1228*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " pkey=0x", &s_rec.service_pkey);
1229*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " lease=0x",
1230*d6b92ffaSHans Petter Selasky 				    &s_rec.service_lease);
1231*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " key=0x",
1232*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_key[0]));
1233*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1234*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_key[8]));
1235*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, string64, " name=", s_rec.service_name);
1236*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " data8=0x",
1237*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data8[0]));
1238*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1239*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data8[8]));
1240*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " data16=0x",
1241*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data16[0]));
1242*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1243*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data16[4]));
1244*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " data32=0x",
1245*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data32[0]));
1246*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1247*d6b92ffaSHans Petter Selasky 				    (ib_net64_t *) (&s_rec.service_data32[2]));
1248*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " data64=0x",
1249*d6b92ffaSHans Petter Selasky 				    &s_rec.service_data64[0]);
1250*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x", &s_rec.service_data64[1]);
1251*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " modified_time=0x",
1252*d6b92ffaSHans Petter Selasky 				    &modified_time);
1253*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " lease_period=0x",
1254*d6b92ffaSHans Petter Selasky 				    &lease_period);
1255*d6b92ffaSHans Petter Selasky 
1256*d6b92ffaSHans Petter Selasky 			if (load_svcr(p_osm, &s_rec, cl_ntoh32(modified_time),
1257*d6b92ffaSHans Petter Selasky 				      cl_ntoh32(lease_period)))
1258*d6b92ffaSHans Petter Selasky 				rereg_clients = 1;
1259*d6b92ffaSHans Petter Selasky 		} else if (!strncmp(p, "InformInfo Record:", 18)) {
1260*d6b92ffaSHans Petter Selasky 			ib_inform_info_record_t i_rec;
1261*d6b92ffaSHans Petter Selasky 			osm_mad_addr_t rep_addr;
1262*d6b92ffaSHans Petter Selasky 			ib_net16_t val16;
1263*d6b92ffaSHans Petter Selasky 
1264*d6b92ffaSHans Petter Selasky 			p_next_mgrp = NULL;
1265*d6b92ffaSHans Petter Selasky 			memset(&i_rec, 0, sizeof(i_rec));
1266*d6b92ffaSHans Petter Selasky 			memset(&rep_addr, 0, sizeof(rep_addr));
1267*d6b92ffaSHans Petter Selasky 
1268*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " subscriber_gid=0x",
1269*d6b92ffaSHans Petter Selasky 				    &i_rec.subscriber_gid.unicast.prefix);
1270*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1271*d6b92ffaSHans Petter Selasky 				    &i_rec.subscriber_gid.unicast.interface_id);
1272*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " subscriber_enum=0x",
1273*d6b92ffaSHans Petter Selasky 				    &i_rec.subscriber_enum);
1274*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " gid=0x",
1275*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.gid.unicast.prefix);
1276*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, ":0x",
1277*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.gid.unicast.
1278*d6b92ffaSHans Petter Selasky 				    interface_id);
1279*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " lid_range_begin=0x",
1280*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.lid_range_begin);
1281*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " lid_range_end=0x",
1282*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.lid_range_end);
1283*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " is_generic=0x",
1284*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.is_generic);
1285*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " subscribe=0x",
1286*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.subscribe);
1287*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " trap_type=0x",
1288*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.trap_type);
1289*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " trap_num=0x",
1290*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.g_or_v.generic.trap_num);
1291*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " qpn_resp_time_val=0x",
1292*d6b92ffaSHans Petter Selasky 				    &i_rec.inform_info.g_or_v.generic.
1293*d6b92ffaSHans Petter Selasky 				    qpn_resp_time_val);
1294*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " node_type=0x",
1295*d6b92ffaSHans Petter Selasky 				    (uint32_t *) & i_rec.inform_info.g_or_v.
1296*d6b92ffaSHans Petter Selasky 				    generic.reserved2);
1297*d6b92ffaSHans Petter Selasky 
1298*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " rep_addr: lid=0x",
1299*d6b92ffaSHans Petter Selasky 				    &rep_addr.dest_lid);
1300*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " path_bits=0x",
1301*d6b92ffaSHans Petter Selasky 				    &rep_addr.path_bits);
1302*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " static_rate=0x",
1303*d6b92ffaSHans Petter Selasky 				    &rep_addr.static_rate);
1304*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " remote_qp=0x",
1305*d6b92ffaSHans Petter Selasky 				    &rep_addr.addr_type.gsi.remote_qp);
1306*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net32, " remote_qkey=0x",
1307*d6b92ffaSHans Petter Selasky 				    &rep_addr.addr_type.gsi.remote_qkey);
1308*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " pkey_ix=0x", &val16);
1309*d6b92ffaSHans Petter Selasky 			rep_addr.addr_type.gsi.pkey_ix = cl_ntoh16(val16);
1310*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " sl=0x",
1311*d6b92ffaSHans Petter Selasky 				    &rep_addr.addr_type.gsi.service_level);
1312*d6b92ffaSHans Petter Selasky 
1313*d6b92ffaSHans Petter Selasky 			if (load_infr(p_osm, &i_rec, &rep_addr))
1314*d6b92ffaSHans Petter Selasky 				rereg_clients = 1;
1315*d6b92ffaSHans Petter Selasky 		} else if (!strncmp(p, "GUIDInfo Record:", 16)) {
1316*d6b92ffaSHans Petter Selasky 			ib_guidinfo_record_t gi_rec;
1317*d6b92ffaSHans Petter Selasky 			ib_net64_t base_guid;
1318*d6b92ffaSHans Petter Selasky 
1319*d6b92ffaSHans Petter Selasky 			p_next_mgrp = NULL;
1320*d6b92ffaSHans Petter Selasky 			memset(&gi_rec, 0, sizeof(gi_rec));
1321*d6b92ffaSHans Petter Selasky 
1322*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " base_guid=0x", &base_guid);
1323*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net16, " lid=0x", &gi_rec.lid);
1324*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net8, " block_num=0x",
1325*d6b92ffaSHans Petter Selasky 				    &gi_rec.block_num);
1326*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid0=0x",
1327*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[0]);
1328*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid1=0x",
1329*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[1]);
1330*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid2=0x",
1331*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[2]);
1332*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid3=0x",
1333*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[3]);
1334*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid4=0x",
1335*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[4]);
1336*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid5=0x",
1337*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[5]);
1338*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid6=0x",
1339*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[6]);
1340*d6b92ffaSHans Petter Selasky 			PARSE_AHEAD(p, net64, " guid7=0x",
1341*d6b92ffaSHans Petter Selasky 				    &gi_rec.guid_info.guid[7]);
1342*d6b92ffaSHans Petter Selasky 
1343*d6b92ffaSHans Petter Selasky 			if (load_guidinfo(p_osm, base_guid, &gi_rec))
1344*d6b92ffaSHans Petter Selasky 				rereg_clients = 1;
1345*d6b92ffaSHans Petter Selasky 		}
1346*d6b92ffaSHans Petter Selasky 
1347*d6b92ffaSHans Petter Selasky 		/*
1348*d6b92ffaSHans Petter Selasky 		 * p_next_mgrp points to the multicast group now being parsed.
1349*d6b92ffaSHans Petter Selasky 		 * p_prev_mgrp points to the last multicast group we parsed.
1350*d6b92ffaSHans Petter Selasky 		 * We decide whether to keep or delete each multicast group
1351*d6b92ffaSHans Petter Selasky 		 * only when we finish parsing it's member records. if the
1352*d6b92ffaSHans Petter Selasky 		 * group has full members, or it is a "well known group" we
1353*d6b92ffaSHans Petter Selasky 		 * keep it.
1354*d6b92ffaSHans Petter Selasky 		 */
1355*d6b92ffaSHans Petter Selasky 		if (p_prev_mgrp != p_next_mgrp) {
1356*d6b92ffaSHans Petter Selasky 			if (p_prev_mgrp)
1357*d6b92ffaSHans Petter Selasky 				sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
1358*d6b92ffaSHans Petter Selasky 			p_prev_mgrp = p_next_mgrp;
1359*d6b92ffaSHans Petter Selasky 		}
1360*d6b92ffaSHans Petter Selasky 	}
1361*d6b92ffaSHans Petter Selasky 
1362*d6b92ffaSHans Petter Selasky 	if (p_next_mgrp)
1363*d6b92ffaSHans Petter Selasky 		sa_db_file_load_handle_mgrp(p_osm, p_prev_mgrp);
1364*d6b92ffaSHans Petter Selasky 
1365*d6b92ffaSHans Petter Selasky 	/*
1366*d6b92ffaSHans Petter Selasky 	 * If loading succeeded, do whatever 'no_clients_rereg' says.
1367*d6b92ffaSHans Petter Selasky 	 * If loading failed at some point, turn off the 'no_clients_rereg'
1368*d6b92ffaSHans Petter Selasky 	 * option (turn on re-registration requests).
1369*d6b92ffaSHans Petter Selasky 	 */
1370*d6b92ffaSHans Petter Selasky 	if (rereg_clients)
1371*d6b92ffaSHans Petter Selasky 		p_osm->subn.opt.no_clients_rereg = FALSE;
1372*d6b92ffaSHans Petter Selasky 
1373*d6b92ffaSHans Petter Selasky 	/* We've just finished loading SA DB file - clear the "dirty" flag */
1374*d6b92ffaSHans Petter Selasky 	p_osm->sa.dirty = FALSE;
1375*d6b92ffaSHans Petter Selasky 
1376*d6b92ffaSHans Petter Selasky _error:
1377*d6b92ffaSHans Petter Selasky 	fclose(file);
1378*d6b92ffaSHans Petter Selasky 	return ret;
1379*d6b92ffaSHans Petter Selasky }
1380