osmtest.c revision 277361
1/*
2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36/* TODO : Check why we dont free the cl_qmap_items we store when reading DB */
37
38/*
39 * Abstract:
40 *    Implementation of osmtest_t.
41 *    This object represents the OSMTest Test object.
42 *
43 */
44
45#ifdef __WIN__
46#pragma warning(disable : 4996)
47#endif
48
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#ifdef __WIN__
53#include <complib/cl_timer.h>
54#else
55#include <strings.h>
56#include <sys/time.h>
57#endif
58#include <complib/cl_debug.h>
59#include "osmtest.h"
60
61#ifndef __WIN__
62#define strnicmp strncasecmp
63#endif
64
65#define POOL_MIN_ITEMS  64
66#define GUID_ARRAY_SIZE 64
67
68typedef struct _osmtest_sm_info_rec {
69	ib_net64_t sm_guid;
70	ib_net16_t lid;
71	uint8_t priority;
72	uint8_t sm_state;
73} osmtest_sm_info_rec_t;
74
75typedef struct _osmtest_inform_info {
76	boolean_t subscribe;
77	ib_net32_t qpn;
78	ib_net16_t trap;
79} osmtest_inform_info_t;
80
81typedef struct _osmtest_inform_info_rec {
82	ib_gid_t subscriber_gid;
83	ib_net16_t subscriber_enum;
84} osmtest_inform_info_rec_t;
85
86typedef enum _osmtest_token_val {
87	OSMTEST_TOKEN_COMMENT = 0,
88	OSMTEST_TOKEN_END,
89	OSMTEST_TOKEN_DEFINE_NODE,
90	OSMTEST_TOKEN_DEFINE_PORT,
91	OSMTEST_TOKEN_DEFINE_PATH,
92	OSMTEST_TOKEN_DEFINE_LINK,
93	OSMTEST_TOKEN_LID,
94	OSMTEST_TOKEN_BASE_VERSION,
95	OSMTEST_TOKEN_CLASS_VERSION,
96	OSMTEST_TOKEN_NODE_TYPE,
97	OSMTEST_TOKEN_NUM_PORTS,
98	OSMTEST_TOKEN_SYS_GUID,
99	OSMTEST_TOKEN_NODE_GUID,
100	OSMTEST_TOKEN_PORT_GUID,
101	OSMTEST_TOKEN_PARTITION_CAP,
102	OSMTEST_TOKEN_DEVICE_ID,
103	OSMTEST_TOKEN_REVISION,
104	OSMTEST_TOKEN_PORT_NUM,
105	OSMTEST_TOKEN_VENDOR_ID,
106	OSMTEST_TOKEN_DGID,
107	OSMTEST_TOKEN_SGID,
108	OSMTEST_TOKEN_DLID,
109	OSMTEST_TOKEN_SLID,
110	OSMTEST_TOKEN_HOP_FLOW_RAW,
111	OSMTEST_TOKEN_TCLASS,
112	OSMTEST_TOKEN_NUM_PATH,
113	OSMTEST_TOKEN_PKEY,
114	OSMTEST_TOKEN_SL,
115	OSMTEST_TOKEN_RATE,
116	OSMTEST_TOKEN_PKT_LIFE,
117	OSMTEST_TOKEN_PREFERENCE,
118	OSMTEST_TOKEN_MKEY,
119	OSMTEST_TOKEN_SUBN_PREF,
120	OSMTEST_TOKEN_BASE_LID,
121	OSMTEST_TOKEN_SM_BASE_LID,
122	OSMTEST_TOKEN_CAP_MASK,
123	OSMTEST_TOKEN_DIAG_CODE,
124	OSMTEST_TOKEN_MKEY_LEASE_PER,
125	OSMTEST_TOKEN_LOC_PORT_NUM,
126	OSMTEST_TOKEN_LINK_WID_EN,
127	OSMTEST_TOKEN_LINK_WID_SUP,
128	OSMTEST_TOKEN_LINK_WID_ACT,
129	OSMTEST_TOKEN_LINK_SPEED_SUP,
130	OSMTEST_TOKEN_PORT_STATE,
131	OSMTEST_TOKEN_STATE_INFO2,
132	OSMTEST_TOKEN_MKEY_PROT_BITS,
133	OSMTEST_TOKEN_LMC,
134	OSMTEST_TOKEN_LINK_SPEED,
135	OSMTEST_TOKEN_MTU_SMSL,
136	OSMTEST_TOKEN_VL_CAP,
137	OSMTEST_TOKEN_VL_HIGH_LIMIT,
138	OSMTEST_TOKEN_VL_ARB_HIGH_CAP,
139	OSMTEST_TOKEN_VL_ARB_LOW_CAP,
140	OSMTEST_TOKEN_MTU_CAP,
141	OSMTEST_TOKEN_VL_STALL_LIFE,
142	OSMTEST_TOKEN_VL_ENFORCE,
143	OSMTEST_TOKEN_MKEY_VIOL,
144	OSMTEST_TOKEN_PKEY_VIOL,
145	OSMTEST_TOKEN_QKEY_VIOL,
146	OSMTEST_TOKEN_GUID_CAP,
147	OSMTEST_TOKEN_SUBN_TIMEOUT,
148	OSMTEST_TOKEN_RESP_TIME_VAL,
149	OSMTEST_TOKEN_ERR_THRESHOLD,
150	OSMTEST_TOKEN_MTU,
151	OSMTEST_TOKEN_FROMLID,
152	OSMTEST_TOKEN_FROMPORTNUM,
153	OSMTEST_TOKEN_TOPORTNUM,
154	OSMTEST_TOKEN_TOLID,
155	OSMTEST_TOKEN_UNKNOWN
156} osmtest_token_val_t;
157
158typedef struct _osmtest_token {
159	osmtest_token_val_t val;
160	size_t str_size;
161	const char *str;
162} osmtest_token_t;
163
164const osmtest_token_t token_array[] = {
165	{OSMTEST_TOKEN_COMMENT, 1, "#"},
166	{OSMTEST_TOKEN_END, 3, "END"},
167	{OSMTEST_TOKEN_DEFINE_NODE, 11, "DEFINE_NODE"},
168	{OSMTEST_TOKEN_DEFINE_PORT, 11, "DEFINE_PORT"},
169	{OSMTEST_TOKEN_DEFINE_PATH, 11, "DEFINE_PATH"},
170	{OSMTEST_TOKEN_DEFINE_LINK, 11, "DEFINE_LINK"},
171	{OSMTEST_TOKEN_LID, 3, "LID"},
172	{OSMTEST_TOKEN_BASE_VERSION, 12, "BASE_VERSION"},
173	{OSMTEST_TOKEN_CLASS_VERSION, 13, "CLASS_VERSION"},
174	{OSMTEST_TOKEN_NODE_TYPE, 9, "NODE_TYPE"},
175	{OSMTEST_TOKEN_NUM_PORTS, 9, "NUM_PORTS"},
176	{OSMTEST_TOKEN_SYS_GUID, 8, "SYS_GUID"},
177	{OSMTEST_TOKEN_NODE_GUID, 9, "NODE_GUID"},
178	{OSMTEST_TOKEN_PORT_GUID, 9, "PORT_GUID"},
179	{OSMTEST_TOKEN_PARTITION_CAP, 13, "PARTITION_CAP"},
180	{OSMTEST_TOKEN_DEVICE_ID, 9, "DEVICE_ID"},
181	{OSMTEST_TOKEN_REVISION, 8, "REVISION"},
182	{OSMTEST_TOKEN_PORT_NUM, 8, "PORT_NUM"},
183	{OSMTEST_TOKEN_VENDOR_ID, 9, "VENDOR_ID"},
184	{OSMTEST_TOKEN_DGID, 4, "DGID"},
185	{OSMTEST_TOKEN_SGID, 4, "SGID"},
186	{OSMTEST_TOKEN_DLID, 4, "DLID"},
187	{OSMTEST_TOKEN_SLID, 4, "SLID"},
188	{OSMTEST_TOKEN_HOP_FLOW_RAW, 12, "HOP_FLOW_RAW"},
189	{OSMTEST_TOKEN_TCLASS, 6, "TCLASS"},
190	{OSMTEST_TOKEN_NUM_PATH, 8, "NUM_PATH"},
191	{OSMTEST_TOKEN_PKEY, 4, "PKEY"},
192	{OSMTEST_TOKEN_SL, 2, "SL"},
193	{OSMTEST_TOKEN_RATE, 4, "RATE"},
194	{OSMTEST_TOKEN_PKT_LIFE, 8, "PKT_LIFE"},
195	{OSMTEST_TOKEN_PREFERENCE, 10, "PREFERENCE"},
196	{OSMTEST_TOKEN_MKEY, 4, "M_KEY"},
197	{OSMTEST_TOKEN_SUBN_PREF, 13, "SUBNET_PREFIX"},
198	{OSMTEST_TOKEN_BASE_LID, 8, "BASE_LID"},
199	{OSMTEST_TOKEN_SM_BASE_LID, 18, "MASTER_SM_BASE_LID"},
200	{OSMTEST_TOKEN_CAP_MASK, 15, "CAPABILITY_MASK"},
201	{OSMTEST_TOKEN_DIAG_CODE, 9, "DIAG_CODE"},
202	{OSMTEST_TOKEN_MKEY_LEASE_PER, 18, "m_key_lease_period"},
203	{OSMTEST_TOKEN_LOC_PORT_NUM, 14, "local_port_num"},
204	{OSMTEST_TOKEN_LINK_WID_EN, 18, "link_width_enabled"},
205	{OSMTEST_TOKEN_LINK_WID_SUP, 20, "link_width_supported"},
206	{OSMTEST_TOKEN_LINK_WID_ACT, 17, "link_width_active"},
207	{OSMTEST_TOKEN_LINK_SPEED_SUP, 20, "link_speed_supported"},
208	{OSMTEST_TOKEN_PORT_STATE, 10, "port_state"},
209	{OSMTEST_TOKEN_STATE_INFO2, 10, "state_info2"},
210	{OSMTEST_TOKEN_MKEY_PROT_BITS, 3, "mpb"},
211	{OSMTEST_TOKEN_LMC, 3, "lmc"},
212	{OSMTEST_TOKEN_LINK_SPEED, 10, "link_speed"},
213	{OSMTEST_TOKEN_MTU_SMSL, 8, "mtu_smsl"},
214	{OSMTEST_TOKEN_VL_CAP, 6, "vl_cap"},
215	{OSMTEST_TOKEN_VL_HIGH_LIMIT, 13, "vl_high_limit"},
216	{OSMTEST_TOKEN_VL_ARB_HIGH_CAP, 15, "vl_arb_high_cap"},
217	{OSMTEST_TOKEN_VL_ARB_LOW_CAP, 14, "vl_arb_low_cap"},
218	{OSMTEST_TOKEN_MTU_CAP, 7, "mtu_cap"},
219	{OSMTEST_TOKEN_VL_STALL_LIFE, 13, "vl_stall_life"},
220	{OSMTEST_TOKEN_VL_ENFORCE, 10, "vl_enforce"},
221	{OSMTEST_TOKEN_MKEY_VIOL, 16, "m_key_violations"},
222	{OSMTEST_TOKEN_PKEY_VIOL, 16, "p_key_violations"},
223	{OSMTEST_TOKEN_QKEY_VIOL, 16, "q_key_violations"},
224	{OSMTEST_TOKEN_GUID_CAP, 8, "guid_cap"},
225	{OSMTEST_TOKEN_SUBN_TIMEOUT, 14, "subnet_timeout"},
226	{OSMTEST_TOKEN_RESP_TIME_VAL, 15, "resp_time_value"},
227	{OSMTEST_TOKEN_ERR_THRESHOLD, 15, "error_threshold"},
228	{OSMTEST_TOKEN_MTU, 3, "MTU"},	/*  must be after the other mtu... tokens. */
229	{OSMTEST_TOKEN_FROMLID, 8, "from_lid"},
230	{OSMTEST_TOKEN_FROMPORTNUM, 13, "from_port_num"},
231	{OSMTEST_TOKEN_TOPORTNUM, 11, "to_port_num"},
232	{OSMTEST_TOKEN_TOLID, 6, "to_lid"},
233	{OSMTEST_TOKEN_UNKNOWN, 0, ""}	/* must be last entry */
234};
235
236#define IB_MAD_STATUS_CLASS_MASK       (CL_HTON16(0xFF00))
237
238static const char ib_mad_status_str_busy[] = "IB_MAD_STATUS_BUSY";
239static const char ib_mad_status_str_redirect[] = "IB_MAD_STATUS_REDIRECT";
240static const char ib_mad_status_str_unsup_class_ver[] =
241    "IB_MAD_STATUS_UNSUP_CLASS_VER";
242static const char ib_mad_status_str_unsup_method[] =
243    "IB_MAD_STATUS_UNSUP_METHOD";
244static const char ib_mad_status_str_unsup_method_attr[] =
245    "IB_MAD_STATUS_UNSUP_METHOD_ATTR";
246static const char ib_mad_status_str_invalid_field[] =
247    "IB_MAD_STATUS_INVALID_FIELD";
248static const char ib_mad_status_str_no_resources[] =
249    "IB_SA_MAD_STATUS_NO_RESOURCES";
250static const char ib_mad_status_str_req_invalid[] =
251    "IB_SA_MAD_STATUS_REQ_INVALID";
252static const char ib_mad_status_str_no_records[] =
253    "IB_SA_MAD_STATUS_NO_RECORDS";
254static const char ib_mad_status_str_too_many_records[] =
255    "IB_SA_MAD_STATUS_TOO_MANY_RECORDS";
256static const char ib_mad_status_str_invalid_gid[] =
257    "IB_SA_MAD_STATUS_INVALID_GID";
258static const char ib_mad_status_str_insuf_comps[] =
259    "IB_SA_MAD_STATUS_INSUF_COMPS";
260static const char generic_or_str[] = " | ";
261
262/**********************************************************************
263 **********************************************************************/
264const char *ib_get_mad_status_str(IN const ib_mad_t * const p_mad)
265{
266	static char line[512];
267	uint32_t offset = 0;
268	ib_net16_t status;
269	boolean_t first = TRUE;
270
271	line[offset] = '\0';
272
273	status = (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
274
275	if (status == 0) {
276		strcat(&line[offset], "IB_SUCCESS");
277		return (line);
278	}
279
280	if (status & IB_MAD_STATUS_BUSY) {
281		strcat(&line[offset], ib_mad_status_str_busy);
282		offset += sizeof(ib_mad_status_str_busy);
283	}
284	if (status & IB_MAD_STATUS_REDIRECT) {
285		if (!first) {
286			strcat(&line[offset], generic_or_str);
287			offset += sizeof(generic_or_str) - 1;
288		}
289		first = FALSE;
290		strcat(&line[offset], ib_mad_status_str_redirect);
291		offset += sizeof(ib_mad_status_str_redirect) - 1;
292	}
293	if ((status & IB_MAD_STATUS_INVALID_FIELD) ==
294	    IB_MAD_STATUS_UNSUP_CLASS_VER) {
295		if (!first) {
296			strcat(&line[offset], generic_or_str);
297			offset += sizeof(generic_or_str) - 1;
298		}
299		first = FALSE;
300		strcat(&line[offset], ib_mad_status_str_unsup_class_ver);
301		offset += sizeof(ib_mad_status_str_unsup_class_ver) - 1;
302	}
303	if ((status & IB_MAD_STATUS_INVALID_FIELD) ==
304	    IB_MAD_STATUS_UNSUP_METHOD) {
305		if (!first) {
306			strcat(&line[offset], generic_or_str);
307			offset += sizeof(generic_or_str) - 1;
308		}
309		first = FALSE;
310		strcat(&line[offset], ib_mad_status_str_unsup_method);
311		offset += sizeof(ib_mad_status_str_unsup_method) - 1;
312	}
313	if ((status & IB_MAD_STATUS_INVALID_FIELD) ==
314	    IB_MAD_STATUS_UNSUP_METHOD_ATTR) {
315		if (!first) {
316			strcat(&line[offset], generic_or_str);
317			offset += sizeof(generic_or_str) - 1;
318		}
319		first = FALSE;
320		strcat(&line[offset], ib_mad_status_str_unsup_method_attr);
321		offset += sizeof(ib_mad_status_str_unsup_method_attr) - 1;
322	}
323	if ((status & IB_MAD_STATUS_INVALID_FIELD) ==
324	    IB_MAD_STATUS_INVALID_FIELD) {
325		if (!first) {
326			strcat(&line[offset], generic_or_str);
327			offset += sizeof(generic_or_str) - 1;
328		}
329		first = FALSE;
330		strcat(&line[offset], ib_mad_status_str_invalid_field);
331		offset += sizeof(ib_mad_status_str_invalid_field) - 1;
332	}
333	if ((status & IB_MAD_STATUS_CLASS_MASK) ==
334	    IB_SA_MAD_STATUS_NO_RESOURCES) {
335		if (!first) {
336			strcat(&line[offset], generic_or_str);
337			offset += sizeof(generic_or_str) - 1;
338		}
339		first = FALSE;
340		strcat(&line[offset], ib_mad_status_str_no_resources);
341		offset += sizeof(ib_mad_status_str_no_resources) - 1;
342	}
343	if ((status & IB_MAD_STATUS_CLASS_MASK) == IB_SA_MAD_STATUS_REQ_INVALID) {
344		if (!first) {
345			strcat(&line[offset], generic_or_str);
346			offset += sizeof(generic_or_str) - 1;
347		}
348		first = FALSE;
349		strcat(&line[offset], ib_mad_status_str_req_invalid);
350		offset += sizeof(ib_mad_status_str_req_invalid) - 1;
351	}
352	if ((status & IB_MAD_STATUS_CLASS_MASK) == IB_SA_MAD_STATUS_NO_RECORDS) {
353		if (!first) {
354			strcat(&line[offset], generic_or_str);
355			offset += sizeof(generic_or_str) - 1;
356		}
357		first = FALSE;
358		strcat(&line[offset], ib_mad_status_str_no_records);
359		offset += sizeof(ib_mad_status_str_no_records) - 1;
360	}
361	if ((status & IB_MAD_STATUS_CLASS_MASK) ==
362	    IB_SA_MAD_STATUS_TOO_MANY_RECORDS) {
363		if (!first) {
364			strcat(&line[offset], generic_or_str);
365			offset += sizeof(generic_or_str) - 1;
366		}
367		first = FALSE;
368		strcat(&line[offset], ib_mad_status_str_too_many_records);
369		offset += sizeof(ib_mad_status_str_too_many_records) - 1;
370	}
371	if ((status & IB_MAD_STATUS_CLASS_MASK) == IB_SA_MAD_STATUS_INVALID_GID) {
372		if (!first) {
373			strcat(&line[offset], generic_or_str);
374			offset += sizeof(generic_or_str) - 1;
375		}
376		first = FALSE;
377		strcat(&line[offset], ib_mad_status_str_invalid_gid);
378		offset += sizeof(ib_mad_status_str_invalid_gid) - 1;
379	}
380	if ((status & IB_MAD_STATUS_CLASS_MASK) == IB_SA_MAD_STATUS_INSUF_COMPS) {
381		if (!first) {
382			strcat(&line[offset], generic_or_str);
383			offset += sizeof(generic_or_str) - 1;
384		}
385		first = FALSE;
386		strcat(&line[offset], ib_mad_status_str_insuf_comps);
387		offset += sizeof(ib_mad_status_str_insuf_comps) - 1;
388	}
389
390	return (line);
391}
392
393/**********************************************************************
394 **********************************************************************/
395void subnet_construct(IN subnet_t * const p_subn)
396{
397	cl_qmap_init(&p_subn->link_tbl);
398	cl_qmap_init(&p_subn->node_lid_tbl);
399	cl_qmap_init(&p_subn->node_guid_tbl);
400	cl_qmap_init(&p_subn->mgrp_mlid_tbl);
401
402	/* NO WAY TO HAVE UNIQUE PORT BY LID OR GUID */
403	/* cl_qmap_init( &p_subn->port_lid_tbl ); */
404	/* cl_qmap_init( &p_subn->port_guid_tbl ); */
405
406	/* port key is a lid and num pair */
407	cl_qmap_init(&p_subn->port_key_tbl);
408	cl_qmap_init(&p_subn->path_tbl);
409}
410
411/**********************************************************************
412 **********************************************************************/
413cl_status_t subnet_init(IN subnet_t * const p_subn)
414{
415	cl_status_t status = IB_SUCCESS;
416
417	subnet_construct(p_subn);
418
419	return (status);
420}
421
422/**********************************************************************
423 **********************************************************************/
424void osmtest_construct(IN osmtest_t * const p_osmt)
425{
426	memset(p_osmt, 0, sizeof(*p_osmt));
427	osm_log_construct(&p_osmt->log);
428	subnet_construct(&p_osmt->exp_subn);
429}
430
431/**********************************************************************
432 **********************************************************************/
433void osmtest_destroy(IN osmtest_t * const p_osmt)
434{
435	cl_map_item_t *p_item, *p_next_item;
436
437	/* Currently there is a problem with IBAL exit flow - memory overrun,
438	   so bypass vendor deletion - it will be cleaned by the Windows OS */
439#ifndef __WIN__
440	if (p_osmt->p_vendor)
441		osm_vendor_delete(&p_osmt->p_vendor);
442#endif
443
444	cl_qpool_destroy(&p_osmt->port_pool);
445	cl_qpool_destroy(&p_osmt->node_pool);
446
447	/* destroy the qmap tables */
448	p_next_item = cl_qmap_head(&p_osmt->exp_subn.link_tbl);
449	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.link_tbl)) {
450		p_item = p_next_item;
451		p_next_item = cl_qmap_next(p_item);
452		free(p_item);
453	}
454	p_next_item = cl_qmap_head(&p_osmt->exp_subn.mgrp_mlid_tbl);
455	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.mgrp_mlid_tbl)) {
456		p_item = p_next_item;
457		p_next_item = cl_qmap_next(p_item);
458		free(p_item);
459	}
460	p_next_item = cl_qmap_head(&p_osmt->exp_subn.node_guid_tbl);
461	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.node_guid_tbl)) {
462		p_item = p_next_item;
463		p_next_item = cl_qmap_next(p_item);
464		free(p_item);
465	}
466
467	p_next_item = cl_qmap_head(&p_osmt->exp_subn.node_lid_tbl);
468	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.node_lid_tbl)) {
469		p_item = p_next_item;
470		p_next_item = cl_qmap_next(p_item);
471		free(p_item);
472	}
473
474	p_next_item = cl_qmap_head(&p_osmt->exp_subn.path_tbl);
475	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.path_tbl)) {
476		p_item = p_next_item;
477		p_next_item = cl_qmap_next(p_item);
478		free(p_item);
479	}
480	p_next_item = cl_qmap_head(&p_osmt->exp_subn.port_key_tbl);
481	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.port_key_tbl)) {
482		p_item = p_next_item;
483		p_next_item = cl_qmap_next(p_item);
484		free(p_item);
485	}
486
487	osm_log_destroy(&p_osmt->log);
488}
489
490/**********************************************************************
491 **********************************************************************/
492ib_api_status_t
493osmtest_init(IN osmtest_t * const p_osmt,
494	     IN const osmtest_opt_t * const p_opt,
495	     IN const osm_log_level_t log_flags)
496{
497	ib_api_status_t status;
498
499	/* Can't use log macros here, since we're initializing the log. */
500	osmtest_construct(p_osmt);
501
502	status = osm_log_init_v2(&p_osmt->log, p_opt->force_log_flush,
503				 0x0001, p_opt->log_file, 0, TRUE);
504	if (status != IB_SUCCESS)
505		return (status);
506
507	/* but we do not want any extra stuff here */
508	osm_log_set_level(&p_osmt->log, log_flags);
509
510	OSM_LOG(&p_osmt->log, OSM_LOG_FUNCS, "[\n");
511
512	p_osmt->opt = *p_opt;
513
514	status = cl_qpool_init(&p_osmt->node_pool, POOL_MIN_ITEMS, 0,
515			       POOL_MIN_ITEMS, sizeof(node_t), NULL, NULL,
516			       NULL);
517	CL_ASSERT(status == CL_SUCCESS);
518
519	status = cl_qpool_init(&p_osmt->port_pool, POOL_MIN_ITEMS, 0,
520			       POOL_MIN_ITEMS, sizeof(port_t), NULL, NULL,
521			       NULL);
522	CL_ASSERT(status == CL_SUCCESS);
523
524	p_osmt->p_vendor = osm_vendor_new(&p_osmt->log,
525					  p_opt->transaction_timeout);
526
527	if (p_osmt->p_vendor == NULL) {
528		status = IB_INSUFFICIENT_RESOURCES;
529		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0001: "
530			"Unable to allocate vendor object");
531		status = IB_ERROR;
532		goto Exit;
533	}
534
535	osm_mad_pool_construct(&p_osmt->mad_pool);
536	status = osm_mad_pool_init(&p_osmt->mad_pool);
537	if (status != IB_SUCCESS)
538		goto Exit;
539
540Exit:
541	OSM_LOG(&p_osmt->log, OSM_LOG_FUNCS, "]\n");
542	return (status);
543}
544
545/**********************************************************************
546 **********************************************************************/
547void osmtest_query_res_cb(IN osmv_query_res_t * p_rec)
548{
549	osmtest_req_context_t *const p_ctxt =
550	    (osmtest_req_context_t *) p_rec->query_context;
551	osmtest_t *const p_osmt = p_ctxt->p_osmt;
552
553	OSM_LOG_ENTER(&p_osmt->log);
554
555	p_ctxt->result = *p_rec;
556
557	if (p_rec->status != IB_SUCCESS) {
558		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0003: "
559			"Error on query (%s)\n", ib_get_err_str(p_rec->status));
560	}
561
562	OSM_LOG_EXIT(&p_osmt->log);
563}
564
565/**********************************************************************
566 **********************************************************************/
567ib_api_status_t
568osmtest_get_all_recs(IN osmtest_t * const p_osmt,
569		     IN ib_net16_t const attr_id,
570		     IN size_t const attr_size,
571		     IN OUT osmtest_req_context_t * const p_context)
572{
573	ib_api_status_t status = IB_SUCCESS;
574	osmv_user_query_t user;
575	osmv_query_req_t req;
576
577	OSM_LOG_ENTER(&p_osmt->log);
578
579	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Getting all %s records\n",
580		ib_get_sa_attr_str(attr_id));
581
582	/*
583	 * Do a blocking query for all <attr_id> records in the subnet.
584	 * The result is returned in the result field of the caller's
585	 * context structure.
586	 *
587	 * The query structures are locals.
588	 */
589	memset(&req, 0, sizeof(req));
590	memset(&user, 0, sizeof(user));
591
592	p_context->p_osmt = p_osmt;
593	user.attr_id = attr_id;
594	user.attr_offset = cl_ntoh16((uint16_t) (attr_size >> 3));
595
596	req.query_type = OSMV_QUERY_USER_DEFINED;
597	req.timeout_ms = p_osmt->opt.transaction_timeout;
598	req.retry_cnt = p_osmt->opt.retry_count;
599	req.flags = OSM_SA_FLAGS_SYNC;
600	req.query_context = p_context;
601	req.pfn_query_cb = osmtest_query_res_cb;
602	req.p_query_input = &user;
603	req.sm_key = 0;
604
605	status = osmv_query_sa(p_osmt->h_bind, &req);
606	if (status != IB_SUCCESS) {
607		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0004: "
608			"ib_query failed (%s)\n", ib_get_err_str(status));
609		goto Exit;
610	}
611
612	status = p_context->result.status;
613
614	if (status != IB_SUCCESS) {
615		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0064: "
616			"ib_query failed (%s)\n", ib_get_err_str(status));
617
618		if (status == IB_REMOTE_ERROR) {
619			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
620				"Remote error = %s\n",
621				ib_get_mad_status_str(osm_madw_get_mad_ptr
622						      (p_context->result.
623						       p_result_madw)));
624		}
625		goto Exit;
626	}
627
628Exit:
629	OSM_LOG_EXIT(&p_osmt->log);
630	return (status);
631}
632
633/**********************************************************************
634 **********************************************************************/
635ib_api_status_t osmtest_validate_sa_class_port_info(IN osmtest_t * const p_osmt)
636{
637	ib_api_status_t status = IB_SUCCESS;
638	osmv_query_req_t req;
639	ib_class_port_info_t *p_cpi;
640	osmtest_req_context_t context;
641	osmtest_req_context_t *p_context = &context;
642	ib_sa_mad_t *p_resp_sa_madp;
643
644	OSM_LOG_ENTER(&p_osmt->log);
645
646	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Getting ClassPortInfo\n");
647
648	/*
649	 * Do a blocking query for this record in the subnet.
650	 * The result is returned in the result field of the caller's
651	 * context structure.
652	 *
653	 * The query structures are locals.
654	 */
655	memset(&req, 0, sizeof(req));
656
657	p_context->p_osmt = p_osmt;
658	req.query_type = OSMV_QUERY_CLASS_PORT_INFO;
659	req.timeout_ms = p_osmt->opt.transaction_timeout;
660	req.retry_cnt = p_osmt->opt.retry_count;
661	req.flags = OSM_SA_FLAGS_SYNC;
662	req.query_context = p_context;
663	req.pfn_query_cb = osmtest_query_res_cb;
664	req.p_query_input = 0;
665	req.sm_key = 0;
666
667	status = osmv_query_sa(p_osmt->h_bind, &req);
668	if (status != IB_SUCCESS) {
669		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0065: "
670			"ib_query failed (%s)\n", ib_get_err_str(status));
671		goto Exit;
672	}
673
674	status = p_context->result.status;
675
676	if (status != IB_SUCCESS) {
677		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0070: "
678			"ib_query failed (%s)\n", ib_get_err_str(status));
679		if (status == IB_REMOTE_ERROR) {
680			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
681				"Remote error = %s\n",
682				ib_get_mad_status_str(osm_madw_get_mad_ptr
683						      (p_context->result.
684						       p_result_madw)));
685		}
686		goto Exit;
687	}
688
689	/* ok we got it so please print it out */
690	p_resp_sa_madp =
691	    (ib_sa_mad_t *) osm_madw_get_mad_ptr(context.result.p_result_madw);
692	p_cpi =
693	    (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_madp);
694
695	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
696		"\n-----------------------------\n"
697		"SA Class Port Info:\n"
698		" base_ver:%u\n"
699		" class_ver:%u\n"
700		" cap_mask:0x%X\n"
701		" cap_mask2:0x%X\n"
702		" resp_time_val:0x%X\n"
703		"-----------------------------\n",
704		p_cpi->base_ver, p_cpi->class_ver, cl_ntoh16(p_cpi->cap_mask),
705		ib_class_cap_mask2(p_cpi), ib_class_resp_time_val(p_cpi));
706
707Exit:
708#if 0
709	if (context.result.p_result_madw != NULL) {
710		osm_mad_pool_put(&p_osmt->mad_pool,
711				 context.result.p_result_madw);
712		context.result.p_result_madw = NULL;
713	}
714#endif
715
716	OSM_LOG_EXIT(&p_osmt->log);
717	return (status);
718}
719
720/**********************************************************************
721 **********************************************************************/
722ib_api_status_t
723osmtest_get_node_rec(IN osmtest_t * const p_osmt,
724		     IN ib_net64_t const node_guid,
725		     IN OUT osmtest_req_context_t * const p_context)
726{
727	ib_api_status_t status = IB_SUCCESS;
728	osmv_user_query_t user;
729	osmv_query_req_t req;
730	ib_node_record_t record;
731
732	OSM_LOG_ENTER(&p_osmt->log);
733
734	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
735		"Getting node record for 0x%016" PRIx64 "\n",
736		cl_ntoh64(node_guid));
737
738	/*
739	 * Do a blocking query for this record in the subnet.
740	 * The result is returned in the result field of the caller's
741	 * context structure.
742	 *
743	 * The query structures are locals.
744	 */
745	memset(&req, 0, sizeof(req));
746	memset(&user, 0, sizeof(user));
747	memset(&record, 0, sizeof(record));
748
749	record.node_info.node_guid = node_guid;
750
751	p_context->p_osmt = p_osmt;
752	user.comp_mask = IB_NR_COMPMASK_NODEGUID;
753	user.attr_id = IB_MAD_ATTR_NODE_RECORD;
754	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
755	user.p_attr = &record;
756
757	req.query_type = OSMV_QUERY_USER_DEFINED;
758	req.timeout_ms = p_osmt->opt.transaction_timeout;
759	req.retry_cnt = p_osmt->opt.retry_count;
760	req.flags = OSM_SA_FLAGS_SYNC;
761	req.query_context = p_context;
762	req.pfn_query_cb = osmtest_query_res_cb;
763	req.p_query_input = &user;
764	req.sm_key = 0;
765
766	status = osmv_query_sa(p_osmt->h_bind, &req);
767	if (status != IB_SUCCESS) {
768		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0071: "
769			"ib_query failed (%s)\n", ib_get_err_str(status));
770		goto Exit;
771	}
772
773	status = p_context->result.status;
774
775	if (status != IB_SUCCESS) {
776		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0072: "
777			"ib_query failed (%s)\n", ib_get_err_str(status));
778		if (status == IB_REMOTE_ERROR) {
779			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
780				"Remote error = %s\n",
781				ib_get_mad_status_str(osm_madw_get_mad_ptr
782						      (p_context->result.
783						       p_result_madw)));
784		}
785		goto Exit;
786	}
787
788Exit:
789	OSM_LOG_EXIT(&p_osmt->log);
790	return (status);
791}
792
793/**********************************************************************
794 * Get a node record by node LID
795 **********************************************************************/
796ib_api_status_t
797osmtest_get_node_rec_by_lid(IN osmtest_t * const p_osmt,
798			    IN ib_net16_t const lid,
799			    IN OUT osmtest_req_context_t * const p_context)
800{
801	ib_api_status_t status = IB_SUCCESS;
802	osmv_user_query_t user;
803	osmv_query_req_t req;
804	ib_node_record_t record;
805	ib_mad_t *p_mad;
806
807	OSM_LOG_ENTER(&p_osmt->log);
808
809	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
810		"Getting node record for LID 0x%02X\n", cl_ntoh16(lid));
811
812	/*
813	 * Do a blocking query for this record in the subnet.
814	 * The result is returned in the result field of the caller's
815	 * context structure.
816	 *
817	 * The query structures are locals.
818	 */
819	memset(&req, 0, sizeof(req));
820	memset(&user, 0, sizeof(user));
821	memset(&record, 0, sizeof(record));
822
823	record.lid = lid;
824
825	p_context->p_osmt = p_osmt;
826	user.comp_mask = IB_NR_COMPMASK_LID;
827	user.attr_id = IB_MAD_ATTR_NODE_RECORD;
828	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
829	user.p_attr = &record;
830
831	req.query_type = OSMV_QUERY_USER_DEFINED;
832	req.timeout_ms = p_osmt->opt.transaction_timeout;
833	req.retry_cnt = p_osmt->opt.retry_count;
834	req.flags = OSM_SA_FLAGS_SYNC;
835	req.query_context = p_context;
836	req.pfn_query_cb = osmtest_query_res_cb;
837	req.p_query_input = &user;
838	req.sm_key = 0;
839
840	status = osmv_query_sa(p_osmt->h_bind, &req);
841	if (status != IB_SUCCESS) {
842		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0073: "
843			"ib_query failed (%s)\n", ib_get_err_str(status));
844		goto Exit;
845	}
846
847	status = p_context->result.status;
848
849	if (status != IB_SUCCESS) {
850		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0074: "
851			"ib_query failed (%s)\n", ib_get_err_str(status));
852		if (status == IB_REMOTE_ERROR) {
853			p_mad =
854			    osm_madw_get_mad_ptr(p_context->result.
855						 p_result_madw);
856			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
857				"Remote error = %s\n",
858				ib_get_mad_status_str(p_mad));
859
860			status =
861			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
862		}
863		goto Exit;
864	}
865
866Exit:
867	OSM_LOG_EXIT(&p_osmt->log);
868	return (status);
869}
870
871/**********************************************************************
872 **********************************************************************/
873static ib_api_status_t
874osmtest_get_path_rec_by_guid_pair(IN osmtest_t * const p_osmt,
875				  IN ib_net64_t sguid,
876				  IN ib_net64_t dguid,
877				  IN osmtest_req_context_t * p_context)
878{
879	cl_status_t status = IB_SUCCESS;
880	osmv_query_req_t req;
881	osmv_guid_pair_t guid_pair;
882
883	OSM_LOG_ENTER(&p_osmt->log);
884
885	memset(&req, 0, sizeof(req));
886	memset(p_context, 0, sizeof(*p_context));
887
888	p_context->p_osmt = p_osmt;
889	req.timeout_ms = p_osmt->opt.transaction_timeout;
890	req.retry_cnt = p_osmt->opt.retry_count;
891	req.flags = OSM_SA_FLAGS_SYNC;
892	req.query_context = p_context;
893	req.pfn_query_cb = osmtest_query_res_cb;
894
895	req.query_type = OSMV_QUERY_PATH_REC_BY_PORT_GUIDS;
896
897	guid_pair.dest_guid = dguid;
898	guid_pair.src_guid = sguid;
899
900	req.p_query_input = &guid_pair;
901	req.sm_key = 0;
902
903	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
904		"Query for path from 0x%" PRIx64 " to 0x%" PRIx64 "\n",
905		sguid, dguid);
906
907	status = osmv_query_sa(p_osmt->h_bind, &req);
908	if (status != IB_SUCCESS) {
909		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0063: "
910			"ib_query failed (%s)\n", ib_get_err_str(status));
911		goto Exit;
912	}
913
914	status = (*p_context).result.status;
915
916	if (status != IB_SUCCESS) {
917		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0066: "
918			"ib_query failed (%s)\n", ib_get_err_str(status));
919
920		if (status == IB_REMOTE_ERROR) {
921			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
922				"Remote error = %s\n",
923				ib_get_mad_status_str(osm_madw_get_mad_ptr
924						      ((*p_context).result.
925						       p_result_madw)));
926		}
927		goto Exit;
928	}
929
930Exit:
931
932	OSM_LOG_EXIT(&p_osmt->log);
933	return (status);
934}
935
936/**********************************************************************
937 **********************************************************************/
938static ib_api_status_t
939osmtest_get_path_rec_by_gid_pair(IN osmtest_t * const p_osmt,
940				 IN ib_gid_t sgid,
941				 IN ib_gid_t dgid,
942				 IN osmtest_req_context_t * p_context)
943{
944	cl_status_t status = IB_SUCCESS;
945	osmv_query_req_t req;
946	osmv_gid_pair_t gid_pair;
947
948	OSM_LOG_ENTER(&p_osmt->log);
949
950	memset(&req, 0, sizeof(req));
951	memset(p_context, 0, sizeof(*p_context));
952
953	p_context->p_osmt = p_osmt;
954	req.timeout_ms = p_osmt->opt.transaction_timeout;
955	req.retry_cnt = p_osmt->opt.retry_count;
956	req.flags = OSM_SA_FLAGS_SYNC;
957	req.query_context = p_context;
958	req.pfn_query_cb = osmtest_query_res_cb;
959
960	req.query_type = OSMV_QUERY_PATH_REC_BY_GIDS;
961
962	gid_pair.dest_gid = dgid;
963	gid_pair.src_gid = sgid;
964
965	req.p_query_input = &gid_pair;
966	req.sm_key = 0;
967
968	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
969		"Query for path from 0x%016" PRIx64 " 0x%016" PRIx64
970		" to 0x%016" PRIx64 " 0x%016" PRIx64 "\n", sgid.unicast.prefix,
971		sgid.unicast.interface_id, dgid.unicast.prefix,
972		dgid.unicast.interface_id);
973
974	status = osmv_query_sa(p_osmt->h_bind, &req);
975	if (status != IB_SUCCESS) {
976		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006A: "
977			"ib_query failed (%s)\n", ib_get_err_str(status));
978		goto Exit;
979	}
980
981	status = (*p_context).result.status;
982
983	if (status != IB_SUCCESS) {
984		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006B: "
985			"ib_query failed (%s)\n", ib_get_err_str(status));
986
987		if (status == IB_REMOTE_ERROR) {
988			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
989				"Remote error = %s\n",
990				ib_get_mad_status_str(osm_madw_get_mad_ptr
991						      ((*p_context).result.
992						       p_result_madw)));
993		}
994		goto Exit;
995	}
996
997Exit:
998
999	OSM_LOG_EXIT(&p_osmt->log);
1000	return (status);
1001}
1002
1003#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
1004/**********************************************************************
1005 **********************************************************************/
1006static ib_api_status_t
1007osmtest_get_multipath_rec(IN osmtest_t * const p_osmt,
1008			  IN osmv_multipath_req_t * p_request,
1009			  IN osmtest_req_context_t * p_context)
1010{
1011	cl_status_t status = IB_SUCCESS;
1012	osmv_query_req_t req;
1013
1014	OSM_LOG_ENTER(&p_osmt->log);
1015
1016	/*
1017	 * Do a blocking query for this record in the subnet.
1018	 * The result is returned in the result field of the caller's
1019	 * context structure.
1020	 *
1021	 * The query structures are locals.
1022	 */
1023	memset(&req, 0, sizeof(req));
1024
1025	p_context->p_osmt = p_osmt;
1026	req.timeout_ms = p_osmt->opt.transaction_timeout;
1027	req.retry_cnt = p_osmt->opt.retry_count;
1028	req.flags = OSM_SA_FLAGS_SYNC;
1029	req.query_context = p_context;
1030	req.pfn_query_cb = osmtest_query_res_cb;
1031
1032	req.query_type = OSMV_QUERY_MULTIPATH_REC;
1033
1034	req.p_query_input = p_request;
1035	req.sm_key = 0;
1036
1037	status = osmv_query_sa(p_osmt->h_bind, &req);
1038	if (status != IB_SUCCESS) {
1039		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0068: "
1040			"ib_query failed (%s)\n", ib_get_err_str(status));
1041		goto Exit;
1042	}
1043
1044	status = p_context->result.status;
1045
1046	if (status != IB_SUCCESS) {
1047		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0069: "
1048			"ib_query failed (%s)\n", ib_get_err_str(status));
1049
1050		if (status == IB_REMOTE_ERROR) {
1051			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1052				"Remote error = %s\n",
1053				ib_get_mad_status_str(osm_madw_get_mad_ptr
1054						      (p_context->result.
1055						       p_result_madw)));
1056		}
1057		goto Exit;
1058	}
1059
1060Exit:
1061	OSM_LOG_EXIT(&p_osmt->log);
1062	return (status);
1063}
1064#endif
1065
1066/**********************************************************************
1067 **********************************************************************/
1068ib_api_status_t
1069osmtest_get_port_rec(IN osmtest_t * const p_osmt,
1070		     IN ib_net16_t const lid,
1071		     IN OUT osmtest_req_context_t * const p_context)
1072{
1073	ib_api_status_t status = IB_SUCCESS;
1074	osmv_user_query_t user;
1075	osmv_query_req_t req;
1076	ib_portinfo_record_t record;
1077
1078	OSM_LOG_ENTER(&p_osmt->log);
1079
1080	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
1081		"Getting PortInfoRecord for port with LID 0x%X\n",
1082		cl_ntoh16(lid));
1083
1084	/*
1085	 * Do a blocking query for this record in the subnet.
1086	 * The result is returned in the result field of the caller's
1087	 * context structure.
1088	 *
1089	 * The query structures are locals.
1090	 */
1091	memset(&req, 0, sizeof(req));
1092	memset(&user, 0, sizeof(user));
1093	memset(&record, 0, sizeof(record));
1094
1095	record.lid = lid;
1096
1097	p_context->p_osmt = p_osmt;
1098	user.comp_mask = IB_PIR_COMPMASK_LID;
1099	user.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;
1100	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
1101	user.p_attr = &record;
1102
1103	req.query_type = OSMV_QUERY_USER_DEFINED;
1104	req.timeout_ms = p_osmt->opt.transaction_timeout;
1105	req.retry_cnt = p_osmt->opt.retry_count;
1106	req.flags = OSM_SA_FLAGS_SYNC;
1107	req.query_context = p_context;
1108	req.pfn_query_cb = osmtest_query_res_cb;
1109	req.p_query_input = &user;
1110	req.sm_key = 0;
1111
1112	status = osmv_query_sa(p_osmt->h_bind, &req);
1113	if (status != IB_SUCCESS) {
1114		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0075: "
1115			"ib_query failed (%s)\n", ib_get_err_str(status));
1116		goto Exit;
1117	}
1118
1119	status = p_context->result.status;
1120
1121	if (status != IB_SUCCESS) {
1122		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0076: "
1123			"ib_query failed (%s)\n", ib_get_err_str(status));
1124
1125		if (status == IB_REMOTE_ERROR) {
1126			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1127				"Remote error = %s\n",
1128				ib_get_mad_status_str(osm_madw_get_mad_ptr
1129						      (p_context->result.
1130						       p_result_madw)));
1131		}
1132		goto Exit;
1133	}
1134
1135Exit:
1136	OSM_LOG_EXIT(&p_osmt->log);
1137	return (status);
1138}
1139
1140/**********************************************************************
1141 **********************************************************************/
1142ib_api_status_t
1143osmtest_get_port_rec_by_num(IN osmtest_t * const p_osmt,
1144			    IN ib_net16_t const lid,
1145			    IN uint8_t const port_num,
1146			    IN OUT osmtest_req_context_t * const p_context)
1147{
1148	ib_api_status_t status = IB_SUCCESS;
1149	osmv_user_query_t user;
1150	osmv_query_req_t req;
1151	ib_portinfo_record_t record;
1152	ib_mad_t *p_mad;
1153
1154	OSM_LOG_ENTER(&p_osmt->log);
1155
1156	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
1157		"Getting PortInfoRecord for port with LID 0x%X Num:0x%X\n",
1158		cl_ntoh16(lid), port_num);
1159
1160	/*
1161	 * Do a blocking query for this record in the subnet.
1162	 * The result is returned in the result field of the caller's
1163	 * context structure.
1164	 *
1165	 * The query structures are locals.
1166	 */
1167	memset(&req, 0, sizeof(req));
1168	memset(&user, 0, sizeof(user));
1169	memset(&record, 0, sizeof(record));
1170
1171	record.lid = lid;
1172	record.port_num = port_num;
1173	user.p_attr = &record;
1174
1175	p_context->p_osmt = p_osmt;
1176
1177	req.query_type = OSMV_QUERY_PORT_REC_BY_LID_AND_NUM;
1178	req.timeout_ms = p_osmt->opt.transaction_timeout;
1179	req.retry_cnt = p_osmt->opt.retry_count;
1180	req.flags = OSM_SA_FLAGS_SYNC;
1181	req.query_context = p_context;
1182	req.pfn_query_cb = osmtest_query_res_cb;
1183	req.p_query_input = &user;
1184	req.sm_key = 0;
1185
1186	status = osmv_query_sa(p_osmt->h_bind, &req);
1187	if (status != IB_SUCCESS) {
1188		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0077: "
1189			"ib_query failed (%s)\n", ib_get_err_str(status));
1190		goto Exit;
1191	}
1192
1193	status = p_context->result.status;
1194
1195	if (status != IB_SUCCESS) {
1196		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0078: "
1197			"ib_query failed (%s)\n", ib_get_err_str(status));
1198
1199		if (status == IB_REMOTE_ERROR) {
1200			p_mad =
1201			    osm_madw_get_mad_ptr(p_context->result.
1202						 p_result_madw);
1203			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1204				"Remote error = %s\n",
1205				ib_get_mad_status_str(p_mad));
1206			status =
1207			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
1208		}
1209		goto Exit;
1210	}
1211
1212Exit:
1213	OSM_LOG_EXIT(&p_osmt->log);
1214	return (status);
1215}
1216
1217/**********************************************************************
1218 **********************************************************************/
1219ib_api_status_t
1220osmtest_stress_port_recs_large(IN osmtest_t * const p_osmt,
1221			       OUT uint32_t * const p_num_recs,
1222			       OUT uint32_t * const p_num_queries)
1223{
1224	osmtest_req_context_t context;
1225	ib_portinfo_record_t *p_rec;
1226	uint32_t i;
1227	cl_status_t status;
1228	uint32_t num_recs = 0;
1229
1230	OSM_LOG_ENTER(&p_osmt->log);
1231
1232	memset(&context, 0, sizeof(context));
1233	/*
1234	 * Do a blocking query for all PortInfoRecords in the subnet.
1235	 */
1236	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_PORTINFO_RECORD,
1237				      sizeof(*p_rec), &context);
1238
1239	if (status != IB_SUCCESS) {
1240		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0006: "
1241			"osmtest_get_all_recs failed (%s)\n",
1242			ib_get_err_str(status));
1243		goto Exit;
1244	}
1245
1246	/*
1247	 * Populate the database with the received records.
1248	 */
1249	num_recs = context.result.result_cnt;
1250	*p_num_recs += num_recs;
1251	++*p_num_queries;
1252
1253	if (osm_log_is_active(&p_osmt->log, OSM_LOG_VERBOSE)) {
1254		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1255			"Received %u records\n", num_recs);
1256
1257		for (i = 0; i < num_recs; i++) {
1258			p_rec =
1259			    osmv_get_query_portinfo_rec(context.result.
1260							p_result_madw, i);
1261			osm_dump_portinfo_record(&p_osmt->log, p_rec,
1262						 OSM_LOG_VERBOSE);
1263		}
1264	}
1265
1266Exit:
1267	/*
1268	 * Return the IB query MAD to the pool as necessary.
1269	 */
1270	if (context.result.p_result_madw != NULL) {
1271		osm_mad_pool_put(&p_osmt->mad_pool,
1272				 context.result.p_result_madw);
1273		context.result.p_result_madw = NULL;
1274	}
1275
1276	OSM_LOG_EXIT(&p_osmt->log);
1277	return (status);
1278}
1279
1280/**********************************************************************
1281 **********************************************************************/
1282ib_api_status_t
1283osmtest_stress_node_recs_large(IN osmtest_t * const p_osmt,
1284			       OUT uint32_t * const p_num_recs,
1285			       OUT uint32_t * const p_num_queries)
1286{
1287	osmtest_req_context_t context;
1288	ib_node_record_t *p_rec;
1289	uint32_t i;
1290	cl_status_t status;
1291	uint32_t num_recs = 0;
1292
1293	OSM_LOG_ENTER(&p_osmt->log);
1294
1295	memset(&context, 0, sizeof(context));
1296
1297	/*
1298	 * Do a blocking query for all NodeRecords in the subnet.
1299	 */
1300	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_NODE_RECORD,
1301				      sizeof(*p_rec), &context);
1302
1303	if (status != IB_SUCCESS) {
1304		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0007: "
1305			"osmtest_get_all_recs failed (%s)\n",
1306			ib_get_err_str(status));
1307		goto Exit;
1308	}
1309
1310	/*
1311	 * Populate the database with the received records.
1312	 */
1313	num_recs = context.result.result_cnt;
1314	*p_num_recs += num_recs;
1315	++*p_num_queries;
1316
1317	if (osm_log_is_active(&p_osmt->log, OSM_LOG_VERBOSE)) {
1318		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1319			"Received %u records\n", num_recs);
1320
1321		for (i = 0; i < num_recs; i++) {
1322			p_rec =
1323			    osmv_get_query_node_rec(context.result.
1324						    p_result_madw, i);
1325			osm_dump_node_record(&p_osmt->log, p_rec,
1326					     OSM_LOG_VERBOSE);
1327		}
1328	}
1329
1330Exit:
1331	/*
1332	 * Return the IB query MAD to the pool as necessary.
1333	 */
1334	if (context.result.p_result_madw != NULL) {
1335		osm_mad_pool_put(&p_osmt->mad_pool,
1336				 context.result.p_result_madw);
1337		context.result.p_result_madw = NULL;
1338	}
1339
1340	OSM_LOG_EXIT(&p_osmt->log);
1341	return (status);
1342}
1343
1344/**********************************************************************
1345 **********************************************************************/
1346ib_api_status_t
1347osmtest_stress_path_recs_large(IN osmtest_t * const p_osmt,
1348			       OUT uint32_t * const p_num_recs,
1349			       OUT uint32_t * const p_num_queries)
1350{
1351	osmtest_req_context_t context;
1352	ib_path_rec_t *p_rec;
1353	uint32_t i;
1354	cl_status_t status;
1355	uint32_t num_recs = 0;
1356
1357	OSM_LOG_ENTER(&p_osmt->log);
1358
1359	memset(&context, 0, sizeof(context));
1360
1361	/*
1362	 * Do a blocking query for all PathRecords in the subnet.
1363	 */
1364	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_PATH_RECORD,
1365				      sizeof(*p_rec), &context);
1366	if (status != IB_SUCCESS) {
1367		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0008: "
1368			"osmtest_get_all_recs failed (%s)\n",
1369			ib_get_err_str(status));
1370		goto Exit;
1371	}
1372
1373	/*
1374	 * Populate the database with the received records.
1375	 */
1376	num_recs = context.result.result_cnt;
1377	*p_num_recs += num_recs;
1378	++*p_num_queries;
1379
1380	if (osm_log_is_active(&p_osmt->log, OSM_LOG_VERBOSE)) {
1381		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1382			"Received %u records\n", num_recs);
1383
1384		for (i = 0; i < num_recs; i++) {
1385			p_rec =
1386			    osmv_get_query_path_rec(context.result.
1387						    p_result_madw, i);
1388			osm_dump_path_record(&p_osmt->log, p_rec,
1389					     OSM_LOG_VERBOSE);
1390		}
1391	}
1392
1393Exit:
1394	/*
1395	 * Return the IB query MAD to the pool as necessary.
1396	 */
1397	if (context.result.p_result_madw != NULL) {
1398		osm_mad_pool_put(&p_osmt->mad_pool,
1399				 context.result.p_result_madw);
1400		context.result.p_result_madw = NULL;
1401	}
1402
1403	OSM_LOG_EXIT(&p_osmt->log);
1404	return (status);
1405}
1406
1407/**********************************************************************
1408 **********************************************************************/
1409ib_api_status_t
1410osmtest_stress_path_recs_by_guid(IN osmtest_t * const p_osmt,
1411				 OUT uint32_t * const p_num_recs,
1412				 OUT uint32_t * const p_num_queries)
1413{
1414	osmtest_req_context_t context;
1415	ib_path_rec_t *p_rec;
1416	uint32_t i;
1417	cl_status_t status = IB_SUCCESS;
1418	uint32_t num_recs = 0;
1419	node_t *p_src_node, *p_dst_node;
1420	cl_qmap_t *p_tbl;
1421
1422	OSM_LOG_ENTER(&p_osmt->log);
1423
1424	memset(&context, 0, sizeof(context));
1425
1426	context.p_osmt = p_osmt;
1427
1428	p_tbl = &p_osmt->exp_subn.node_guid_tbl;
1429
1430	p_src_node = (node_t *) cl_qmap_head(p_tbl);
1431
1432	/*
1433	 * Go over all nodes that exist in the subnet
1434	 * for each pair that are not switch nodes get the path record
1435	 */
1436	while (p_src_node != (node_t *) cl_qmap_end(p_tbl)) {
1437		p_dst_node = (node_t *) cl_qmap_head(p_tbl);
1438
1439		while (p_dst_node != (node_t *) cl_qmap_end(p_tbl)) {
1440			/*
1441			 * Do a blocking query for CA to CA Path Record
1442			 */
1443			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1444				"Source : guid = 0x%" PRIx64 " type = %d"
1445				"Target : guid = 0x%" PRIx64 " type = %d\n",
1446				cl_ntoh64(p_src_node->rec.node_info.port_guid),
1447				p_src_node->rec.node_info.node_type,
1448				cl_ntoh64(p_dst_node->rec.node_info.port_guid),
1449				p_dst_node->rec.node_info.node_type);
1450
1451			if (p_src_node->rec.node_info.node_type ==
1452			    IB_NODE_TYPE_CA
1453			    && p_dst_node->rec.node_info.node_type ==
1454			    IB_NODE_TYPE_CA) {
1455				status =
1456				    osmtest_get_path_rec_by_guid_pair(p_osmt,
1457								      p_src_node->
1458								      rec.
1459								      node_info.
1460								      port_guid,
1461								      p_dst_node->
1462								      rec.
1463								      node_info.
1464								      port_guid,
1465								      &context);
1466
1467				/* In a case of TIMEOUT you still can try sending but cant count, maybe its a temporary issue */
1468				if (status != IB_SUCCESS) {
1469					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1470						"ERR 0009: "
1471						"osmtest_get_path_rec_by_guid_pair failed (%s)\n",
1472						ib_get_err_str(status));
1473					if (status != IB_TIMEOUT)
1474						goto Exit;
1475				} else {
1476					/* we might have received several records */
1477					num_recs = context.result.result_cnt;
1478					/*
1479					 * Populate the database with the received records.
1480					 */
1481					*p_num_recs += num_recs;
1482					++*p_num_queries;
1483					OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1484						"Received %u records\n", num_recs);
1485					/* Dont waste time if not VERBOSE and above */
1486					if (p_osmt->log.level & OSM_LOG_VERBOSE) {
1487						for (i = 0; i < num_recs; i++) {
1488							p_rec =
1489							    osmv_get_query_path_rec
1490							    (context.result.
1491							     p_result_madw, i);
1492							osm_dump_path_record
1493							    (&p_osmt->log,
1494							     p_rec,
1495							     OSM_LOG_VERBOSE);
1496						}
1497					}
1498				}
1499				if (context.result.p_result_madw != NULL) {
1500					osm_mad_pool_put(&p_osmt->mad_pool,
1501							 context.result.
1502							 p_result_madw);
1503					context.result.p_result_madw = NULL;
1504				}
1505			}
1506			/* next one please */
1507			p_dst_node =
1508			    (node_t *) cl_qmap_next(&p_dst_node->map_item);
1509		}
1510
1511		p_src_node = (node_t *) cl_qmap_next(&p_src_node->map_item);
1512	}
1513
1514Exit:
1515	OSM_LOG_EXIT(&p_osmt->log);
1516	return (status);
1517}
1518
1519/**********************************************************************
1520 **********************************************************************/
1521ib_api_status_t
1522osmtest_stress_port_recs_small(IN osmtest_t * const p_osmt,
1523			       OUT uint32_t * const p_num_recs,
1524			       OUT uint32_t * const p_num_queries)
1525{
1526	osmtest_req_context_t context;
1527	ib_portinfo_record_t *p_rec;
1528	uint32_t i;
1529	cl_status_t status;
1530	uint32_t num_recs = 0;
1531
1532	OSM_LOG_ENTER(&p_osmt->log);
1533
1534	memset(&context, 0, sizeof(context));
1535
1536	/*
1537	 * Do a blocking query for our own PortInfoRecord in the subnet.
1538	 */
1539	status = osmtest_get_port_rec(p_osmt,
1540				      cl_ntoh16(p_osmt->local_port.lid),
1541				      &context);
1542
1543	if (status != IB_SUCCESS) {
1544		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0010: "
1545			"osmtest_get_port_rec failed (%s)\n",
1546			ib_get_err_str(status));
1547		goto Exit;
1548	}
1549
1550	/*
1551	 * Populate the database with the received records.
1552	 */
1553	num_recs = context.result.result_cnt;
1554	*p_num_recs += num_recs;
1555	++*p_num_queries;
1556
1557	if (osm_log_is_active(&p_osmt->log, OSM_LOG_VERBOSE)) {
1558		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1559			"Received %u records\n", num_recs);
1560
1561		for (i = 0; i < num_recs; i++) {
1562			p_rec =
1563			    osmv_get_query_portinfo_rec(context.result.
1564							p_result_madw, i);
1565			osm_dump_portinfo_record(&p_osmt->log, p_rec,
1566						 OSM_LOG_VERBOSE);
1567		}
1568	}
1569
1570Exit:
1571	/*
1572	 * Return the IB query MAD to the pool as necessary.
1573	 */
1574	if (context.result.p_result_madw != NULL) {
1575		osm_mad_pool_put(&p_osmt->mad_pool,
1576				 context.result.p_result_madw);
1577		context.result.p_result_madw = NULL;
1578	}
1579
1580	OSM_LOG_EXIT(&p_osmt->log);
1581	return (status);
1582}
1583
1584/**********************************************************************
1585 **********************************************************************/
1586ib_api_status_t
1587osmtest_get_local_port_lmc(IN osmtest_t * const p_osmt,
1588			   IN ib_net16_t lid, OUT uint8_t * const p_lmc)
1589{
1590	osmtest_req_context_t context;
1591	ib_portinfo_record_t *p_rec;
1592	uint32_t i;
1593	cl_status_t status;
1594	uint32_t num_recs = 0;
1595
1596	OSM_LOG_ENTER(&p_osmt->log);
1597
1598	memset(&context, 0, sizeof(context));
1599
1600	/*
1601	 * Do a blocking query for our own PortInfoRecord in the subnet.
1602	 */
1603	status = osmtest_get_port_rec(p_osmt, cl_ntoh16(lid), &context);
1604
1605	if (status != IB_SUCCESS) {
1606		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 001A: "
1607			"osmtest_get_port_rec failed (%s)\n",
1608			ib_get_err_str(status));
1609		goto Exit;
1610	}
1611
1612	num_recs = context.result.result_cnt;
1613
1614	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %u records\n", num_recs);
1615
1616	for (i = 0; i < num_recs; i++) {
1617		p_rec =
1618		    osmv_get_query_portinfo_rec(context.result.p_result_madw,
1619						i);
1620		osm_dump_portinfo_record(&p_osmt->log, p_rec, OSM_LOG_VERBOSE);
1621		if (p_lmc) {
1622			*p_lmc = ib_port_info_get_lmc(&p_rec->port_info);
1623			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "LMC %d\n", *p_lmc);
1624		}
1625	}
1626
1627Exit:
1628	/*
1629	 * Return the IB query MAD to the pool as necessary.
1630	 */
1631	if (context.result.p_result_madw != NULL) {
1632		osm_mad_pool_put(&p_osmt->mad_pool,
1633				 context.result.p_result_madw);
1634		context.result.p_result_madw = NULL;
1635	}
1636
1637	OSM_LOG_EXIT(&p_osmt->log);
1638	return (status);
1639}
1640
1641/**********************************************************************
1642 * Use a wrong SM_Key in a simple port query and report success if
1643 * failed.
1644 **********************************************************************/
1645ib_api_status_t osmtest_wrong_sm_key_ignored(IN osmtest_t * const p_osmt)
1646{
1647	ib_api_status_t status = IB_SUCCESS;
1648	osmv_user_query_t user;
1649	osmv_query_req_t req;
1650	ib_portinfo_record_t record;
1651	osmtest_req_context_t context;
1652	osmtest_req_context_t *p_context = &context;
1653	uint8_t port_num = 1;
1654
1655	OSM_LOG_ENTER(&p_osmt->log);
1656
1657	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1658		"Trying PortInfoRecord for port with LID 0x%X Num:0x%X\n",
1659		p_osmt->local_port.sm_lid, port_num);
1660
1661	/*
1662	 * Do a blocking query for this record in the subnet.
1663	 * The result is returned in the result field of the caller's
1664	 * context structure.
1665	 *
1666	 * The query structures are locals.
1667	 */
1668	memset(&req, 0, sizeof(req));
1669	memset(&user, 0, sizeof(user));
1670	memset(&record, 0, sizeof(record));
1671
1672	record.lid = p_osmt->local_port.sm_lid;
1673	record.port_num = port_num;
1674	user.p_attr = &record;
1675
1676	p_context->p_osmt = p_osmt;
1677
1678	req.query_type = OSMV_QUERY_PORT_REC_BY_LID_AND_NUM;
1679	req.timeout_ms = p_osmt->opt.transaction_timeout;
1680	req.retry_cnt = p_osmt->opt.retry_count;
1681	req.flags = OSM_SA_FLAGS_SYNC;
1682	req.query_context = p_context;
1683	req.pfn_query_cb = osmtest_query_res_cb;
1684	req.p_query_input = &user;
1685	req.sm_key = 9999;
1686	context.result.p_result_madw = NULL;
1687
1688	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1689	status = osmv_query_sa(p_osmt->h_bind, &req);
1690	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1691
1692	/* since we use a wrong sm_key we should get a timeout */
1693	if (status != IB_TIMEOUT) {
1694		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0011: "
1695			"Did not get a timeout but got (%s)\n",
1696			ib_get_err_str(status));
1697		if (status == IB_SUCCESS) {
1698			/* assign some error value to status, since IB_SUCCESS is a bad rc */
1699			status = IB_ERROR;
1700		}
1701		goto Exit;
1702	} else {
1703		status = IB_SUCCESS;
1704	}
1705
1706Exit:
1707	if (context.result.p_result_madw != NULL) {
1708		osm_mad_pool_put(&p_osmt->mad_pool,
1709				 context.result.p_result_madw);
1710		context.result.p_result_madw = NULL;
1711	}
1712
1713	OSM_LOG_EXIT(&p_osmt->log);
1714	return (status);
1715}
1716
1717/**********************************************************************
1718 **********************************************************************/
1719static ib_api_status_t
1720osmtest_write_port_info(IN osmtest_t * const p_osmt,
1721			IN FILE * fh,
1722			IN const ib_portinfo_record_t * const p_rec)
1723{
1724	int result;
1725	cl_status_t status = IB_SUCCESS;
1726
1727	OSM_LOG_ENTER(&p_osmt->log);
1728
1729	result = fprintf(fh,
1730			 "DEFINE_PORT\n"
1731			 "lid                     0x%X\n"
1732			 "port_num                0x%X\n"
1733			 "m_key                   0x%016" PRIx64 "\n"
1734			 "subnet_prefix           0x%016" PRIx64 "\n"
1735			 "base_lid                0x%X\n"
1736			 "master_sm_base_lid      0x%X\n"
1737			 "capability_mask         0x%X\n"
1738			 "diag_code               0x%X\n"
1739			 "m_key_lease_period      0x%X\n"
1740			 "local_port_num          0x%X\n"
1741			 "link_width_enabled      0x%X\n"
1742			 "link_width_supported    0x%X\n"
1743			 "link_width_active       0x%X\n"
1744			 "link_speed_supported    0x%X\n"
1745			 "port_state              %s\n"
1746			 "state_info2             0x%X\n"
1747			 "mpb                     0x%X\n"
1748			 "lmc                     0x%X\n"
1749			 "link_speed              0x%X\n"
1750			 "mtu_smsl                0x%X\n"
1751			 "vl_cap                  0x%X\n"
1752			 "vl_high_limit           0x%X\n"
1753			 "vl_arb_high_cap         0x%X\n"
1754			 "vl_arb_low_cap          0x%X\n"
1755			 "mtu_cap                 0x%X\n"
1756			 "vl_stall_life           0x%X\n"
1757			 "vl_enforce              0x%X\n"
1758			 "m_key_violations        0x%X\n"
1759			 "p_key_violations        0x%X\n"
1760			 "q_key_violations        0x%X\n"
1761			 "guid_cap                0x%X\n"
1762			 "subnet_timeout          0x%X\n"
1763			 "resp_time_value         0x%X\n"
1764			 "error_threshold         0x%X\n"
1765			 "END\n\n",
1766			 cl_ntoh16(p_rec->lid),
1767			 p_rec->port_num,
1768			 cl_ntoh64(p_rec->port_info.m_key),
1769			 cl_ntoh64(p_rec->port_info.subnet_prefix),
1770			 cl_ntoh16(p_rec->port_info.base_lid),
1771			 cl_ntoh16(p_rec->port_info.master_sm_base_lid),
1772			 cl_ntoh32(p_rec->port_info.capability_mask),
1773			 cl_ntoh16(p_rec->port_info.diag_code),
1774			 cl_ntoh16(p_rec->port_info.m_key_lease_period),
1775			 p_rec->port_info.local_port_num,
1776			 p_rec->port_info.link_width_enabled,
1777			 p_rec->port_info.link_width_supported,
1778			 p_rec->port_info.link_width_active,
1779			 ib_port_info_get_link_speed_sup(&p_rec->port_info),
1780			 ib_get_port_state_str(ib_port_info_get_port_state
1781					       (&p_rec->port_info)),
1782			 p_rec->port_info.state_info2,
1783			 ib_port_info_get_mpb(&p_rec->port_info),
1784			 ib_port_info_get_lmc(&p_rec->port_info),
1785			 p_rec->port_info.link_speed, p_rec->port_info.mtu_smsl,
1786			 p_rec->port_info.vl_cap,
1787			 p_rec->port_info.vl_high_limit,
1788			 p_rec->port_info.vl_arb_high_cap,
1789			 p_rec->port_info.vl_arb_low_cap,
1790			 p_rec->port_info.mtu_cap,
1791			 p_rec->port_info.vl_stall_life,
1792			 p_rec->port_info.vl_enforce,
1793			 cl_ntoh16(p_rec->port_info.m_key_violations),
1794			 cl_ntoh16(p_rec->port_info.p_key_violations),
1795			 cl_ntoh16(p_rec->port_info.q_key_violations),
1796			 p_rec->port_info.guid_cap,
1797			 ib_port_info_get_timeout(&p_rec->port_info),
1798			 p_rec->port_info.resp_time_value,
1799			 p_rec->port_info.error_threshold);
1800
1801	if (result < 0) {
1802		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0161: "
1803			"Write failed\n");
1804		status = IB_ERROR;
1805		goto Exit;
1806	}
1807
1808Exit:
1809	OSM_LOG_EXIT(&p_osmt->log);
1810	return (status);
1811}
1812
1813/**********************************************************************
1814 **********************************************************************/
1815static ib_api_status_t
1816osmtest_write_path_info(IN osmtest_t * const p_osmt,
1817			IN FILE * fh, IN const ib_path_rec_t * const p_rec)
1818{
1819	int result;
1820	cl_status_t status = IB_SUCCESS;
1821
1822	OSM_LOG_ENTER(&p_osmt->log);
1823
1824	result = fprintf(fh,
1825			 "DEFINE_PATH\n"
1826			 "dgid                    0x%016" PRIx64 " 0x%016"
1827			 PRIx64 "\nsgid                    0x%016" PRIx64
1828			 " 0x%016" PRIx64 "\ndlid                    0x%X\n"
1829			 "slid                    0x%X\n"
1830			 "# hop_flow_raw          0x%X\n"
1831			 "# tclass                0x%X\n"
1832			 "# num_path              0x%X\n"
1833			 "pkey                    0x%X\n"
1834			 "# sl                    0x%X\n"
1835			 "# qos_class             0x%X\n"
1836			 "# mtu                   0x%X\n"
1837			 "# rate                  0x%X\n"
1838			 "# pkt_life              0x%X\n"
1839			 "# preference            0x%X\n" "END\n\n",
1840			 cl_ntoh64(p_rec->dgid.unicast.prefix),
1841			 cl_ntoh64(p_rec->dgid.unicast.interface_id),
1842			 cl_ntoh64(p_rec->sgid.unicast.prefix),
1843			 cl_ntoh64(p_rec->sgid.unicast.interface_id),
1844			 cl_ntoh16(p_rec->dlid), cl_ntoh16(p_rec->slid),
1845			 cl_ntoh32(p_rec->hop_flow_raw), p_rec->tclass,
1846			 p_rec->num_path, cl_ntoh16(p_rec->pkey),
1847			 ib_path_rec_sl(p_rec), ib_path_rec_qos_class(p_rec),
1848			 p_rec->mtu, p_rec->rate, p_rec->pkt_life,
1849			 p_rec->preference);
1850
1851	if (result < 0) {
1852		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0162: "
1853			"Write failed\n");
1854		status = IB_ERROR;
1855		goto Exit;
1856	}
1857
1858Exit:
1859	OSM_LOG_EXIT(&p_osmt->log);
1860	return (status);
1861}
1862
1863/**********************************************************************
1864 **********************************************************************/
1865static ib_api_status_t
1866osmtest_write_node_info(IN osmtest_t * const p_osmt,
1867			IN FILE * fh, IN const ib_node_record_t * const p_rec)
1868{
1869	int result;
1870	cl_status_t status = IB_SUCCESS;
1871	char desc[IB_NODE_DESCRIPTION_SIZE + 1];
1872
1873	OSM_LOG_ENTER(&p_osmt->log);
1874
1875	memcpy(desc, p_rec->node_desc.description, IB_NODE_DESCRIPTION_SIZE);
1876	desc[IB_NODE_DESCRIPTION_SIZE] = '\0';
1877
1878	result = fprintf(fh,
1879			 "DEFINE_NODE\n"
1880			 "lid                     0x%X\n"
1881			 "base_version            0x%X\n"
1882			 "class_version           0x%X\n"
1883			 "node_type               0x%X # (%s)\n"
1884			 "num_ports               0x%X\n"
1885			 "sys_guid                0x%016" PRIx64 "\n"
1886			 "node_guid               0x%016" PRIx64 "\n"
1887			 "port_guid               0x%016" PRIx64 "\n"
1888			 "partition_cap           0x%X\n"
1889			 "device_id               0x%X\n"
1890			 "revision                0x%X\n"
1891			 "# port_num              0x%X\n"
1892			 "# vendor_id             0x%X\n"
1893			 "# node_desc             %s\n"
1894			 "END\n\n",
1895			 cl_ntoh16(p_rec->lid),
1896			 p_rec->node_info.base_version,
1897			 p_rec->node_info.class_version,
1898			 p_rec->node_info.node_type,
1899			 ib_get_node_type_str(p_rec->node_info.node_type),
1900			 p_rec->node_info.num_ports,
1901			 cl_ntoh64(p_rec->node_info.sys_guid),
1902			 cl_ntoh64(p_rec->node_info.node_guid),
1903			 cl_ntoh64(p_rec->node_info.port_guid),
1904			 cl_ntoh16(p_rec->node_info.partition_cap),
1905			 cl_ntoh16(p_rec->node_info.device_id),
1906			 cl_ntoh32(p_rec->node_info.revision),
1907			 ib_node_info_get_local_port_num(&p_rec->node_info),
1908			 cl_ntoh32(ib_node_info_get_vendor_id
1909				   (&p_rec->node_info)), desc);
1910
1911	if (result < 0) {
1912		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0163: "
1913			"Write failed\n");
1914		status = IB_ERROR;
1915		goto Exit;
1916	}
1917
1918Exit:
1919	OSM_LOG_EXIT(&p_osmt->log);
1920	return (status);
1921}
1922
1923/**********************************************************************
1924 **********************************************************************/
1925static ib_api_status_t
1926osmtest_write_link(IN osmtest_t * const p_osmt,
1927		   IN FILE * fh, IN const ib_link_record_t * const p_rec)
1928{
1929	int result;
1930	cl_status_t status = IB_SUCCESS;
1931
1932	OSM_LOG_ENTER(&p_osmt->log);
1933
1934	result = fprintf(fh,
1935			 "DEFINE_LINK\n"
1936			 "from_lid                0x%X\n"
1937			 "from_port_num           0x%X\n"
1938			 "to_port_num             0x%X\n"
1939			 "to_lid                  0x%X\n"
1940			 "END\n\n",
1941			 cl_ntoh16(p_rec->from_lid),
1942			 p_rec->from_port_num,
1943			 p_rec->to_port_num, cl_ntoh16(p_rec->to_lid));
1944
1945	if (result < 0) {
1946		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0164: "
1947			"Write failed\n");
1948		status = IB_ERROR;
1949		goto Exit;
1950	}
1951
1952Exit:
1953	OSM_LOG_EXIT(&p_osmt->log);
1954	return (status);
1955}
1956
1957/**********************************************************************
1958 **********************************************************************/
1959static ib_api_status_t
1960osmtest_write_all_link_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
1961{
1962	osmtest_req_context_t context;
1963	const ib_link_record_t *p_rec;
1964	uint32_t i;
1965	cl_status_t status;
1966	size_t num_recs;
1967	int result;
1968
1969	OSM_LOG_ENTER(&p_osmt->log);
1970
1971	memset(&context, 0, sizeof(context));
1972
1973	/*
1974	 * Do a blocking query for all NodeRecords in the subnet.
1975	 */
1976	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_LINK_RECORD,
1977				      sizeof(*p_rec), &context);
1978
1979	if (status != IB_SUCCESS) {
1980		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0165: "
1981			"osmtest_get_all_recs failed (%s)\n",
1982			ib_get_err_str(status));
1983		goto Exit;
1984	}
1985
1986	/*
1987	 * Write the received records out to the file.
1988	 */
1989	num_recs = context.result.result_cnt;
1990
1991	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1992		"Received %zu records\n", num_recs);
1993
1994	result = fprintf(fh, "#\n" "# Link Records\n" "#\n");
1995	if (result < 0) {
1996		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0166: "
1997			"Write failed\n");
1998		status = IB_ERROR;
1999		goto Exit;
2000	}
2001
2002	for (i = 0; i < num_recs; i++) {
2003		p_rec =
2004		    (ib_link_record_t *) osmv_get_query_result(context.result.
2005							       p_result_madw,
2006							       i);
2007
2008		osmtest_write_link(p_osmt, fh, p_rec);
2009	}
2010
2011Exit:
2012	/*
2013	 * Return the IB query MAD to the pool as necessary.
2014	 */
2015	if (context.result.p_result_madw != NULL) {
2016		osm_mad_pool_put(&p_osmt->mad_pool,
2017				 context.result.p_result_madw);
2018		context.result.p_result_madw = NULL;
2019	}
2020
2021	OSM_LOG_EXIT(&p_osmt->log);
2022	return (status);
2023}
2024
2025/**********************************************************************
2026 **********************************************************************/
2027static ib_api_status_t
2028osmtest_get_path_rec_by_lid_pair(IN osmtest_t * const p_osmt,
2029				 IN ib_net16_t slid,
2030				 IN ib_net16_t dlid,
2031				 IN osmtest_req_context_t * p_context)
2032{
2033	cl_status_t status = IB_SUCCESS;
2034	osmv_query_req_t req;
2035	osmv_lid_pair_t lid_pair;
2036
2037	OSM_LOG_ENTER(&p_osmt->log);
2038
2039	memset(&req, 0, sizeof(req));
2040	memset(p_context, 0, sizeof(*p_context));
2041
2042	p_context->p_osmt = p_osmt;
2043	req.timeout_ms = p_osmt->opt.transaction_timeout;
2044	req.retry_cnt = p_osmt->opt.retry_count;
2045	req.flags = OSM_SA_FLAGS_SYNC;
2046	req.query_context = p_context;
2047	req.pfn_query_cb = osmtest_query_res_cb;
2048
2049	req.query_type = OSMV_QUERY_PATH_REC_BY_LIDS;
2050
2051	lid_pair.dest_lid = dlid;
2052	lid_pair.src_lid = slid;
2053
2054	req.p_query_input = &lid_pair;
2055	req.sm_key = 0;
2056
2057	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2058		"Query for path from 0x%X to 0x%X\n", slid, dlid);
2059	status = osmv_query_sa(p_osmt->h_bind, &req);
2060	if (status != IB_SUCCESS) {
2061		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0053: "
2062			"ib_query failed (%s)\n", ib_get_err_str(status));
2063		goto Exit;
2064	}
2065
2066	status = (*p_context).result.status;
2067
2068	if (status != IB_SUCCESS) {
2069		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0067: "
2070			"ib_query failed (%s)\n", ib_get_err_str(status));
2071
2072		if (status == IB_REMOTE_ERROR) {
2073			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2074				"Remote error = %s\n",
2075				ib_get_mad_status_str(osm_madw_get_mad_ptr
2076						      ((*p_context).result.
2077						       p_result_madw)));
2078		}
2079		goto Exit;
2080	}
2081
2082Exit:
2083	OSM_LOG_EXIT(&p_osmt->log);
2084	return (status);
2085}
2086
2087#ifdef VENDOR_RMPP_SUPPORT
2088/**********************************************************************
2089 * ASSUMES RMPP
2090 **********************************************************************/
2091static ib_api_status_t
2092osmtest_write_all_node_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2093{
2094	osmtest_req_context_t context;
2095	const ib_node_record_t *p_rec;
2096	uint32_t i;
2097	cl_status_t status;
2098	size_t num_recs;
2099	int result;
2100
2101	OSM_LOG_ENTER(&p_osmt->log);
2102
2103	memset(&context, 0, sizeof(context));
2104
2105	/*
2106	 * Do a blocking query for all NodeRecords in the subnet.
2107	 */
2108	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_NODE_RECORD,
2109				      sizeof(*p_rec), &context);
2110
2111	if (status != IB_SUCCESS) {
2112		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0022: "
2113			"osmtest_get_all_recs failed (%s)\n",
2114			ib_get_err_str(status));
2115		goto Exit;
2116	}
2117
2118	/*
2119	 * Write the received records out to the file.
2120	 */
2121	num_recs = context.result.result_cnt;
2122
2123	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n", num_recs);
2124
2125	result = fprintf(fh, "#\n" "# Node Records\n" "#\n");
2126	if (result < 0) {
2127		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0023: "
2128			"Write failed\n");
2129		status = IB_ERROR;
2130		goto Exit;
2131	}
2132
2133	for (i = 0; i < num_recs; i++) {
2134		p_rec =
2135		    osmv_get_query_node_rec(context.result.p_result_madw, i);
2136		osmtest_write_node_info(p_osmt, fh, p_rec);
2137	}
2138
2139Exit:
2140	/*
2141	 * Return the IB query MAD to the pool as necessary.
2142	 */
2143	if (context.result.p_result_madw != NULL) {
2144		osm_mad_pool_put(&p_osmt->mad_pool,
2145				 context.result.p_result_madw);
2146		context.result.p_result_madw = NULL;
2147	}
2148
2149	OSM_LOG_EXIT(&p_osmt->log);
2150	return (status);
2151}
2152
2153/**********************************************************************
2154 * ASSUMES RMPP
2155 **********************************************************************/
2156static ib_api_status_t
2157osmtest_write_all_port_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2158{
2159	osmtest_req_context_t context;
2160	const ib_portinfo_record_t *p_rec;
2161	uint32_t i;
2162	cl_status_t status;
2163	size_t num_recs;
2164	int result;
2165
2166	OSM_LOG_ENTER(&p_osmt->log);
2167
2168	memset(&context, 0, sizeof(context));
2169
2170	/*
2171	 * Do a blocking query for all NodeRecords in the subnet.
2172	 */
2173	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_PORTINFO_RECORD,
2174				      sizeof(*p_rec), &context);
2175
2176	if (status != IB_SUCCESS) {
2177		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0167: "
2178			"osmtest_get_all_recs failed (%s)\n",
2179			ib_get_err_str(status));
2180		goto Exit;
2181	}
2182
2183	/*
2184	 * Write the received records out to the file.
2185	 */
2186	num_recs = context.result.result_cnt;
2187
2188	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n", num_recs);
2189
2190	result = fprintf(fh, "#\n" "# PortInfo Records\n" "#\n");
2191	if (result < 0) {
2192		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0024: "
2193			"Write failed\n");
2194		status = IB_ERROR;
2195		goto Exit;
2196	}
2197
2198	for (i = 0; i < num_recs; i++) {
2199		p_rec =
2200		    osmv_get_query_portinfo_rec(context.result.p_result_madw,
2201						i);
2202		osmtest_write_port_info(p_osmt, fh, p_rec);
2203	}
2204
2205Exit:
2206	/*
2207	 * Return the IB query MAD to the pool as necessary.
2208	 */
2209	if (context.result.p_result_madw != NULL) {
2210		osm_mad_pool_put(&p_osmt->mad_pool,
2211				 context.result.p_result_madw);
2212		context.result.p_result_madw = NULL;
2213	}
2214
2215	OSM_LOG_EXIT(&p_osmt->log);
2216	return (status);
2217}
2218
2219/**********************************************************************
2220 * ASSUMES RMPP
2221 **********************************************************************/
2222static ib_api_status_t
2223osmtest_write_all_path_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2224{
2225	osmtest_req_context_t context;
2226	const ib_path_rec_t *p_rec;
2227	uint32_t i;
2228	cl_status_t status;
2229	size_t num_recs;
2230	int result;
2231
2232	OSM_LOG_ENTER(&p_osmt->log);
2233
2234	memset(&context, 0, sizeof(context));
2235
2236	/*
2237	 * Do a blocking query for all PathRecords in the subnet.
2238	 */
2239	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_PATH_RECORD,
2240				      sizeof(*p_rec), &context);
2241
2242	if (status != IB_SUCCESS) {
2243		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0025: "
2244			"osmtest_get_all_recs failed (%s)\n",
2245			ib_get_err_str(status));
2246		goto Exit;
2247	}
2248
2249	/*
2250	 * Write the received records out to the file.
2251	 */
2252	num_recs = context.result.result_cnt;
2253
2254	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n", num_recs);
2255
2256	result = fprintf(fh, "#\n" "# Path Records\n" "#\n");
2257	if (result < 0) {
2258		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0026: "
2259			"Write failed\n");
2260		status = IB_ERROR;
2261		goto Exit;
2262	}
2263
2264	for (i = 0; i < num_recs; i++) {
2265		p_rec =
2266		    osmv_get_query_path_rec(context.result.p_result_madw, i);
2267		osmtest_write_path_info(p_osmt, fh, p_rec);
2268	}
2269
2270Exit:
2271	/*
2272	 * Return the IB query MAD to the pool as necessary.
2273	 */
2274	if (context.result.p_result_madw != NULL) {
2275		osm_mad_pool_put(&p_osmt->mad_pool,
2276				 context.result.p_result_madw);
2277		context.result.p_result_madw = NULL;
2278	}
2279
2280	OSM_LOG_EXIT(&p_osmt->log);
2281	return (status);
2282}
2283
2284#else
2285/*
2286 * NON RMPP BASED QUERY FOR ALL NODES: BASED ON THE MAX LID GIVEN BY THE USER
2287 */
2288static ib_api_status_t
2289osmtest_write_all_node_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2290{
2291	osmtest_req_context_t context;
2292	node_t *p_node;
2293	node_t *p_guid_node;
2294	const ib_node_record_t *p_rec;
2295	cl_status_t status = CL_SUCCESS;
2296	int result;
2297	uint16_t lid;
2298
2299	OSM_LOG_ENTER(&p_osmt->log);
2300
2301	result = fprintf(fh, "#\n" "# Node Records\n" "#\n");
2302	if (result < 0) {
2303		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0027: "
2304			"Write failed\n");
2305		status = IB_ERROR;
2306		goto Exit;
2307	}
2308
2309	/*
2310	 * Go over all LIDs in the range 1 to max_lid and do a
2311	 * NodeRecord query by that lid.
2312	 */
2313	for (lid = 1; lid <= p_osmt->max_lid; lid++) {
2314		/* prepare the query context */
2315		memset(&context, 0, sizeof(context));
2316
2317		status =
2318		    osmtest_get_node_rec_by_lid(p_osmt, cl_ntoh16(lid),
2319						&context);
2320		if (status != IB_SUCCESS) {
2321			if (status != IB_SA_MAD_STATUS_NO_RECORDS) {
2322				OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "ERR 0028: "
2323					"failed to get node info for LID:0x%02X (%s)\n",
2324					cl_ntoh16(lid), ib_get_err_str(status));
2325				goto Exit;
2326			} else {
2327				OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "WRN 0121: "
2328					"failed to get node info for LID:0x%02X (%s)\n",
2329					cl_ntoh16(lid), ib_get_err_str(status));
2330				status = IB_SUCCESS;
2331			}
2332		} else {
2333			/* OK we got something */
2334			p_rec =
2335			    osmv_get_query_node_rec(context.result.
2336						    p_result_madw, 0);
2337			osmtest_write_node_info(p_osmt, fh, p_rec);
2338
2339			/* create a subnet object */
2340			p_node = node_new();
2341			CL_ASSERT(p_node != NULL);
2342
2343			/* copy the info to the subnet node object */
2344			p_node->rec = *p_rec;
2345
2346			cl_qmap_insert(&p_osmt->exp_subn.node_lid_tbl,
2347				       p_node->rec.lid, &p_node->map_item);
2348
2349			p_guid_node = node_new();
2350			CL_ASSERT(p_guid_node != NULL);
2351
2352			*p_guid_node = *p_node;
2353
2354			cl_qmap_insert(&p_osmt->exp_subn.node_guid_tbl,
2355				       p_guid_node->rec.node_info.node_guid,
2356				       &p_guid_node->map_item);
2357
2358		}
2359
2360		if (context.result.p_result_madw != NULL) {
2361			osm_mad_pool_put(&p_osmt->mad_pool,
2362					 context.result.p_result_madw);
2363			context.result.p_result_madw = NULL;
2364		}
2365	}
2366
2367Exit:
2368	if (context.result.p_result_madw != NULL) {
2369		osm_mad_pool_put(&p_osmt->mad_pool,
2370				 context.result.p_result_madw);
2371		context.result.p_result_madw = NULL;
2372	}
2373
2374	OSM_LOG_EXIT(&p_osmt->log);
2375	return (status);
2376}
2377
2378/*
2379 * GET ALL PORT RECORDS IN THE FABRIC -
2380 * one by one by using the node info received
2381 */
2382static ib_api_status_t
2383osmtest_write_all_port_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2384{
2385	osmtest_req_context_t context;
2386	const ib_node_record_t *p_node_rec;
2387	const ib_portinfo_record_t *p_rec;
2388	uint8_t port_num;
2389	cl_status_t status = CL_SUCCESS;
2390	cl_qmap_t *p_tbl;
2391	node_t *p_node;
2392	port_t *p_port;
2393	int result;
2394
2395	OSM_LOG_ENTER(&p_osmt->log);
2396
2397	memset(&context, 0, sizeof(context));
2398
2399	/* print header */
2400	result = fprintf(fh, "#\n" "# PortInfo Records\n" "#\n");
2401	if (result < 0) {
2402		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0029: "
2403			"Write failed\n");
2404		status = IB_ERROR;
2405		goto Exit;
2406	}
2407
2408	/* use the pre-explored set of nodes */
2409	p_tbl = &p_osmt->exp_subn.node_lid_tbl;
2410	p_node = (node_t *) cl_qmap_head(p_tbl);
2411
2412	/*
2413	 * Go over all LIDs in the range 1 to max_lid and do a
2414	 * NodeRecord query by that lid.
2415	 */
2416	while (p_node != (node_t *) cl_qmap_end(p_tbl)) {
2417
2418		p_node_rec = &(p_node->rec);
2419
2420		/* go through all ports of the node: */
2421		for (port_num = 0; port_num <= p_node_rec->node_info.num_ports;
2422		     port_num++) {
2423			/* prepare the query context */
2424			memset(&context, 0, sizeof(context));
2425
2426			status = osmtest_get_port_rec_by_num(p_osmt,
2427							     p_node_rec->lid,
2428							     port_num,
2429							     &context);
2430			if (status != IB_SUCCESS) {
2431				if (status != IB_SA_MAD_STATUS_NO_RECORDS) {
2432					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2433						"WRN 0122: "
2434						"Error encountered getting port info for LID:0x%04X Num:0x%02X (%s)\n",
2435						p_node_rec->lid, port_num,
2436						ib_get_err_str(status));
2437					goto Exit;
2438				} else {
2439					OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
2440						"WRN 0123: "
2441						"failed to get port info for LID:0x%04X Num:0x%02X (%s)\n",
2442						p_node_rec->lid, port_num,
2443						ib_get_err_str(status));
2444					status = IB_SUCCESS;
2445				}
2446			} else {
2447				/* OK we got something */
2448				p_rec =
2449				    osmv_get_query_portinfo_rec(context.result.
2450								p_result_madw,
2451								0);
2452				osmtest_write_port_info(p_osmt, fh, p_rec);
2453
2454				/* create a subnet object */
2455				p_port = port_new();
2456				CL_ASSERT(p_port != NULL);
2457
2458				/* copy the info to the subnet node object */
2459				p_port->rec = *p_rec;
2460
2461				cl_qmap_insert(&p_osmt->exp_subn.port_key_tbl,
2462					       port_gen_id(p_node_rec->lid,
2463							   port_num),
2464					       &p_port->map_item);
2465			}
2466
2467			if (context.result.p_result_madw != NULL) {
2468				osm_mad_pool_put(&p_osmt->mad_pool,
2469						 context.result.p_result_madw);
2470				context.result.p_result_madw = NULL;
2471			}
2472		}
2473		p_node = (node_t *) cl_qmap_next(&p_node->map_item);
2474	}
2475
2476	/* we must set the exist status to avoid abort of the over all algorith */
2477
2478Exit:
2479	/*
2480	 * Return the IB query MAD to the pool as necessary.
2481	 */
2482
2483	if (context.result.p_result_madw != NULL) {
2484		osm_mad_pool_put(&p_osmt->mad_pool,
2485				 context.result.p_result_madw);
2486		context.result.p_result_madw = NULL;
2487	}
2488
2489	OSM_LOG_EXIT(&p_osmt->log);
2490	return (status);
2491}
2492
2493/**********************************************************************
2494 * ASSUMES NO RMPP
2495 **********************************************************************/
2496static ib_api_status_t
2497osmtest_write_all_path_recs(IN osmtest_t * const p_osmt, IN FILE * fh)
2498{
2499	osmtest_req_context_t context;
2500	const ib_path_rec_t *p_rec;
2501	cl_status_t status = CL_SUCCESS;
2502	int num_recs, i;
2503	cl_qmap_t *p_tbl;
2504	node_t *p_src_node, *p_dst_node;
2505	ib_api_status_t got_status = IB_SUCCESS;
2506
2507	OSM_LOG_ENTER(&p_osmt->log);
2508
2509	memset(&context, 0, sizeof(context));
2510
2511	/*
2512	 * Go over all nodes that exist in the subnet
2513	 * for each pair that are not switch nodes get the path record
2514	 */
2515
2516	context.p_osmt = p_osmt;
2517
2518	p_tbl = &p_osmt->exp_subn.node_lid_tbl;
2519
2520	p_src_node = (node_t *) cl_qmap_head(p_tbl);
2521
2522	while (p_src_node != (node_t *) cl_qmap_end(p_tbl)) {
2523		/* HACK we use capability_mask to know diff a CA node from switch node */
2524		/* if(p_src_node->rec.node_info.capability_mask  ) { */
2525		p_dst_node = (node_t *) cl_qmap_head(p_tbl);
2526
2527		while (p_dst_node != (node_t *) cl_qmap_end(p_tbl)) {
2528			/* HACK we use capability_mask to know diff a CA node from switch node */
2529			/* if (p_dst_node->rec.node_info.capability_mask) { */
2530
2531			/* query for it: */
2532			status = osmtest_get_path_rec_by_lid_pair(p_osmt,
2533								  p_src_node->
2534								  rec.lid,
2535								  p_dst_node->
2536								  rec.lid,
2537								  &context);
2538
2539			if (status != IB_SUCCESS) {
2540				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 012D: "
2541					"failed to get path info from LID:0x%X To LID:0x%X (%s)\n",
2542					p_src_node->rec.lid,
2543					p_dst_node->rec.lid,
2544					ib_get_err_str(status));
2545				/* remember the first error status */
2546				got_status =
2547				    (got_status ==
2548				     IB_SUCCESS) ? status : got_status;
2549			} else {
2550				/* we might have received several records */
2551				num_recs = context.result.result_cnt;
2552				for (i = 0; i < num_recs; i++) {
2553					p_rec =
2554					    osmv_get_query_path_rec(context.
2555								    result.
2556								    p_result_madw,
2557								    i);
2558					osmtest_write_path_info(p_osmt, fh,
2559								p_rec);
2560				}
2561			}
2562/*  } */
2563
2564			if (context.result.p_result_madw != NULL) {
2565				osm_mad_pool_put(&p_osmt->mad_pool,
2566						 context.result.p_result_madw);
2567				context.result.p_result_madw = NULL;
2568			}
2569
2570			/* next one please */
2571			p_dst_node =
2572			    (node_t *) cl_qmap_next(&p_dst_node->map_item);
2573		}
2574/* } */
2575
2576		p_src_node = (node_t *) cl_qmap_next(&p_src_node->map_item);
2577	}
2578
2579	if (got_status != IB_SUCCESS)
2580		status = got_status;
2581
2582	/*
2583	 * Return the IB query MAD to the pool as necessary.
2584	 */
2585	if (context.result.p_result_madw != NULL) {
2586		osm_mad_pool_put(&p_osmt->mad_pool,
2587				 context.result.p_result_madw);
2588		context.result.p_result_madw = NULL;
2589	}
2590
2591	OSM_LOG_EXIT(&p_osmt->log);
2592	return (status);
2593}
2594
2595#endif
2596
2597/**********************************************************************
2598 **********************************************************************/
2599static ib_api_status_t
2600osmtest_create_inventory_file(IN osmtest_t * const p_osmt)
2601{
2602	FILE *fh;
2603	ib_api_status_t status = IB_SUCCESS;
2604
2605	OSM_LOG_ENTER(&p_osmt->log);
2606
2607	fh = fopen(p_osmt->opt.file_name, "w");
2608	if (fh == NULL) {
2609		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0079: "
2610			"Unable to open inventory file (%s)\n",
2611			p_osmt->opt.file_name);
2612		status = IB_ERROR;
2613		goto Exit;
2614	}
2615
2616	/* HACK: the order is important: nodes ports paths */
2617	status = osmtest_write_all_node_recs(p_osmt, fh);
2618	if (status != IB_SUCCESS)
2619		goto Exit;
2620
2621	status = osmtest_write_all_port_recs(p_osmt, fh);
2622	if (status != IB_SUCCESS)
2623		goto Exit;
2624
2625	if (!p_osmt->opt.ignore_path_records) {
2626		status = osmtest_write_all_path_recs(p_osmt, fh);
2627		if (status != IB_SUCCESS)
2628			goto Exit;
2629	}
2630
2631	status = osmtest_write_all_link_recs(p_osmt, fh);
2632	if (status != IB_SUCCESS)
2633		goto Exit;
2634
2635	fclose(fh);
2636
2637Exit:
2638	OSM_LOG_EXIT(&p_osmt->log);
2639	return (status);
2640}
2641
2642/**********************************************************************
2643 **********************************************************************/
2644static ib_api_status_t osmtest_stress_large_rmpp_pr(IN osmtest_t * const p_osmt)
2645{
2646	ib_api_status_t status = IB_SUCCESS;
2647	uint64_t num_recs = 0;
2648	uint64_t num_queries = 0;
2649	uint32_t delta_recs;
2650	uint32_t delta_queries;
2651	uint32_t print_freq = 0;
2652	struct timeval start_tv, end_tv;
2653	long sec_diff, usec_diff;
2654	float ratio;
2655
2656	OSM_LOG_ENTER(&p_osmt->log);
2657	gettimeofday(&start_tv, NULL);
2658	printf("-I- Start time is : %09ld:%06ld [sec:usec]\n", (long)start_tv.tv_sec,
2659	       (long)start_tv.tv_usec);
2660
2661	while (num_queries < STRESS_LARGE_PR_RMPP_THR) {
2662		delta_recs = 0;
2663		delta_queries = 0;
2664
2665		status = osmtest_stress_path_recs_by_guid(p_osmt, &delta_recs,
2666							  &delta_queries);
2667		if (status != IB_SUCCESS)
2668			goto Exit;
2669
2670		num_recs += delta_recs;
2671		num_queries += delta_queries;
2672
2673		print_freq += delta_recs;
2674		if (print_freq > 10000) {
2675			gettimeofday(&end_tv, NULL);
2676			if (end_tv.tv_usec > start_tv.tv_usec) {
2677				sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2678				usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2679			} else {
2680				sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2681				usec_diff =
2682				    1000000 - (start_tv.tv_usec -
2683					       end_tv.tv_usec);
2684			}
2685			printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2686			       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2687			printf("-I- Querying %" PRId64
2688			       " Path Record queries CA to CA (rmpp)\n\ttook %04ld:%06ld [sec:usec]\n",
2689			       num_queries, sec_diff, usec_diff);
2690			if (num_recs == 0)
2691				ratio = 0;
2692			else
2693				ratio = ((float)num_queries / (float)num_recs);
2694			printf("-I- Queries to Record Ratio is %" PRIu64
2695			       " records, %" PRIu64 " queries : %.2f \n",
2696			       num_recs, num_queries, ratio);
2697			print_freq = 0;
2698		}
2699	}
2700
2701Exit:
2702	gettimeofday(&end_tv, NULL);
2703	printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2704	       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2705	if (end_tv.tv_usec > start_tv.tv_usec) {
2706		sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2707		usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2708	} else {
2709		sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2710		usec_diff = 1000000 - (start_tv.tv_usec - end_tv.tv_usec);
2711	}
2712
2713	printf("-I- Querying %" PRId64
2714	       " Path Record queries (rmpp) took %04ld:%06ld [sec:usec]\n",
2715	       num_queries, sec_diff, usec_diff);
2716
2717	OSM_LOG_EXIT(&p_osmt->log);
2718	return (status);
2719}
2720
2721/**********************************************************************
2722 **********************************************************************/
2723static ib_api_status_t osmtest_stress_large_rmpp(IN osmtest_t * const p_osmt)
2724{
2725	ib_api_status_t status = IB_SUCCESS;
2726	uint64_t num_recs = 0;
2727	uint64_t num_queries = 0;
2728	uint32_t delta_recs;
2729	uint32_t delta_queries;
2730	uint32_t print_freq = 0;
2731	struct timeval start_tv, end_tv;
2732	long sec_diff, usec_diff;
2733
2734	OSM_LOG_ENTER(&p_osmt->log);
2735	gettimeofday(&start_tv, NULL);
2736	printf("-I- Start time is : %09ld:%06ld [sec:usec]\n", (long)start_tv.tv_sec,
2737	       (long)start_tv.tv_usec);
2738
2739	while (num_queries < STRESS_LARGE_RMPP_THR) {
2740		delta_recs = 0;
2741		delta_queries = 0;
2742
2743		status = osmtest_stress_node_recs_large(p_osmt, &delta_recs,
2744							&delta_queries);
2745		if (status != IB_SUCCESS)
2746			goto Exit;
2747
2748		status = osmtest_stress_path_recs_large(p_osmt, &delta_recs,
2749							&delta_queries);
2750		if (status != IB_SUCCESS)
2751			goto Exit;
2752
2753		status = osmtest_stress_port_recs_large(p_osmt, &delta_recs,
2754							&delta_queries);
2755		if (status != IB_SUCCESS)
2756			goto Exit;
2757
2758		num_recs += delta_recs;
2759		num_queries += delta_queries;
2760
2761		print_freq += delta_recs;
2762
2763		if (print_freq > 100000) {
2764			gettimeofday(&end_tv, NULL);
2765			if (end_tv.tv_usec > start_tv.tv_usec) {
2766				sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2767				usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2768			} else {
2769				sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2770				usec_diff =
2771				    1000000 - (start_tv.tv_usec -
2772					       end_tv.tv_usec);
2773			}
2774			printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2775			       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2776			printf("-I- Querying %" PRId64
2777			       " large mixed queries (rmpp) took %04ld:%06ld [sec:usec]\n",
2778			       num_queries, sec_diff, usec_diff);
2779			printf("%" PRIu64 " records, %" PRIu64 " queries\n",
2780			       num_recs, num_queries);
2781			print_freq = 0;
2782		}
2783	}
2784
2785Exit:
2786	gettimeofday(&end_tv, NULL);
2787	printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2788	       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2789	if (end_tv.tv_usec > start_tv.tv_usec) {
2790		sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2791		usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2792	} else {
2793		sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2794		usec_diff = 1000000 - (start_tv.tv_usec - end_tv.tv_usec);
2795	}
2796
2797	printf("-I- Querying %" PRId64
2798	       " large mixed queries (rmpp) took %04ld:%06ld [sec:usec]\n",
2799	       num_queries, sec_diff, usec_diff);
2800
2801	OSM_LOG_EXIT(&p_osmt->log);
2802	return (status);
2803}
2804
2805/**********************************************************************
2806 **********************************************************************/
2807static ib_api_status_t osmtest_stress_small_rmpp(IN osmtest_t * const p_osmt)
2808{
2809	ib_api_status_t status = IB_SUCCESS;
2810	uint64_t num_recs = 0;
2811	uint64_t num_queries = 0;
2812	uint32_t delta_recs;
2813	uint32_t delta_queries;
2814	uint32_t print_freq = 0;
2815	int num_timeouts = 0;
2816	struct timeval start_tv, end_tv;
2817	long sec_diff, usec_diff;
2818
2819	OSM_LOG_ENTER(&p_osmt->log);
2820	gettimeofday(&start_tv, NULL);
2821	printf("-I- Start time is : %09ld:%06ld [sec:usec]\n",
2822	       (long)start_tv.tv_sec, (long)start_tv.tv_usec);
2823
2824	while ((num_queries < STRESS_SMALL_RMPP_THR) && (num_timeouts < 100)) {
2825		delta_recs = 0;
2826		delta_queries = 0;
2827
2828		status = osmtest_stress_port_recs_small(p_osmt, &delta_recs,
2829							&delta_queries);
2830		if (status != IB_SUCCESS)
2831			goto Exit;
2832
2833		num_recs += delta_recs;
2834		num_queries += delta_queries;
2835
2836		print_freq += delta_recs;
2837		if (print_freq > 5000) {
2838			gettimeofday(&end_tv, NULL);
2839			printf("%" PRIu64 " records, %" PRIu64 " queries\n",
2840			       num_recs, num_queries);
2841			if (end_tv.tv_usec > start_tv.tv_usec) {
2842				sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2843				usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2844			} else {
2845				sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2846				usec_diff =
2847				    1000000 - (start_tv.tv_usec -
2848					       end_tv.tv_usec);
2849			}
2850			printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2851			       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2852			printf("-I- Querying %" PRId64
2853			       " port_info queries (single mad) took %04ld:%06ld [sec:usec]\n",
2854			       num_queries, sec_diff, usec_diff);
2855			print_freq = 0;
2856		}
2857	}
2858
2859Exit:
2860	gettimeofday(&end_tv, NULL);
2861	printf("-I- End time is : %09ld:%06ld [sec:usec]\n",
2862	       (long)end_tv.tv_sec, (long)end_tv.tv_usec);
2863	if (end_tv.tv_usec > start_tv.tv_usec) {
2864		sec_diff = end_tv.tv_sec - start_tv.tv_sec;
2865		usec_diff = end_tv.tv_usec - start_tv.tv_usec;
2866	} else {
2867		sec_diff = end_tv.tv_sec - start_tv.tv_sec - 1;
2868		usec_diff = 1000000 - (start_tv.tv_usec - end_tv.tv_usec);
2869	}
2870
2871	printf("-I- Querying %" PRId64
2872	       " port_info queries (single mad) took %04ld:%06ld [sec:usec]\n",
2873	       num_queries, sec_diff, usec_diff);
2874	if (num_timeouts > 50) {
2875		status = IB_TIMEOUT;
2876	}
2877	/* Exit: */
2878	OSM_LOG_EXIT(&p_osmt->log);
2879	return (status);
2880}
2881
2882/**********************************************************************
2883 **********************************************************************/
2884static void
2885osmtest_prepare_db_generic(IN osmtest_t * const p_osmt,
2886			   IN cl_qmap_t * const p_tbl)
2887{
2888	generic_t *p_generic;
2889
2890	OSM_LOG_ENTER(&p_osmt->log);
2891
2892	p_generic = (generic_t *) cl_qmap_head(p_tbl);
2893
2894	while (p_generic != (generic_t *) cl_qmap_end(p_tbl)) {
2895		p_generic->count = 0;
2896		p_generic = (generic_t *) cl_qmap_next(&p_generic->map_item);
2897	}
2898
2899	OSM_LOG_EXIT(&p_osmt->log);
2900}
2901
2902/**********************************************************************
2903 **********************************************************************/
2904static void osmtest_prepare_db(IN osmtest_t * const p_osmt)
2905{
2906	OSM_LOG_ENTER(&p_osmt->log);
2907
2908	osmtest_prepare_db_generic(p_osmt, &p_osmt->exp_subn.node_lid_tbl);
2909	osmtest_prepare_db_generic(p_osmt, &p_osmt->exp_subn.path_tbl);
2910
2911	OSM_LOG_EXIT(&p_osmt->log);
2912}
2913
2914/**********************************************************************
2915 **********************************************************************/
2916static ib_api_status_t osmtest_check_missing_nodes(IN osmtest_t * const p_osmt)
2917{
2918	const node_t *p_node;
2919	cl_status_t status = IB_SUCCESS;
2920	cl_qmap_t *p_tbl;
2921
2922	OSM_LOG_ENTER(&p_osmt->log);
2923
2924	p_tbl = &p_osmt->exp_subn.node_lid_tbl;
2925
2926	p_node = (node_t *) cl_qmap_head(p_tbl);
2927
2928	while (p_node != (node_t *) cl_qmap_end(p_tbl)) {
2929		if (p_node->count == 0) {
2930			/*
2931			 * This node was not reported by the SA
2932			 */
2933			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0080: "
2934				"Missing node 0x%016" PRIx64 "\n",
2935				cl_ntoh64(p_node->rec.node_info.node_guid));
2936			status = IB_ERROR;
2937		}
2938
2939		p_node = (node_t *) cl_qmap_next(&p_node->map_item);
2940	}
2941
2942	OSM_LOG_EXIT(&p_osmt->log);
2943	return (status);
2944}
2945
2946/**********************************************************************
2947 **********************************************************************/
2948static ib_api_status_t osmtest_check_missing_ports(IN osmtest_t * const p_osmt)
2949{
2950	const port_t *p_port;
2951	cl_status_t status = IB_SUCCESS;
2952	cl_qmap_t *p_tbl;
2953
2954	OSM_LOG_ENTER(&p_osmt->log);
2955
2956	p_tbl = &p_osmt->exp_subn.port_key_tbl;
2957
2958	p_port = (port_t *) cl_qmap_head(p_tbl);
2959
2960	while (p_port != (port_t *) cl_qmap_end(p_tbl)) {
2961		if (p_port->count == 0) {
2962			/*
2963			 * This port was not reported by the SA
2964			 */
2965			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0081: "
2966				"Missing port LID:0x%X Num:0x%X\n",
2967				cl_ntoh16(p_port->rec.lid),
2968				p_port->rec.port_num);
2969			status = IB_ERROR;
2970		}
2971
2972		p_port = (port_t *) cl_qmap_next(&p_port->map_item);
2973	}
2974
2975	OSM_LOG_EXIT(&p_osmt->log);
2976	return (status);
2977}
2978
2979/**********************************************************************
2980 **********************************************************************/
2981static ib_api_status_t osmtest_check_missing_paths(IN osmtest_t * const p_osmt)
2982{
2983	const path_t *p_path;
2984	cl_status_t status = IB_SUCCESS;
2985	cl_qmap_t *p_tbl;
2986
2987	OSM_LOG_ENTER(&p_osmt->log);
2988
2989	p_tbl = &p_osmt->exp_subn.path_tbl;
2990
2991	p_path = (path_t *) cl_qmap_head(p_tbl);
2992
2993	while (p_path != (path_t *) cl_qmap_end(p_tbl)) {
2994		if (p_path->count == 0) {
2995			/*
2996			 * This path was not reported by the SA
2997			 */
2998			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0051: "
2999				"SA did not return path SLID 0x%X to DLID 0x%X\n",
3000				cl_ntoh16(p_path->rec.slid),
3001				cl_ntoh16(p_path->rec.dlid));
3002			status = IB_ERROR;
3003			goto Exit;
3004		}
3005
3006		p_path = (path_t *) cl_qmap_next(&p_path->map_item);
3007	}
3008
3009Exit:
3010	OSM_LOG_EXIT(&p_osmt->log);
3011	return (status);
3012}
3013
3014/**********************************************************************
3015 **********************************************************************/
3016static inline uint32_t osmtest_path_rec_key_get(IN const ib_path_rec_t * const p_rec)
3017{
3018	return (p_rec->dlid << 16 | p_rec->slid);
3019}
3020
3021/**********************************************************************
3022 **********************************************************************/
3023static boolean_t
3024osmtest_path_rec_kay_is_valid(IN osmtest_t * const p_osmt,
3025			      IN const path_t * const p_path)
3026{
3027	if ((p_path->comp.dlid == 0) || (p_path->comp.slid == 0)) {
3028		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0168: "
3029			"SLID and DLID must be specified for defined paths\n");
3030		return (FALSE);
3031	}
3032
3033	return (TRUE);
3034}
3035
3036/**********************************************************************
3037 **********************************************************************/
3038static ib_api_status_t
3039osmtest_validate_path_data(IN osmtest_t * const p_osmt,
3040			   IN path_t * const p_path,
3041			   IN const ib_path_rec_t * const p_rec)
3042{
3043	cl_status_t status = IB_SUCCESS;
3044	uint8_t lmc = 0;
3045
3046	OSM_LOG_ENTER(&p_osmt->log);
3047
3048	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
3049		"Checking path SLID 0x%X to DLID 0x%X\n",
3050		cl_ntoh16(p_rec->slid), cl_ntoh16(p_rec->dlid));
3051
3052	status =
3053	    osmtest_get_local_port_lmc(p_osmt, p_osmt->local_port.lid, &lmc);
3054	if (status != IB_SUCCESS)
3055		goto Exit;
3056
3057	/* HACK: Assume uniform LMC across endports in the subnet */
3058	/* This is the only LMC mode which OpenSM currently supports */
3059	/* In absence of this assumption, validation of this is much more complicated */
3060	if (lmc == 0) {
3061		/*
3062		 * Has this record already been returned?
3063		 */
3064		if (p_path->count != 0) {
3065			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0056: "
3066				"Already received path SLID 0x%X to DLID 0x%X\n",
3067				cl_ntoh16(p_rec->slid), cl_ntoh16(p_rec->dlid));
3068			status = IB_ERROR;
3069			goto Exit;
3070		}
3071	} else {
3072		/* Also, this doesn't detect fewer than the correct number of paths being returned */
3073		if (p_path->count >= (uint32_t) (1 << (2 * lmc))) {
3074			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0052: "
3075				"Already received path SLID 0x%X to DLID 0x%X count %d LMC %d\n",
3076				cl_ntoh16(p_rec->slid), cl_ntoh16(p_rec->dlid),
3077				p_path->count, lmc);
3078			status = IB_ERROR;
3079			goto Exit;
3080		}
3081	}
3082
3083	++p_path->count;
3084
3085	/*
3086	 * Check the fields the user wants checked.
3087	 */
3088	if ((p_path->comp.dgid.unicast.interface_id &
3089	     p_path->rec.dgid.unicast.interface_id) !=
3090	    (p_path->comp.dgid.unicast.interface_id &
3091	     p_rec->dgid.unicast.interface_id)) {
3092		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0169: "
3093			"DGID mismatch on path SLID 0x%X to DLID 0x%X\n"
3094			"\t\t\t\tExpected 0x%016" PRIx64 " 0x%016" PRIx64 "\n"
3095			"\t\t\t\tReceived 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
3096			cl_ntoh16(p_path->rec.slid),
3097			cl_ntoh16(p_path->rec.dlid),
3098			cl_ntoh64(p_path->rec.dgid.unicast.prefix),
3099			cl_ntoh64(p_path->rec.dgid.unicast.interface_id),
3100			cl_ntoh64(p_rec->dgid.unicast.prefix),
3101			cl_ntoh64(p_rec->dgid.unicast.interface_id));
3102		status = IB_ERROR;
3103		goto Exit;
3104	}
3105
3106	/*
3107	 * Check the fields the user wants checked.
3108	 */
3109	if ((p_path->comp.sgid.unicast.interface_id &
3110	     p_path->rec.sgid.unicast.interface_id) !=
3111	    (p_path->comp.sgid.unicast.interface_id &
3112	     p_rec->sgid.unicast.interface_id)) {
3113		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0057: "
3114			"SGID mismatch on path SLID 0x%X to DLID 0x%X\n"
3115			"\t\t\t\tExpected 0x%016" PRIx64 " 0x%016" PRIx64 ",\n"
3116			"\t\t\t\tReceived 0x%016" PRIx64 " 0x%016" PRIx64 ".\n",
3117			cl_ntoh16(p_path->rec.slid),
3118			cl_ntoh16(p_path->rec.dlid),
3119			cl_ntoh64(p_path->rec.sgid.unicast.prefix),
3120			cl_ntoh64(p_path->rec.sgid.unicast.interface_id),
3121			cl_ntoh64(p_rec->sgid.unicast.prefix),
3122			cl_ntoh64(p_rec->sgid.unicast.interface_id));
3123		status = IB_ERROR;
3124		goto Exit;
3125	}
3126
3127	/*
3128	 * Compare the fields the user wishes to validate.
3129	 */
3130	if ((p_path->comp.pkey & p_path->rec.pkey) !=
3131	    (p_path->comp.pkey & p_rec->pkey)) {
3132		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0012: "
3133			"PKEY mismatch on path SLID 0x%X to DLID 0x%X\n"
3134			"\t\t\t\tExpected 0x%X, received 0x%X\n",
3135			cl_ntoh16(p_path->rec.slid),
3136			cl_ntoh16(p_path->rec.dlid),
3137			cl_ntoh16(p_path->rec.pkey), cl_ntoh16(p_rec->pkey));
3138		status = IB_ERROR;
3139		goto Exit;
3140	}
3141
3142Exit:
3143	OSM_LOG_EXIT(&p_osmt->log);
3144	return (status);
3145}
3146
3147/**********************************************************************
3148 **********************************************************************/
3149static ib_api_status_t
3150osmtest_validate_node_data(IN osmtest_t * const p_osmt,
3151			   IN node_t * const p_node,
3152			   IN const ib_node_record_t * const p_rec)
3153{
3154	cl_status_t status = IB_SUCCESS;
3155
3156	OSM_LOG_ENTER(&p_osmt->log);
3157
3158	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
3159		"Checking node 0x%016" PRIx64 ", LID 0x%X\n",
3160		cl_ntoh64(p_rec->node_info.node_guid), cl_ntoh16(p_rec->lid));
3161
3162	/*
3163	 * Has this record already been returned?
3164	 */
3165	if (p_node->count != 0) {
3166		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0013: "
3167			"Already received node 0x%016" PRIx64 "\n",
3168			cl_ntoh64(p_node->rec.node_info.node_guid));
3169		status = IB_ERROR;
3170		goto Exit;
3171	}
3172
3173	++p_node->count;
3174
3175	/*
3176	 * Compare the fields the user wishes to validate.
3177	 */
3178	if ((p_node->comp.lid & p_node->rec.lid) !=
3179	    (p_node->comp.lid & p_rec->lid)) {
3180		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0014: "
3181			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3182			"\t\t\t\tExpected LID 0x%X, received 0x%X\n",
3183			cl_ntoh64(p_rec->node_info.node_guid),
3184			cl_ntoh16(p_rec->lid), p_node->rec.lid, p_rec->lid);
3185		status = IB_ERROR;
3186		goto Exit;
3187	}
3188
3189	if ((p_node->comp.node_info.base_version &
3190	     p_node->rec.node_info.base_version) !=
3191	    (p_node->comp.node_info.base_version &
3192	     p_rec->node_info.base_version)) {
3193		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0015: "
3194			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3195			"\t\t\t\tExpected base_version 0x%X, received 0x%X\n",
3196			cl_ntoh64(p_rec->node_info.node_guid),
3197			cl_ntoh16(p_rec->lid),
3198			p_node->rec.node_info.base_version,
3199			p_rec->node_info.base_version);
3200		status = IB_ERROR;
3201		goto Exit;
3202	}
3203
3204	if ((p_node->comp.node_info.class_version &
3205	     p_node->rec.node_info.class_version) !=
3206	    (p_node->comp.node_info.class_version &
3207	     p_rec->node_info.class_version)) {
3208		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0016: "
3209			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3210			"\t\t\t\tExpected class_version 0x%X, received 0x%X\n",
3211			cl_ntoh64(p_rec->node_info.node_guid),
3212			cl_ntoh16(p_rec->lid),
3213			p_node->rec.node_info.class_version,
3214			p_rec->node_info.class_version);
3215		status = IB_ERROR;
3216		goto Exit;
3217	}
3218
3219	if ((p_node->comp.node_info.node_type &
3220	     p_node->rec.node_info.node_type) !=
3221	    (p_node->comp.node_info.node_type & p_rec->node_info.node_type)) {
3222		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0017: "
3223			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3224			"\t\t\t\tExpected node_type 0x%X, received 0x%X\n",
3225			cl_ntoh64(p_rec->node_info.node_guid),
3226			cl_ntoh16(p_rec->lid),
3227			p_node->rec.node_info.node_type,
3228			p_rec->node_info.node_type);
3229		status = IB_ERROR;
3230		goto Exit;
3231	}
3232
3233	if ((p_node->comp.node_info.sys_guid &
3234	     p_node->rec.node_info.sys_guid) !=
3235	    (p_node->comp.node_info.sys_guid & p_rec->node_info.sys_guid)) {
3236		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0018: "
3237			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3238			"\t\t\t\tExpected sys_guid 0x%016" PRIx64
3239			", received 0x%016" PRIx64 "\n",
3240			cl_ntoh64(p_rec->node_info.node_guid),
3241			cl_ntoh16(p_rec->lid),
3242			cl_ntoh64(p_node->rec.node_info.sys_guid),
3243			cl_ntoh64(p_rec->node_info.sys_guid));
3244		status = IB_ERROR;
3245		goto Exit;
3246	}
3247
3248	if ((p_node->comp.node_info.node_guid &
3249	     p_node->rec.node_info.node_guid) !=
3250	    (p_node->comp.node_info.node_guid & p_rec->node_info.node_guid)) {
3251		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0019: "
3252			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3253			"\t\t\t\tExpected node_guid 0x%016" PRIx64
3254			", received 0x%016" PRIx64 "\n",
3255			cl_ntoh64(p_rec->node_info.node_guid),
3256			cl_ntoh16(p_rec->lid),
3257			cl_ntoh64(p_node->rec.node_info.node_guid),
3258			cl_ntoh64(p_rec->node_info.node_guid));
3259		status = IB_ERROR;
3260		goto Exit;
3261	}
3262
3263	if ((p_node->comp.node_info.port_guid &
3264	     p_node->rec.node_info.port_guid) !=
3265	    (p_node->comp.node_info.port_guid & p_rec->node_info.port_guid)) {
3266		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0031: "
3267			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3268			"\t\t\t\tExpected port_guid 0x%016" PRIx64
3269			", received 0x%016" PRIx64 "\n",
3270			cl_ntoh64(p_rec->node_info.node_guid),
3271			cl_ntoh16(p_rec->lid),
3272			cl_ntoh64(p_node->rec.node_info.port_guid),
3273			cl_ntoh64(p_rec->node_info.port_guid));
3274		status = IB_ERROR;
3275		goto Exit;
3276	}
3277
3278	if ((p_node->comp.node_info.partition_cap &
3279	     p_node->rec.node_info.partition_cap) !=
3280	    (p_node->comp.node_info.partition_cap &
3281	     p_rec->node_info.partition_cap)) {
3282		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0032: "
3283			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3284			"\t\t\t\tExpected partition_cap 0x%X, received 0x%X\n",
3285			cl_ntoh64(p_rec->node_info.node_guid),
3286			cl_ntoh16(p_rec->lid),
3287			cl_ntoh16(p_node->rec.node_info.partition_cap),
3288			cl_ntoh16(p_rec->node_info.partition_cap));
3289		status = IB_ERROR;
3290		goto Exit;
3291	}
3292
3293	if ((p_node->comp.node_info.device_id &
3294	     p_node->rec.node_info.device_id) !=
3295	    (p_node->comp.node_info.device_id & p_rec->node_info.device_id)) {
3296		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0033: "
3297			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3298			"\t\t\t\tExpected device_id 0x%X, received 0x%X\n",
3299			cl_ntoh64(p_rec->node_info.node_guid),
3300			cl_ntoh16(p_rec->lid),
3301			cl_ntoh16(p_node->rec.node_info.device_id),
3302			cl_ntoh16(p_rec->node_info.device_id));
3303		status = IB_ERROR;
3304		goto Exit;
3305	}
3306
3307	if ((p_node->comp.node_info.revision &
3308	     p_node->rec.node_info.revision) !=
3309	    (p_node->comp.node_info.revision & p_rec->node_info.revision)) {
3310		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0034: "
3311			"Field mismatch node 0x%016" PRIx64 ", LID 0x%X\n"
3312			"\t\t\t\tExpected revision 0x%X, received 0x%X\n",
3313			cl_ntoh64(p_rec->node_info.node_guid),
3314			cl_ntoh16(p_rec->lid),
3315			cl_ntoh32(p_node->rec.node_info.revision),
3316			cl_ntoh32(p_rec->node_info.revision));
3317		status = IB_ERROR;
3318		goto Exit;
3319	}
3320
3321Exit:
3322	OSM_LOG_EXIT(&p_osmt->log);
3323	return (status);
3324}
3325
3326/**********************************************************************
3327 **********************************************************************/
3328static ib_api_status_t
3329osmtest_validate_node_rec(IN osmtest_t * const p_osmt,
3330			  IN const ib_node_record_t * const p_rec)
3331{
3332	cl_status_t status = IB_SUCCESS;
3333	node_t *p_node;
3334	const cl_qmap_t *p_tbl;
3335
3336	OSM_LOG_ENTER(&p_osmt->log);
3337
3338	/*
3339	 * Find proper node record in the database.
3340	 */
3341	p_tbl = &p_osmt->exp_subn.node_lid_tbl;
3342	p_node = (node_t *) cl_qmap_get(p_tbl, p_rec->lid);
3343	if (p_node == (node_t *) cl_qmap_end(p_tbl)) {
3344		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0035: "
3345			"Unexpected node 0x%016" PRIx64 ", LID 0x%X\n",
3346			cl_ntoh64(p_rec->node_info.node_guid),
3347			cl_ntoh16(p_rec->lid));
3348		status = IB_ERROR;
3349		goto Exit;
3350	}
3351
3352	status = osmtest_validate_node_data(p_osmt, p_node, p_rec);
3353
3354Exit:
3355	OSM_LOG_EXIT(&p_osmt->log);
3356	return (status);
3357}
3358
3359/**********************************************************************
3360 **********************************************************************/
3361static ib_api_status_t
3362osmtest_validate_port_data(IN osmtest_t * const p_osmt,
3363			   IN port_t * const p_port,
3364			   IN const ib_portinfo_record_t * const p_rec)
3365{
3366	cl_status_t status = IB_SUCCESS;
3367
3368	OSM_LOG_ENTER(&p_osmt->log);
3369
3370	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
3371		"Checking port LID 0x%X, Num 0x%X\n",
3372		cl_ntoh16(p_rec->lid), p_rec->port_num);
3373
3374	/*
3375	 * Has this record already been returned?
3376	 */
3377	if (p_port->count != 0) {
3378		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0036: "
3379			"Already received port LID 0x%X, Num 0x%X\n",
3380			cl_ntoh16(p_rec->lid), p_rec->port_num);
3381		status = IB_ERROR;
3382		goto Exit;
3383	}
3384
3385	++p_port->count;
3386
3387	/*
3388	 * Compare the fields the user wishes to validate.
3389	 */
3390	if ((p_port->comp.lid & p_port->rec.lid) !=
3391	    (p_port->comp.lid & p_rec->lid)) {
3392		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0037: "
3393			"Field mismatch port LID 0x%X Num:0x%X\n"
3394			"\t\t\t\tExpected LID 0x%X, received 0x%X\n",
3395			cl_ntoh16(p_rec->lid), p_rec->port_num,
3396			p_port->rec.lid, p_rec->lid);
3397		status = IB_ERROR;
3398		goto Exit;
3399	}
3400
3401	if ((p_port->comp.port_num & p_port->rec.port_num) !=
3402	    (p_port->comp.port_num & p_rec->port_num)) {
3403		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0038: "
3404			"Field mismatch port LID 0x%X Num:0x%X\n"
3405			"\t\t\t\tExpected port_num 0x%X, received 0x%X\n",
3406			cl_ntoh16(p_rec->lid), p_rec->port_num,
3407			p_port->rec.port_num, p_rec->port_num);
3408		status = IB_ERROR;
3409		goto Exit;
3410	}
3411
3412	if ((p_port->comp.port_info.m_key & p_port->rec.port_info.m_key) !=
3413	    (p_port->comp.port_info.m_key & p_rec->port_info.m_key)) {
3414		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0039: "
3415			"Field mismatch port LID 0x%X Num:0x%X\n"
3416			"\t\t\t\tExpected m_key 0x%016" PRIx64
3417			", received 0x%016" PRIx64 "\n", cl_ntoh16(p_rec->lid),
3418			p_rec->port_num, p_port->rec.port_info.m_key,
3419			p_rec->port_info.m_key);
3420		status = IB_ERROR;
3421		goto Exit;
3422	}
3423
3424	if ((p_port->comp.port_info.subnet_prefix & p_port->rec.port_info.
3425	     subnet_prefix) !=
3426	    (p_port->comp.port_info.subnet_prefix & p_rec->port_info.
3427	     subnet_prefix)) {
3428		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0040: "
3429			"Field mismatch port LID 0x%X Num:0x%X\n"
3430			"\t\t\t\tExpected subnet_prefix 0x%016" PRIx64
3431			", received 0x%016" PRIx64 "\n", cl_ntoh16(p_rec->lid),
3432			p_rec->port_num, p_port->rec.port_info.subnet_prefix,
3433			p_rec->port_info.subnet_prefix);
3434		status = IB_ERROR;
3435		goto Exit;
3436	}
3437
3438	if ((p_port->comp.port_info.base_lid & p_port->rec.port_info.
3439	     base_lid) !=
3440	    (p_port->comp.port_info.base_lid & p_rec->port_info.base_lid)) {
3441		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0041: "
3442			"Field mismatch port LID 0x%X Num:0x%X\n"
3443			"\t\t\t\tExpected base_lid 0x%X, received 0x%X\n",
3444			cl_ntoh16(p_rec->lid), p_rec->port_num,
3445			p_port->rec.port_info.base_lid,
3446			p_rec->port_info.base_lid);
3447		status = IB_ERROR;
3448		goto Exit;
3449	}
3450
3451	if ((p_port->comp.port_info.master_sm_base_lid & p_port->rec.port_info.
3452	     master_sm_base_lid) !=
3453	    (p_port->comp.port_info.master_sm_base_lid & p_rec->port_info.
3454	     master_sm_base_lid)) {
3455		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0042: "
3456			"Field mismatch port LID 0x%X Num:0x%X\n"
3457			"\t\t\t\tExpected master_sm_base_lid 0x%X, received 0x%X\n",
3458			cl_ntoh16(p_rec->lid), p_rec->port_num,
3459			p_port->rec.port_info.master_sm_base_lid,
3460			p_rec->port_info.master_sm_base_lid);
3461		status = IB_ERROR;
3462		goto Exit;
3463	}
3464
3465	if ((p_port->comp.port_info.capability_mask & p_port->rec.port_info.
3466	     capability_mask) !=
3467	    (p_port->comp.port_info.capability_mask & p_rec->port_info.
3468	     capability_mask)) {
3469		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0043: "
3470			"Field mismatch port LID 0x%X Num:0x%X\n"
3471			"\t\t\t\tExpected capability_mask 0x%X, received 0x%X\n",
3472			cl_ntoh16(p_rec->lid), p_rec->port_num,
3473			cl_ntoh32(p_port->rec.port_info.capability_mask),
3474			cl_ntoh32(p_rec->port_info.capability_mask));
3475		status = IB_ERROR;
3476		goto Exit;
3477	}
3478
3479	if ((p_port->comp.port_info.diag_code & p_port->rec.port_info.
3480	     diag_code) !=
3481	    (p_port->comp.port_info.diag_code & p_rec->port_info.diag_code)) {
3482		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0044: "
3483			"Field mismatch port LID 0x%X Num:0x%X\n"
3484			"\t\t\t\tExpected diag_code 0x%X, received 0x%X\n",
3485			cl_ntoh16(p_rec->lid), p_rec->port_num,
3486			p_port->rec.port_info.diag_code,
3487			p_rec->port_info.diag_code);
3488		status = IB_ERROR;
3489		goto Exit;
3490	}
3491
3492	if ((p_port->comp.port_info.m_key_lease_period & p_port->rec.port_info.
3493	     m_key_lease_period) !=
3494	    (p_port->comp.port_info.m_key_lease_period & p_rec->port_info.
3495	     m_key_lease_period)) {
3496		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0045: "
3497			"Field mismatch port LID 0x%X Num:0x%X\n"
3498			"\t\t\t\tExpected m_key_lease_period 0x%X, received 0x%X\n",
3499			cl_ntoh16(p_rec->lid), p_rec->port_num,
3500			p_port->rec.port_info.m_key_lease_period,
3501			p_rec->port_info.m_key_lease_period);
3502		status = IB_ERROR;
3503		goto Exit;
3504	}
3505
3506	if ((p_port->comp.port_info.local_port_num & p_port->rec.port_info.
3507	     local_port_num) !=
3508	    (p_port->comp.port_info.local_port_num & p_rec->port_info.
3509	     local_port_num)) {
3510		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0046: "
3511			"Field mismatch port LID 0x%X Num:0x%X\n"
3512			"\t\t\t\tExpected local_port_num 0x%X, received 0x%X\n",
3513			cl_ntoh16(p_rec->lid), p_rec->port_num,
3514			p_port->rec.port_info.local_port_num,
3515			p_rec->port_info.local_port_num);
3516		status = IB_ERROR;
3517		goto Exit;
3518	}
3519
3520	if ((p_port->comp.port_info.link_width_enabled & p_port->rec.port_info.
3521	     link_width_enabled) !=
3522	    (p_port->comp.port_info.link_width_enabled & p_rec->port_info.
3523	     link_width_enabled)) {
3524		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0047: "
3525			"Field mismatch port LID 0x%X Num:0x%X\n"
3526			"\t\t\t\tExpected link_width_enabled 0x%X, received 0x%X\n",
3527			cl_ntoh16(p_rec->lid), p_rec->port_num,
3528			p_port->rec.port_info.link_width_enabled,
3529			p_rec->port_info.link_width_enabled);
3530		status = IB_ERROR;
3531		goto Exit;
3532	}
3533
3534	if ((p_port->comp.port_info.link_width_supported & p_port->rec.
3535	     port_info.link_width_supported) !=
3536	    (p_port->comp.port_info.link_width_supported & p_rec->port_info.
3537	     link_width_supported)) {
3538		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0048: "
3539			"Field mismatch port LID 0x%X Num:0x%X\n"
3540			"\t\t\t\tExpected link_width_supported 0x%X, received 0x%X\n",
3541			cl_ntoh16(p_rec->lid), p_rec->port_num,
3542			p_port->rec.port_info.link_width_supported,
3543			p_rec->port_info.link_width_supported);
3544		status = IB_ERROR;
3545		goto Exit;
3546	}
3547
3548	if ((p_port->comp.port_info.link_width_active & p_port->rec.port_info.
3549	     link_width_active) !=
3550	    (p_port->comp.port_info.link_width_active & p_rec->port_info.
3551	     link_width_active)) {
3552		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0049: "
3553			"Field mismatch port LID 0x%X Num:0x%X\n"
3554			"\t\t\t\tExpected link_width_active 0x%X, received 0x%X\n",
3555			cl_ntoh16(p_rec->lid), p_rec->port_num,
3556			p_port->rec.port_info.link_width_active,
3557			p_rec->port_info.link_width_active);
3558		status = IB_ERROR;
3559		goto Exit;
3560	}
3561
3562	if ((p_port->comp.port_info.link_speed & p_port->rec.port_info.
3563	     link_speed) !=
3564	    (p_port->comp.port_info.link_speed & p_rec->port_info.link_speed)) {
3565		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0054: "
3566			"Field mismatch port LID 0x%X Num:0x%X\n"
3567			"\t\t\t\tExpected link_speed 0x%X, received 0x%X\n",
3568			cl_ntoh16(p_rec->lid), p_rec->port_num,
3569			p_port->rec.port_info.link_speed,
3570			p_rec->port_info.link_speed);
3571		status = IB_ERROR;
3572		goto Exit;
3573	}
3574
3575	if ((p_port->comp.port_info.state_info1 & p_port->rec.port_info.
3576	     state_info1) !=
3577	    (p_port->comp.port_info.state_info1 & p_rec->port_info.
3578	     state_info1)) {
3579		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0055: "
3580			"Field mismatch port LID 0x%X Num:0x%X\n"
3581			"\t\t\t\tExpected state_info1 0x%X, received 0x%X\n",
3582			cl_ntoh16(p_rec->lid), p_rec->port_num,
3583			p_port->rec.port_info.state_info1,
3584			p_rec->port_info.state_info1);
3585		status = IB_ERROR;
3586		goto Exit;
3587	}
3588
3589	if ((p_port->comp.port_info.state_info2 & p_port->rec.port_info.
3590	     state_info2) !=
3591	    (p_port->comp.port_info.state_info2 & p_rec->port_info.
3592	     state_info2)) {
3593		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0058: "
3594			"Field mismatch port LID 0x%X Num:0x%X\n"
3595			"\t\t\t\tExpected state_info2 0x%X, received 0x%X\n",
3596			cl_ntoh16(p_rec->lid), p_rec->port_num,
3597			p_port->rec.port_info.state_info2,
3598			p_rec->port_info.state_info2);
3599		status = IB_ERROR;
3600		goto Exit;
3601	}
3602
3603	if ((p_port->comp.port_info.mkey_lmc & p_port->rec.port_info.
3604	     mkey_lmc) !=
3605	    (p_port->comp.port_info.mkey_lmc & p_rec->port_info.mkey_lmc)) {
3606		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0059: "
3607			"Field mismatch port LID 0x%X Num:0x%X\n"
3608			"\t\t\t\tExpected mkey_lmc 0x%X, received 0x%X\n",
3609			cl_ntoh16(p_rec->lid), p_rec->port_num,
3610			p_port->rec.port_info.mkey_lmc,
3611			p_rec->port_info.mkey_lmc);
3612		status = IB_ERROR;
3613		goto Exit;
3614	}
3615
3616	if ((p_port->comp.port_info.link_speed & p_port->rec.port_info.
3617	     link_speed) !=
3618	    (p_port->comp.port_info.link_speed & p_rec->port_info.link_speed)) {
3619		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0060: "
3620			"Field mismatch port LID 0x%X Num:0x%X\n"
3621			"\t\t\t\tExpected link_speed 0x%X, received 0x%X\n",
3622			cl_ntoh16(p_rec->lid), p_rec->port_num,
3623			p_port->rec.port_info.link_speed,
3624			p_rec->port_info.link_speed);
3625		status = IB_ERROR;
3626		goto Exit;
3627	}
3628
3629	if ((p_port->comp.port_info.mtu_smsl & p_port->rec.port_info.
3630	     mtu_smsl) !=
3631	    (p_port->comp.port_info.mtu_smsl & p_rec->port_info.mtu_smsl)) {
3632		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0061: "
3633			"Field mismatch port LID 0x%X Num:0x%X\n"
3634			"\t\t\t\tExpected mtu_smsl 0x%X, received 0x%X\n",
3635			cl_ntoh16(p_rec->lid), p_rec->port_num,
3636			p_port->rec.port_info.mtu_smsl,
3637			p_rec->port_info.mtu_smsl);
3638		status = IB_ERROR;
3639		goto Exit;
3640	}
3641
3642	if ((p_port->comp.port_info.vl_cap & p_port->rec.port_info.vl_cap) !=
3643	    (p_port->comp.port_info.vl_cap & p_rec->port_info.vl_cap)) {
3644		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0062: "
3645			"Field mismatch port LID 0x%X Num:0x%X\n"
3646			"\t\t\t\tExpected vl_cap 0x%X, received 0x%X\n",
3647			cl_ntoh16(p_rec->lid), p_rec->port_num,
3648			p_port->rec.port_info.vl_cap, p_rec->port_info.vl_cap);
3649		status = IB_ERROR;
3650		goto Exit;
3651	}
3652
3653	if ((p_port->comp.port_info.vl_high_limit & p_port->rec.port_info.
3654	     vl_high_limit) !=
3655	    (p_port->comp.port_info.vl_high_limit & p_rec->port_info.
3656	     vl_high_limit)) {
3657		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0082: "
3658			"Field mismatch port LID 0x%X Num:0x%X\n"
3659			"\t\t\t\tExpected vl_high_limit 0x%X, received 0x%X\n",
3660			cl_ntoh16(p_rec->lid), p_rec->port_num,
3661			p_port->rec.port_info.vl_high_limit,
3662			p_rec->port_info.vl_high_limit);
3663		status = IB_ERROR;
3664		goto Exit;
3665	}
3666
3667	if ((p_port->comp.port_info.vl_arb_high_cap & p_port->rec.port_info.
3668	     vl_arb_high_cap) !=
3669	    (p_port->comp.port_info.vl_arb_high_cap & p_rec->port_info.
3670	     vl_arb_high_cap)) {
3671		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0083: "
3672			"Field mismatch port LID 0x%X Num:0x%X\n"
3673			"\t\t\t\tExpected vl_arb_high_cap 0x%X, received 0x%X\n",
3674			cl_ntoh16(p_rec->lid), p_rec->port_num,
3675			p_port->rec.port_info.vl_arb_high_cap,
3676			p_rec->port_info.vl_arb_high_cap);
3677		status = IB_ERROR;
3678		goto Exit;
3679	}
3680
3681	if ((p_port->comp.port_info.vl_arb_low_cap & p_port->rec.port_info.
3682	     vl_arb_low_cap) !=
3683	    (p_port->comp.port_info.vl_arb_low_cap & p_rec->port_info.
3684	     vl_arb_low_cap)) {
3685		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0084: "
3686			"Field mismatch port LID 0x%X Num:0x%X\n"
3687			"\t\t\t\tExpected vl_arb_low_cap 0x%X, received 0x%X\n",
3688			cl_ntoh16(p_rec->lid), p_rec->port_num,
3689			p_port->rec.port_info.vl_arb_low_cap,
3690			p_rec->port_info.vl_arb_low_cap);
3691		status = IB_ERROR;
3692		goto Exit;
3693	}
3694
3695	if ((p_port->comp.port_info.mtu_cap & p_port->rec.port_info.mtu_cap) !=
3696	    (p_port->comp.port_info.mtu_cap & p_rec->port_info.mtu_cap)) {
3697		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0085: "
3698			"Field mismatch port LID 0x%X Num:0x%X\n"
3699			"\t\t\t\tExpected mtu_cap 0x%X, received 0x%X\n",
3700			cl_ntoh16(p_rec->lid), p_rec->port_num,
3701			p_port->rec.port_info.mtu_cap,
3702			p_rec->port_info.mtu_cap);
3703		status = IB_ERROR;
3704		goto Exit;
3705	}
3706#if 0
3707	/* this is a dynamic attribute */
3708	if ((p_port->comp.port_info.vl_stall_life & p_port->rec.port_info.
3709	     vl_stall_life) !=
3710	    (p_port->comp.port_info.vl_stall_life & p_rec->port_info.
3711	     vl_stall_life)) {
3712		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 012F: "
3713			"Field mismatch port LID 0x%X Num:0x%X\n"
3714			"\t\t\t\tExpected vl_stall_life 0x%X, received 0x%X\n",
3715			cl_ntoh16(p_rec->lid), p_rec->port_num,
3716			p_port->rec.port_info.vl_stall_life,
3717			p_rec->port_info.vl_stall_life);
3718		status = IB_ERROR;
3719		goto Exit;
3720	}
3721#endif
3722
3723	if ((p_port->comp.port_info.vl_enforce & p_port->rec.port_info.
3724	     vl_enforce) !=
3725	    (p_port->comp.port_info.vl_enforce & p_rec->port_info.vl_enforce)) {
3726		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0086: "
3727			"Field mismatch port LID 0x%X Num:0x%X\n"
3728			"\t\t\t\tExpected vl_enforce 0x%X, received 0x%X\n",
3729			cl_ntoh16(p_rec->lid), p_rec->port_num,
3730			p_port->rec.port_info.vl_enforce,
3731			p_rec->port_info.vl_enforce);
3732		status = IB_ERROR;
3733		goto Exit;
3734	}
3735
3736	if ((p_port->comp.port_info.m_key_violations & p_port->rec.port_info.
3737	     m_key_violations) !=
3738	    (p_port->comp.port_info.m_key_violations & p_rec->port_info.
3739	     m_key_violations)) {
3740		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0087: "
3741			"Field mismatch port LID 0x%X Num:0x%X\n"
3742			"\t\t\t\tExpected m_key_violations 0x%X, received 0x%X\n",
3743			cl_ntoh16(p_rec->lid), p_rec->port_num,
3744			cl_ntoh16(p_port->rec.port_info.m_key_violations),
3745			cl_ntoh16(p_rec->port_info.m_key_violations));
3746		status = IB_ERROR;
3747		goto Exit;
3748	}
3749
3750	if ((p_port->comp.port_info.p_key_violations & p_port->rec.port_info.
3751	     p_key_violations) !=
3752	    (p_port->comp.port_info.p_key_violations & p_rec->port_info.
3753	     p_key_violations)) {
3754		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0088: "
3755			"Field mismatch port LID 0x%X Num:0x%X\n"
3756			"\t\t\t\tExpected p_key_violations 0x%X, received 0x%X\n",
3757			cl_ntoh16(p_rec->lid), p_rec->port_num,
3758			cl_ntoh16(p_port->rec.port_info.p_key_violations),
3759			cl_ntoh16(p_rec->port_info.p_key_violations));
3760		status = IB_ERROR;
3761		goto Exit;
3762	}
3763
3764	if ((p_port->comp.port_info.q_key_violations & p_port->rec.port_info.
3765	     q_key_violations) !=
3766	    (p_port->comp.port_info.q_key_violations & p_rec->port_info.
3767	     q_key_violations)) {
3768		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0089: "
3769			"Field mismatch port LID 0x%X Num:0x%X\n"
3770			"\t\t\t\tExpected q_key_violations 0x%X, received 0x%X\n",
3771			cl_ntoh16(p_rec->lid), p_rec->port_num,
3772			cl_ntoh16(p_port->rec.port_info.q_key_violations),
3773			cl_ntoh16(p_rec->port_info.q_key_violations));
3774		status = IB_ERROR;
3775		goto Exit;
3776	}
3777
3778	if ((p_port->comp.port_info.guid_cap & p_port->rec.port_info.
3779	     guid_cap) !=
3780	    (p_port->comp.port_info.guid_cap & p_rec->port_info.guid_cap)) {
3781		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0090: "
3782			"Field mismatch port LID 0x%X Num:0x%X\n"
3783			"\t\t\t\tExpected guid_cap 0x%X, received 0x%X\n",
3784			cl_ntoh16(p_rec->lid), p_rec->port_num,
3785			p_port->rec.port_info.guid_cap,
3786			p_rec->port_info.guid_cap);
3787		status = IB_ERROR;
3788		goto Exit;
3789	}
3790
3791	if ((p_port->comp.port_info.subnet_timeout & p_port->rec.port_info.
3792	     subnet_timeout) !=
3793	    (p_port->comp.port_info.subnet_timeout & p_rec->port_info.
3794	     subnet_timeout)) {
3795		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0091: "
3796			"Field mismatch port LID 0x%X Num:0x%X\n"
3797			"\t\t\t\tExpected subnet_timeout 0x%X, received 0x%X\n",
3798			cl_ntoh16(p_rec->lid), p_rec->port_num,
3799			ib_port_info_get_timeout(&p_port->rec.port_info),
3800			ib_port_info_get_timeout(&p_rec->port_info));
3801		status = IB_ERROR;
3802		goto Exit;
3803	}
3804
3805	if ((p_port->comp.port_info.resp_time_value & p_port->rec.port_info.
3806	     resp_time_value) !=
3807	    (p_port->comp.port_info.resp_time_value & p_rec->port_info.
3808	     resp_time_value)) {
3809		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0092: "
3810			"Field mismatch port LID 0x%X Num:0x%X\n"
3811			"\t\t\t\tExpected resp_time_value 0x%X, received 0x%X\n",
3812			cl_ntoh16(p_rec->lid), p_rec->port_num,
3813			p_port->rec.port_info.resp_time_value,
3814			p_rec->port_info.resp_time_value);
3815		status = IB_ERROR;
3816		goto Exit;
3817	}
3818
3819	if ((p_port->comp.port_info.error_threshold & p_port->rec.port_info.
3820	     error_threshold) !=
3821	    (p_port->comp.port_info.error_threshold & p_rec->port_info.
3822	     error_threshold)) {
3823		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0093: "
3824			"Field mismatch port LID 0x%X Num:0x%X\n"
3825			"\t\t\t\tExpected error_threshold 0x%X, received 0x%X\n",
3826			cl_ntoh16(p_rec->lid), p_rec->port_num,
3827			p_port->rec.port_info.error_threshold,
3828			p_rec->port_info.error_threshold);
3829		status = IB_ERROR;
3830		goto Exit;
3831	}
3832
3833Exit:
3834	OSM_LOG_EXIT(&p_osmt->log);
3835	return (status);
3836}
3837
3838/**********************************************************************
3839 **********************************************************************/
3840static ib_api_status_t
3841osmtest_validate_port_rec(IN osmtest_t * const p_osmt,
3842			  IN const ib_portinfo_record_t * const p_rec)
3843{
3844	cl_status_t status = IB_SUCCESS;
3845	port_t *p_port;
3846	const cl_qmap_t *p_tbl;
3847
3848	OSM_LOG_ENTER(&p_osmt->log);
3849
3850	/*
3851	 * Find proper port record in the database.
3852	 * (we use by guid - since lid is not unique)
3853	 */
3854	p_tbl = &p_osmt->exp_subn.port_key_tbl;
3855	p_port =
3856	    (port_t *) cl_qmap_get(p_tbl,
3857				   port_gen_id(p_rec->lid, p_rec->port_num));
3858	if (p_port == (port_t *) cl_qmap_end(p_tbl)) {
3859		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0094: "
3860			"Unexpected port LID 0x%X, Num:0x%X\n",
3861			cl_ntoh16(p_rec->lid), p_rec->port_num);
3862		status = IB_ERROR;
3863		goto Exit;
3864	}
3865
3866	status = osmtest_validate_port_data(p_osmt, p_port, p_rec);
3867
3868Exit:
3869	OSM_LOG_EXIT(&p_osmt->log);
3870	return (status);
3871}
3872
3873/**********************************************************************
3874 **********************************************************************/
3875static ib_api_status_t
3876osmtest_validate_path_rec(IN osmtest_t * const p_osmt,
3877			  IN const ib_path_rec_t * const p_rec)
3878{
3879	cl_status_t status = IB_SUCCESS;
3880	path_t *p_path;
3881	const cl_qmap_t *p_tbl;
3882
3883	OSM_LOG_ENTER(&p_osmt->log);
3884
3885	/*
3886	 * Find proper path record in the database.
3887	 */
3888	p_tbl = &p_osmt->exp_subn.path_tbl;
3889	p_path = (path_t *) cl_qmap_get(p_tbl, osmtest_path_rec_key_get(p_rec));
3890	if (p_path == (path_t *) cl_qmap_end(p_tbl)) {
3891		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0095: "
3892			"Unexpected path SLID 0x%X to DLID 0x%X\n",
3893			cl_ntoh16(p_rec->slid), cl_ntoh16(p_rec->dlid));
3894		status = IB_ERROR;
3895		goto Exit;
3896	}
3897
3898	status = osmtest_validate_path_data(p_osmt, p_path, p_rec);
3899
3900Exit:
3901	OSM_LOG_EXIT(&p_osmt->log);
3902	return (status);
3903}
3904
3905#ifdef VENDOR_RMPP_SUPPORT
3906ib_net64_t portguid = 0;
3907
3908/**********************************************************************
3909 **********************************************************************/
3910static ib_api_status_t
3911osmtest_validate_all_node_recs(IN osmtest_t * const p_osmt)
3912{
3913	osmtest_req_context_t context;
3914	const ib_node_record_t *p_rec;
3915	uint32_t i;
3916	cl_status_t status;
3917	size_t num_recs;
3918
3919	OSM_LOG_ENTER(&p_osmt->log);
3920
3921	memset(&context, 0, sizeof(context));
3922
3923	/*
3924	 * Do a blocking query for all NodeRecords in the subnet.
3925	 */
3926	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_NODE_RECORD,
3927				      sizeof(*p_rec), &context);
3928
3929	if (status != IB_SUCCESS) {
3930		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0096: "
3931			"osmtest_get_all_recs failed (%s)\n",
3932			ib_get_err_str(status));
3933		goto Exit;
3934	}
3935
3936	num_recs = context.result.result_cnt;
3937
3938	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n",
3939		num_recs);
3940
3941	/*
3942	 * Compare the received records to the database.
3943	 */
3944	osmtest_prepare_db(p_osmt);
3945
3946	for (i = 0; i < num_recs; i++) {
3947		p_rec =
3948		    osmv_get_query_node_rec(context.result.p_result_madw, i);
3949
3950		status = osmtest_validate_node_rec(p_osmt, p_rec);
3951		if (status != IB_SUCCESS) {
3952			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0097: "
3953				"osmtest_valid_node_rec failed (%s)\n",
3954				ib_get_err_str(status));
3955			goto Exit;
3956		}
3957		if (!portguid)
3958			portguid = p_rec->node_info.port_guid;
3959	}
3960
3961	status = osmtest_check_missing_nodes(p_osmt);
3962	if (status != IB_SUCCESS) {
3963		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0098: "
3964			"osmtest_check_missing_nodes failed (%s)\n",
3965			ib_get_err_str(status));
3966		goto Exit;
3967	}
3968
3969Exit:
3970	/*
3971	 * Return the IB query MAD to the pool as necessary.
3972	 */
3973	if (context.result.p_result_madw != NULL) {
3974		osm_mad_pool_put(&p_osmt->mad_pool,
3975				 context.result.p_result_madw);
3976		context.result.p_result_madw = NULL;
3977	}
3978
3979	OSM_LOG_EXIT(&p_osmt->log);
3980	return (status);
3981}
3982
3983/**********************************************************************
3984 **********************************************************************/
3985static ib_api_status_t
3986osmtest_validate_all_guidinfo_recs(IN osmtest_t * const p_osmt)
3987{
3988	osmtest_req_context_t context;
3989	const ib_guidinfo_record_t *p_rec;
3990	cl_status_t status;
3991	size_t num_recs;
3992
3993	OSM_LOG_ENTER(&p_osmt->log);
3994
3995	memset(&context, 0, sizeof(context));
3996
3997	/*
3998	 * Do a blocking query for all GuidInfoRecords in the subnet.
3999	 */
4000	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_GUIDINFO_RECORD,
4001				      sizeof(*p_rec), &context);
4002
4003	if (status != IB_SUCCESS) {
4004		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0099: "
4005			"osmtest_get_all_recs failed (%s)\n",
4006			ib_get_err_str(status));
4007		goto Exit;
4008	}
4009
4010	num_recs = context.result.result_cnt;
4011
4012	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n",
4013		num_recs);
4014
4015	/* No validation as yet */
4016
4017Exit:
4018	/*
4019	 * Return the IB query MAD to the pool as necessary.
4020	 */
4021	if (context.result.p_result_madw != NULL) {
4022		osm_mad_pool_put(&p_osmt->mad_pool,
4023				 context.result.p_result_madw);
4024		context.result.p_result_madw = NULL;
4025	}
4026
4027	OSM_LOG_EXIT(&p_osmt->log);
4028	return (status);
4029}
4030
4031/**********************************************************************
4032 **********************************************************************/
4033static ib_api_status_t
4034osmtest_validate_all_path_recs(IN osmtest_t * const p_osmt)
4035{
4036	osmtest_req_context_t context;
4037	const ib_path_rec_t *p_rec;
4038	uint32_t i;
4039	cl_status_t status;
4040	size_t num_recs;
4041
4042	OSM_LOG_ENTER(&p_osmt->log);
4043
4044	memset(&context, 0, sizeof(context));
4045
4046	/*
4047	 * Do a blocking query for all PathRecords in the subnet.
4048	 */
4049	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_PATH_RECORD,
4050				      sizeof(*p_rec), &context);
4051
4052	if (status != IB_SUCCESS) {
4053		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 009A: "
4054			"osmtest_get_all_recs failed (%s)\n",
4055			ib_get_err_str(status));
4056		goto Exit;
4057	}
4058
4059	num_recs = context.result.result_cnt;
4060
4061	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %zu records\n",
4062		num_recs);
4063
4064	/*
4065	 * Compare the received records to the database.
4066	 */
4067	osmtest_prepare_db(p_osmt);
4068
4069	for (i = 0; i < num_recs; i++) {
4070		p_rec =
4071		    osmv_get_query_path_rec(context.result.p_result_madw, i);
4072
4073		status = osmtest_validate_path_rec(p_osmt, p_rec);
4074		if (status != IB_SUCCESS) {
4075			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0100: "
4076				"osmtest_validate_path_rec failed (%s)\n",
4077				ib_get_err_str(status));
4078			goto Exit;
4079		}
4080	}
4081
4082	status = osmtest_check_missing_paths(p_osmt);
4083	if (status != IB_SUCCESS) {
4084		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0101: "
4085			"osmtest_check_missing_paths failed (%s)\n",
4086			ib_get_err_str(status));
4087		goto Exit;
4088	}
4089
4090Exit:
4091	/*
4092	 * Return the IB query MAD to the pool as necessary.
4093	 */
4094	if (context.result.p_result_madw != NULL) {
4095		osm_mad_pool_put(&p_osmt->mad_pool,
4096				 context.result.p_result_madw);
4097		context.result.p_result_madw = NULL;
4098	}
4099
4100	OSM_LOG_EXIT(&p_osmt->log);
4101	return (status);
4102}
4103
4104/**********************************************************************
4105 * Get link record by LID
4106 **********************************************************************/
4107ib_api_status_t
4108osmtest_get_link_rec_by_lid(IN osmtest_t * const p_osmt,
4109			    IN ib_net16_t const from_lid,
4110			    IN ib_net16_t const to_lid,
4111			    IN OUT osmtest_req_context_t * const p_context)
4112{
4113	ib_api_status_t status = IB_SUCCESS;
4114	osmv_user_query_t user;
4115	osmv_query_req_t req;
4116	ib_link_record_t record;
4117	ib_mad_t *p_mad;
4118
4119	OSM_LOG_ENTER(&p_osmt->log);
4120
4121	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4122		"Getting link record from LID 0x%02X to LID 0x%02X\n",
4123		cl_ntoh16(from_lid), cl_ntoh16(to_lid));
4124
4125	/*
4126	 * Do a blocking query for this record in the subnet.
4127	 * The result is returned in the result field of the caller's
4128	 * context structure.
4129	 *
4130	 * The query structures are locals.
4131	 */
4132	memset(&req, 0, sizeof(req));
4133	memset(&user, 0, sizeof(user));
4134	memset(&record, 0, sizeof(record));
4135
4136	record.from_lid = from_lid;
4137	record.to_lid = to_lid;
4138	p_context->p_osmt = p_osmt;
4139	if (from_lid)
4140		user.comp_mask |= IB_LR_COMPMASK_FROM_LID;
4141	if (to_lid)
4142		user.comp_mask |= IB_LR_COMPMASK_TO_LID;
4143	user.attr_id = IB_MAD_ATTR_LINK_RECORD;
4144	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4145	user.p_attr = &record;
4146
4147	req.query_type = OSMV_QUERY_USER_DEFINED;
4148	req.timeout_ms = p_osmt->opt.transaction_timeout;
4149	req.retry_cnt = p_osmt->opt.retry_count;
4150	req.flags = OSM_SA_FLAGS_SYNC;
4151	req.query_context = p_context;
4152	req.pfn_query_cb = osmtest_query_res_cb;
4153	req.p_query_input = &user;
4154	req.sm_key = 0;
4155
4156	status = osmv_query_sa(p_osmt->h_bind, &req);
4157	if (status != IB_SUCCESS) {
4158		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007A: "
4159			"ib_query failed (%s)\n", ib_get_err_str(status));
4160		goto Exit;
4161	}
4162
4163	status = p_context->result.status;
4164
4165	if (status != IB_SUCCESS) {
4166		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007B: "
4167			"ib_query failed (%s)\n", ib_get_err_str(status));
4168		if (status == IB_REMOTE_ERROR) {
4169			p_mad =
4170			    osm_madw_get_mad_ptr(p_context->result.
4171						 p_result_madw);
4172			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4173				"osmtest_get_link_rec_by_lid: "
4174				"Remote error = %s\n",
4175				ib_get_mad_status_str(p_mad));
4176
4177			status =
4178			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4179		}
4180		goto Exit;
4181	}
4182
4183Exit:
4184	OSM_LOG_EXIT(&p_osmt->log);
4185	return (status);
4186}
4187
4188/**********************************************************************
4189 * Get GUIDInfo record by LID
4190 **********************************************************************/
4191ib_api_status_t
4192osmtest_get_guidinfo_rec_by_lid(IN osmtest_t * const p_osmt,
4193				IN ib_net16_t const lid,
4194				IN OUT osmtest_req_context_t * const p_context)
4195{
4196	ib_api_status_t status = IB_SUCCESS;
4197	osmv_user_query_t user;
4198	osmv_query_req_t req;
4199	ib_guidinfo_record_t record;
4200	ib_mad_t *p_mad;
4201
4202	OSM_LOG_ENTER(&p_osmt->log);
4203
4204	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4205		"Getting GUIDInfo record for LID 0x%02X\n", cl_ntoh16(lid));
4206
4207	/*
4208	 * Do a blocking query for this record in the subnet.
4209	 * The result is returned in the result field of the caller's
4210	 * context structure.
4211	 *
4212	 * The query structures are locals.
4213	 */
4214	memset(&req, 0, sizeof(req));
4215	memset(&user, 0, sizeof(user));
4216	memset(&record, 0, sizeof(record));
4217
4218	record.lid = lid;
4219	p_context->p_osmt = p_osmt;
4220	user.comp_mask = IB_GIR_COMPMASK_LID;
4221	user.attr_id = IB_MAD_ATTR_GUIDINFO_RECORD;
4222	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4223	user.p_attr = &record;
4224
4225	req.query_type = OSMV_QUERY_USER_DEFINED;
4226	req.timeout_ms = p_osmt->opt.transaction_timeout;
4227	req.retry_cnt = p_osmt->opt.retry_count;
4228
4229	req.flags = OSM_SA_FLAGS_SYNC;
4230	req.query_context = p_context;
4231	req.pfn_query_cb = osmtest_query_res_cb;
4232	req.p_query_input = &user;
4233	req.sm_key = 0;
4234
4235	status = osmv_query_sa(p_osmt->h_bind, &req);
4236	if (status != IB_SUCCESS) {
4237		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007C: "
4238			"ib_query failed (%s)\n", ib_get_err_str(status));
4239		goto Exit;
4240	}
4241
4242	status = p_context->result.status;
4243
4244	if (status != IB_SUCCESS) {
4245		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007D: "
4246			"ib_query failed (%s)\n", ib_get_err_str(status));
4247		if (status == IB_REMOTE_ERROR) {
4248			p_mad =
4249			    osm_madw_get_mad_ptr(p_context->result.
4250						 p_result_madw);
4251			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4252				"Remote error = %s\n",
4253				ib_get_mad_status_str(p_mad));
4254
4255			status =
4256			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4257		}
4258		goto Exit;
4259	}
4260
4261Exit:
4262	OSM_LOG_EXIT(&p_osmt->log);
4263	return (status);
4264}
4265
4266/**********************************************************************
4267 * Get PKeyTable record by LID
4268 **********************************************************************/
4269ib_api_status_t
4270osmtest_get_pkeytbl_rec_by_lid(IN osmtest_t * const p_osmt,
4271			       IN ib_net16_t const lid,
4272			       IN ib_net64_t const sm_key,
4273			       IN OUT osmtest_req_context_t * const p_context)
4274{
4275	ib_api_status_t status = IB_SUCCESS;
4276	osmv_user_query_t user;
4277	osmv_query_req_t req;
4278	ib_pkey_table_record_t record;
4279	ib_mad_t *p_mad;
4280
4281	OSM_LOG_ENTER(&p_osmt->log);
4282
4283	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4284		"Getting PKeyTable record for LID 0x%02X\n", cl_ntoh16(lid));
4285
4286	/*
4287	 * Do a blocking query for this record in the subnet.
4288	 * The result is returned in the result field of the caller's
4289	 * context structure.
4290	 *
4291	 * The query structures are locals.
4292	 */
4293	memset(&req, 0, sizeof(req));
4294	memset(&user, 0, sizeof(user));
4295	memset(&record, 0, sizeof(record));
4296
4297	record.lid = lid;
4298	p_context->p_osmt = p_osmt;
4299	user.comp_mask = IB_PKEY_COMPMASK_LID;
4300	user.attr_id = IB_MAD_ATTR_PKEY_TBL_RECORD;
4301	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4302	user.p_attr = &record;
4303
4304	req.query_type = OSMV_QUERY_USER_DEFINED;
4305	req.timeout_ms = p_osmt->opt.transaction_timeout;
4306	req.retry_cnt = p_osmt->opt.retry_count;
4307
4308	req.flags = OSM_SA_FLAGS_SYNC;
4309	req.query_context = p_context;
4310	req.pfn_query_cb = osmtest_query_res_cb;
4311	req.p_query_input = &user;
4312	req.sm_key = sm_key;
4313
4314	status = osmv_query_sa(p_osmt->h_bind, &req);
4315	if (status != IB_SUCCESS) {
4316		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007E: "
4317			"ib_query failed (%s)\n", ib_get_err_str(status));
4318		goto Exit;
4319	}
4320
4321	status = p_context->result.status;
4322
4323	if (status != IB_SUCCESS) {
4324		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 007F: "
4325			"ib_query failed (%s)\n", ib_get_err_str(status));
4326		if (status == IB_REMOTE_ERROR) {
4327			p_mad =
4328			    osm_madw_get_mad_ptr(p_context->result.
4329						 p_result_madw);
4330			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4331				"Remote error = %s\n",
4332				ib_get_mad_status_str(p_mad));
4333
4334			status =
4335			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4336		}
4337		goto Exit;
4338	}
4339
4340Exit:
4341	OSM_LOG_EXIT(&p_osmt->log);
4342	return (status);
4343}
4344
4345/**********************************************************************
4346 * Get SwitchInfo record by LID
4347 **********************************************************************/
4348ib_api_status_t
4349osmtest_get_sw_info_rec_by_lid(IN osmtest_t * const p_osmt,
4350			       IN ib_net16_t const lid,
4351			       IN OUT osmtest_req_context_t * const p_context)
4352{
4353	ib_api_status_t status = IB_SUCCESS;
4354	osmv_user_query_t user;
4355	osmv_query_req_t req;
4356	ib_switch_info_record_t record;
4357	ib_mad_t *p_mad;
4358
4359	OSM_LOG_ENTER(&p_osmt->log);
4360
4361	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4362		"Getting SwitchInfo record for LID 0x%02X\n", cl_ntoh16(lid));
4363
4364	/*
4365	 * Do a blocking query for this record in the subnet.
4366	 * The result is returned in the result field of the caller's
4367	 * context structure.
4368	 *
4369	 * The query structures are locals.
4370	 */
4371	memset(&req, 0, sizeof(req));
4372	memset(&user, 0, sizeof(user));
4373	memset(&record, 0, sizeof(record));
4374
4375	record.lid = lid;
4376	p_context->p_osmt = p_osmt;
4377	if (lid)
4378		user.comp_mask = IB_SWIR_COMPMASK_LID;
4379	user.attr_id = IB_MAD_ATTR_SWITCH_INFO_RECORD;
4380	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4381	user.p_attr = &record;
4382
4383	req.query_type = OSMV_QUERY_USER_DEFINED;
4384	req.timeout_ms = p_osmt->opt.transaction_timeout;
4385	req.retry_cnt = p_osmt->opt.retry_count;
4386
4387	req.flags = OSM_SA_FLAGS_SYNC;
4388	req.query_context = p_context;
4389	req.pfn_query_cb = osmtest_query_res_cb;
4390	req.p_query_input = &user;
4391	req.sm_key = 0;
4392
4393	status = osmv_query_sa(p_osmt->h_bind, &req);
4394	if (status != IB_SUCCESS) {
4395		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006C: "
4396			"ib_query failed (%s)\n", ib_get_err_str(status));
4397		goto Exit;
4398	}
4399
4400	status = p_context->result.status;
4401
4402	if (status != IB_SUCCESS) {
4403		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 006D: "
4404			"ib_query failed (%s)\n", ib_get_err_str(status));
4405		if (status == IB_REMOTE_ERROR) {
4406			p_mad =
4407			    osm_madw_get_mad_ptr(p_context->result.
4408						 p_result_madw);
4409			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4410				"Remote error = %s\n",
4411				ib_get_mad_status_str(p_mad));
4412
4413			status =
4414			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4415		}
4416		goto Exit;
4417	}
4418
4419Exit:
4420	OSM_LOG_EXIT(&p_osmt->log);
4421	return (status);
4422}
4423
4424/**********************************************************************
4425 * Get LFT record by LID
4426 **********************************************************************/
4427ib_api_status_t
4428osmtest_get_lft_rec_by_lid(IN osmtest_t * const p_osmt,
4429			   IN ib_net16_t const lid,
4430			   IN OUT osmtest_req_context_t * const p_context)
4431{
4432	ib_api_status_t status = IB_SUCCESS;
4433	osmv_user_query_t user;
4434	osmv_query_req_t req;
4435	ib_lft_record_t record;
4436	ib_mad_t *p_mad;
4437
4438	OSM_LOG_ENTER(&p_osmt->log);
4439
4440	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4441		"Getting LFT record for LID 0x%02X\n", cl_ntoh16(lid));
4442
4443	/*
4444	 * Do a blocking query for this record in the subnet.
4445	 * The result is returned in the result field of the caller's
4446	 * context structure.
4447	 *
4448	 * The query structures are locals.
4449	 */
4450	memset(&req, 0, sizeof(req));
4451	memset(&user, 0, sizeof(user));
4452	memset(&record, 0, sizeof(record));
4453
4454	record.lid = lid;
4455	p_context->p_osmt = p_osmt;
4456	if (lid)
4457		user.comp_mask = IB_LFTR_COMPMASK_LID;
4458	user.attr_id = IB_MAD_ATTR_LFT_RECORD;
4459	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4460	user.p_attr = &record;
4461
4462	req.query_type = OSMV_QUERY_USER_DEFINED;
4463	req.timeout_ms = p_osmt->opt.transaction_timeout;
4464	req.retry_cnt = p_osmt->opt.retry_count;
4465
4466	req.flags = OSM_SA_FLAGS_SYNC;
4467	req.query_context = p_context;
4468	req.pfn_query_cb = osmtest_query_res_cb;
4469	req.p_query_input = &user;
4470	req.sm_key = 0;
4471
4472	status = osmv_query_sa(p_osmt->h_bind, &req);
4473	if (status != IB_SUCCESS) {
4474		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008A: "
4475			"ib_query failed (%s)\n", ib_get_err_str(status));
4476		goto Exit;
4477	}
4478
4479	status = p_context->result.status;
4480
4481	if (status != IB_SUCCESS) {
4482		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008B: "
4483			"ib_query failed (%s)\n", ib_get_err_str(status));
4484		if (status == IB_REMOTE_ERROR) {
4485			p_mad =
4486			    osm_madw_get_mad_ptr(p_context->result.
4487						 p_result_madw);
4488			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4489				"Remote error = %s\n",
4490				ib_get_mad_status_str(p_mad));
4491
4492			status =
4493			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4494		}
4495		goto Exit;
4496	}
4497
4498Exit:
4499	OSM_LOG_EXIT(&p_osmt->log);
4500	return (status);
4501}
4502
4503/**********************************************************************
4504 * Get MFT record by LID
4505 **********************************************************************/
4506ib_api_status_t
4507osmtest_get_mft_rec_by_lid(IN osmtest_t * const p_osmt,
4508			   IN ib_net16_t const lid,
4509			   IN OUT osmtest_req_context_t * const p_context)
4510{
4511	ib_api_status_t status = IB_SUCCESS;
4512	osmv_user_query_t user;
4513	osmv_query_req_t req;
4514	ib_mft_record_t record;
4515	ib_mad_t *p_mad;
4516
4517	OSM_LOG_ENTER(&p_osmt->log);
4518
4519	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4520		"Getting MFT record for LID 0x%02X\n", cl_ntoh16(lid));
4521
4522	/*
4523	 * Do a blocking query for this record in the subnet.
4524	 * The result is returned in the result field of the caller's
4525	 * context structure.
4526	 *
4527	 * The query structures are locals.
4528	 */
4529	memset(&req, 0, sizeof(req));
4530	memset(&user, 0, sizeof(user));
4531	memset(&record, 0, sizeof(record));
4532
4533	record.lid = lid;
4534	p_context->p_osmt = p_osmt;
4535	if (lid)
4536		user.comp_mask = IB_MFTR_COMPMASK_LID;
4537	user.attr_id = IB_MAD_ATTR_MFT_RECORD;
4538	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4539	user.p_attr = &record;
4540
4541	req.query_type = OSMV_QUERY_USER_DEFINED;
4542	req.timeout_ms = p_osmt->opt.transaction_timeout;
4543	req.retry_cnt = p_osmt->opt.retry_count;
4544
4545	req.flags = OSM_SA_FLAGS_SYNC;
4546	req.query_context = p_context;
4547	req.pfn_query_cb = osmtest_query_res_cb;
4548	req.p_query_input = &user;
4549	req.sm_key = 0;
4550
4551	status = osmv_query_sa(p_osmt->h_bind, &req);
4552	if (status != IB_SUCCESS) {
4553		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 009B: "
4554			"ib_query failed (%s)\n", ib_get_err_str(status));
4555		goto Exit;
4556	}
4557
4558	status = p_context->result.status;
4559
4560	if (status != IB_SUCCESS) {
4561		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 009C: "
4562			"ib_query failed (%s)\n", ib_get_err_str(status));
4563		if (status == IB_REMOTE_ERROR) {
4564			p_mad =
4565			    osm_madw_get_mad_ptr(p_context->result.
4566						 p_result_madw);
4567			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4568				"Remote error = %s\n",
4569				ib_get_mad_status_str(p_mad));
4570
4571			status =
4572			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4573		}
4574		goto Exit;
4575	}
4576
4577Exit:
4578	OSM_LOG_EXIT(&p_osmt->log);
4579	return (status);
4580}
4581
4582/**********************************************************************
4583 **********************************************************************/
4584static ib_api_status_t
4585osmtest_sminfo_record_request(IN osmtest_t * const p_osmt,
4586			      IN uint8_t method,
4587			      IN void *p_options,
4588			      IN OUT osmtest_req_context_t * const p_context)
4589{
4590	ib_api_status_t status = IB_SUCCESS;
4591	osmv_user_query_t user;
4592	osmv_query_req_t req;
4593	ib_sminfo_record_t record;
4594	ib_mad_t *p_mad;
4595	osmtest_sm_info_rec_t *p_sm_info_opt;
4596
4597	OSM_LOG_ENTER(&p_osmt->log);
4598
4599	/*
4600	 * Do a blocking query for these records in the subnet.
4601	 * The result is returned in the result field of the caller's
4602	 * context structure.
4603	 *
4604	 * The query structures are locals.
4605	 */
4606	memset(&req, 0, sizeof(req));
4607	memset(&user, 0, sizeof(user));
4608	memset(&record, 0, sizeof(record));
4609
4610	p_context->p_osmt = p_osmt;
4611	user.attr_id = IB_MAD_ATTR_SMINFO_RECORD;
4612	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4613	p_sm_info_opt = p_options;
4614	if (p_sm_info_opt->sm_guid != 0) {
4615		record.sm_info.guid = p_sm_info_opt->sm_guid;
4616		user.comp_mask |= IB_SMIR_COMPMASK_GUID;
4617	}
4618	if (p_sm_info_opt->lid != 0) {
4619		record.lid = p_sm_info_opt->lid;
4620		user.comp_mask |= IB_SMIR_COMPMASK_LID;
4621	}
4622	if (p_sm_info_opt->priority != 0) {
4623		record.sm_info.pri_state =
4624		    (p_sm_info_opt->priority & 0x0F) << 4;
4625		user.comp_mask |= IB_SMIR_COMPMASK_PRIORITY;
4626	}
4627	if (p_sm_info_opt->sm_state != 0) {
4628		record.sm_info.pri_state |= p_sm_info_opt->sm_state & 0x0F;
4629		user.comp_mask |= IB_SMIR_COMPMASK_SMSTATE;
4630	}
4631
4632	user.method = method;
4633	user.p_attr = &record;
4634
4635	req.query_type = OSMV_QUERY_USER_DEFINED;
4636	req.timeout_ms = p_osmt->opt.transaction_timeout;
4637	req.retry_cnt = p_osmt->opt.retry_count;
4638
4639	req.flags = OSM_SA_FLAGS_SYNC;
4640	req.query_context = p_context;
4641	req.pfn_query_cb = osmtest_query_res_cb;
4642	req.p_query_input = &user;
4643	req.sm_key = 0;
4644
4645	status = osmv_query_sa(p_osmt->h_bind, &req);
4646	if (status != IB_SUCCESS) {
4647		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008C: "
4648			"ib_query failed (%s)\n", ib_get_err_str(status));
4649		goto Exit;
4650	}
4651
4652	status = p_context->result.status;
4653
4654	if (status != IB_SUCCESS) {
4655		if (status != IB_INVALID_PARAMETER) {
4656			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008D: "
4657				"ib_query failed (%s)\n",
4658				ib_get_err_str(status));
4659		}
4660		if (status == IB_REMOTE_ERROR) {
4661			p_mad =
4662			    osm_madw_get_mad_ptr(p_context->result.
4663						 p_result_madw);
4664			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4665				"Remote error = %s\n",
4666				ib_get_mad_status_str(p_mad));
4667
4668			status =
4669			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4670		}
4671		goto Exit;
4672	}
4673
4674Exit:
4675	OSM_LOG_EXIT(&p_osmt->log);
4676	return (status);
4677}
4678
4679/**********************************************************************
4680 **********************************************************************/
4681static ib_api_status_t
4682osmtest_informinfo_request(IN osmtest_t * const p_osmt,
4683			   IN ib_net16_t attr_id,
4684			   IN uint8_t method,
4685			   IN void *p_options,
4686			   IN OUT osmtest_req_context_t * const p_context)
4687{
4688	ib_api_status_t status = IB_SUCCESS;
4689	osmv_user_query_t user;
4690	osmv_query_req_t req;
4691	ib_inform_info_t rec;
4692	ib_inform_info_record_t record;
4693	ib_mad_t *p_mad;
4694	osmtest_inform_info_t *p_inform_info_opt;
4695	osmtest_inform_info_rec_t *p_inform_info_rec_opt;
4696
4697	OSM_LOG_ENTER(&p_osmt->log);
4698
4699	/*
4700	 * Do a blocking query for these records in the subnet.
4701	 * The result is returned in the result field of the caller's
4702	 * context structure.
4703	 *
4704	 * The query structures are locals.
4705	 */
4706	memset(&req, 0, sizeof(req));
4707	memset(&user, 0, sizeof(user));
4708	memset(&rec, 0, sizeof(rec));
4709	memset(&record, 0, sizeof(record));
4710
4711	p_context->p_osmt = p_osmt;
4712	user.attr_id = attr_id;
4713	if (attr_id == IB_MAD_ATTR_INFORM_INFO_RECORD) {
4714		user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4715		p_inform_info_rec_opt = p_options;
4716		if (p_inform_info_rec_opt->subscriber_gid.unicast.prefix != 0 &&
4717		    p_inform_info_rec_opt->subscriber_gid.unicast.
4718		    interface_id != 0) {
4719			record.subscriber_gid =
4720			    p_inform_info_rec_opt->subscriber_gid;
4721			user.comp_mask = IB_IIR_COMPMASK_SUBSCRIBERGID;
4722		}
4723		record.subscriber_enum =
4724		    cl_hton16(p_inform_info_rec_opt->subscriber_enum);
4725		user.comp_mask |= IB_IIR_COMPMASK_ENUM;
4726		user.p_attr = &record;
4727	} else {
4728		user.attr_offset = cl_ntoh16((uint16_t) (sizeof(rec) >> 3));
4729		/* comp mask bits below are for InformInfoRecord rather than InformInfo */
4730		/* as currently no comp mask bits defined for InformInfo!!! */
4731		user.comp_mask = IB_IIR_COMPMASK_SUBSCRIBE;
4732		p_inform_info_opt = p_options;
4733		rec.subscribe = (uint8_t) p_inform_info_opt->subscribe;
4734		if (p_inform_info_opt->qpn) {
4735			rec.g_or_v.generic.qpn_resp_time_val =
4736			    cl_hton32(p_inform_info_opt->qpn << 8);
4737			user.comp_mask |= IB_IIR_COMPMASK_QPN;
4738		}
4739		if (p_inform_info_opt->trap) {
4740			rec.g_or_v.generic.trap_num =
4741			    cl_hton16(p_inform_info_opt->trap);
4742			user.comp_mask |= IB_IIR_COMPMASK_TRAPNUMB;
4743		}
4744		user.p_attr = &rec;
4745	}
4746	user.method = method;
4747
4748	req.query_type = OSMV_QUERY_USER_DEFINED;
4749	req.timeout_ms = p_osmt->opt.transaction_timeout;
4750	req.retry_cnt = p_osmt->opt.retry_count;
4751
4752	req.flags = OSM_SA_FLAGS_SYNC;
4753	req.query_context = p_context;
4754	req.pfn_query_cb = osmtest_query_res_cb;
4755	req.p_query_input = &user;
4756	req.sm_key = 0;
4757
4758	status = osmv_query_sa(p_osmt->h_bind, &req);
4759	if (status != IB_SUCCESS) {
4760		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008E: "
4761			"ib_query failed (%s)\n", ib_get_err_str(status));
4762		goto Exit;
4763	}
4764
4765	status = p_context->result.status;
4766
4767	if (status != IB_SUCCESS) {
4768		if (status != IB_INVALID_PARAMETER) {
4769			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 008F: "
4770				"ib_query failed (%s)\n",
4771				ib_get_err_str(status));
4772		}
4773		if (status == IB_REMOTE_ERROR) {
4774			p_mad =
4775			    osm_madw_get_mad_ptr(p_context->result.
4776						 p_result_madw);
4777			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4778				"Remote error = %s\n",
4779				ib_get_mad_status_str(p_mad));
4780
4781			status =
4782			    (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK);
4783		}
4784		goto Exit;
4785	}
4786
4787Exit:
4788	OSM_LOG_EXIT(&p_osmt->log);
4789	return (status);
4790}
4791#endif
4792
4793/**********************************************************************
4794 **********************************************************************/
4795static ib_api_status_t
4796osmtest_validate_single_path_rec_lid_pair(IN osmtest_t * const p_osmt,
4797					  IN path_t * const p_path)
4798{
4799	osmtest_req_context_t context;
4800	const ib_path_rec_t *p_rec;
4801	cl_status_t status = IB_SUCCESS;
4802	size_t num_recs;
4803
4804	OSM_LOG_ENTER(&p_osmt->log);
4805
4806	memset(&context, 0, sizeof(context));
4807
4808	status = osmtest_get_path_rec_by_lid_pair(p_osmt,
4809						  p_path->rec.slid,
4810						  p_path->rec.dlid, &context);
4811	if (status != IB_SUCCESS) {
4812		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0102: "
4813			"ib_query failed (%s)\n", ib_get_err_str(status));
4814		goto Exit;
4815	}
4816
4817	num_recs = context.result.result_cnt;
4818	if (num_recs != 1) {
4819		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0103: "
4820			"Too many records. Expected 1, received %zu\n",
4821			num_recs);
4822
4823		status = IB_ERROR;
4824	} else {
4825		p_rec =
4826		    osmv_get_query_path_rec(context.result.p_result_madw, 0);
4827
4828		status = osmtest_validate_path_data(p_osmt, p_path, p_rec);
4829		if (status != IB_SUCCESS) {
4830			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0104: "
4831				"osmtest_validate_path_data failed (%s)\n",
4832				ib_get_err_str(status));
4833		}
4834	}
4835
4836Exit:
4837	/*
4838	 * Return the IB query MAD to the pool as necessary.
4839	 */
4840	if (context.result.p_result_madw != NULL) {
4841		osm_mad_pool_put(&p_osmt->mad_pool,
4842				 context.result.p_result_madw);
4843		context.result.p_result_madw = NULL;
4844	}
4845
4846	OSM_LOG_EXIT(&p_osmt->log);
4847	return (status);
4848}
4849
4850/**********************************************************************
4851 **********************************************************************/
4852static ib_api_status_t
4853osmtest_validate_single_node_rec_lid(IN osmtest_t * const p_osmt,
4854				     IN ib_net16_t const lid,
4855				     IN node_t * const p_node)
4856{
4857	cl_status_t status = IB_SUCCESS;
4858	osmv_user_query_t user;
4859	osmv_query_req_t req;
4860	ib_node_record_t record;
4861
4862	osmtest_req_context_t context;
4863	const ib_node_record_t *p_rec;
4864	int num_recs, i;
4865
4866	OSM_LOG_ENTER(&p_osmt->log);
4867
4868	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
4869		"Getting NodeRecord for node with LID 0x%X\n", cl_ntoh16(lid));
4870
4871	memset(&context, 0, sizeof(context));
4872	memset(&req, 0, sizeof(req));
4873	memset(&user, 0, sizeof(user));
4874	memset(&record, 0, sizeof(record));
4875
4876	record.lid = lid;
4877
4878	context.p_osmt = p_osmt;
4879	user.comp_mask = IB_NR_COMPMASK_LID;
4880	user.attr_id = IB_MAD_ATTR_NODE_RECORD;
4881	user.attr_offset = cl_ntoh16((uint16_t) (sizeof(record) >> 3));
4882	user.p_attr = &record;
4883
4884	req.query_type = OSMV_QUERY_USER_DEFINED;
4885	req.timeout_ms = p_osmt->opt.transaction_timeout;
4886	req.retry_cnt = p_osmt->opt.retry_count;
4887	req.flags = OSM_SA_FLAGS_SYNC;
4888	req.query_context = &context;
4889	req.pfn_query_cb = osmtest_query_res_cb;
4890	req.p_query_input = &user;
4891	req.sm_key = 0;
4892
4893	status = osmv_query_sa(p_osmt->h_bind, &req);
4894
4895	if (status != IB_SUCCESS) {
4896		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0105: "
4897			"ib_query failed (%s)\n", ib_get_err_str(status));
4898		goto Exit;
4899	}
4900
4901	status = context.result.status;
4902
4903	if (status != IB_SUCCESS) {
4904		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0106: "
4905			"ib_query failed (%s)\n", ib_get_err_str(status));
4906
4907		if (status == IB_REMOTE_ERROR) {
4908			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
4909				"Remote error = %s\n",
4910				ib_get_mad_status_str(osm_madw_get_mad_ptr
4911						      (context.result.
4912						       p_result_madw)));
4913		}
4914		goto Exit;
4915	}
4916
4917	num_recs = context.result.result_cnt;
4918	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
4919		"Received %d nodes\n", num_recs);
4920
4921	for (i = 0; i < num_recs; i++) {
4922		p_rec =
4923		    osmv_get_query_node_rec(context.result.p_result_madw, i);
4924
4925		status = osmtest_validate_node_rec(p_osmt, p_rec);
4926		if (status != IB_SUCCESS) {
4927			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0107: "
4928				"osmtest_validate_node_data failed (%s)\n",
4929				ib_get_err_str(status));
4930			goto Exit;
4931		}
4932	}
4933
4934Exit:
4935	/*
4936	 * Return the IB query MAD to the pool as necessary.
4937	 */
4938	if (context.result.p_result_madw != NULL) {
4939		osm_mad_pool_put(&p_osmt->mad_pool,
4940				 context.result.p_result_madw);
4941		context.result.p_result_madw = NULL;
4942	}
4943
4944	OSM_LOG_EXIT(&p_osmt->log);
4945	return (status);
4946}
4947
4948/**********************************************************************
4949 **********************************************************************/
4950static ib_api_status_t
4951osmtest_validate_single_port_rec_lid(IN osmtest_t * const p_osmt,
4952				     IN port_t * const p_port)
4953{
4954	osmtest_req_context_t context;
4955
4956	const ib_portinfo_record_t *p_rec;
4957	cl_status_t status = IB_SUCCESS;
4958
4959	OSM_LOG_ENTER(&p_osmt->log);
4960
4961	memset(&context, 0, sizeof(context));
4962
4963	context.p_osmt = p_osmt;
4964	osmtest_get_port_rec_by_num(p_osmt,
4965				    p_port->rec.lid,
4966				    p_port->rec.port_num, &context);
4967	if (status != IB_SUCCESS) {
4968		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0108: "
4969			"ib_query failed (%s)\n", ib_get_err_str(status));
4970
4971		goto Exit;
4972	}
4973
4974	/* we should have got exactly one port */
4975	p_rec = osmv_get_query_portinfo_rec(context.result.p_result_madw, 0);
4976	status = osmtest_validate_port_rec(p_osmt, p_rec);
4977	if (status != IB_SUCCESS) {
4978		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0109: "
4979			"osmtest_validate_port_data failed (%s)\n",
4980			ib_get_err_str(status));
4981	}
4982
4983Exit:
4984	/*
4985	 * Return the IB query MAD to the pool as necessary.
4986	 */
4987	if (context.result.p_result_madw != NULL) {
4988		osm_mad_pool_put(&p_osmt->mad_pool,
4989				 context.result.p_result_madw);
4990		context.result.p_result_madw = NULL;
4991	}
4992
4993	OSM_LOG_EXIT(&p_osmt->log);
4994	return (status);
4995}
4996
4997/**********************************************************************
4998 **********************************************************************/
4999static ib_api_status_t
5000osmtest_validate_single_path_rec_guid_pair(IN osmtest_t * const p_osmt,
5001					   IN const osmv_guid_pair_t *
5002					   const p_pair)
5003{
5004	osmtest_req_context_t context;
5005	const ib_path_rec_t *p_rec;
5006	cl_status_t status = IB_SUCCESS;
5007	size_t num_recs;
5008	osmv_query_req_t req;
5009	uint32_t i;
5010	boolean_t got_error = FALSE;
5011
5012	OSM_LOG_ENTER(&p_osmt->log);
5013
5014	memset(&req, 0, sizeof(req));
5015	memset(&context, 0, sizeof(context));
5016
5017	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5018		"\n\t\t\t\tChecking src 0x%016" PRIx64
5019		" to dest 0x%016" PRIx64 "\n",
5020		cl_ntoh64(p_pair->src_guid), cl_ntoh64(p_pair->dest_guid));
5021
5022	context.p_osmt = p_osmt;
5023
5024	req.timeout_ms = p_osmt->opt.transaction_timeout;
5025	req.retry_cnt = p_osmt->opt.retry_count;
5026	req.flags = OSM_SA_FLAGS_SYNC;
5027	req.query_context = &context;
5028	req.pfn_query_cb = osmtest_query_res_cb;
5029
5030	req.query_type = OSMV_QUERY_PATH_REC_BY_PORT_GUIDS;
5031	req.p_query_input = p_pair;
5032	req.sm_key = 0;
5033
5034	status = osmv_query_sa(p_osmt->h_bind, &req);
5035	if (status != IB_SUCCESS) {
5036		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0110: "
5037			"ib_query failed (%s)\n", ib_get_err_str(status));
5038		goto Exit;
5039	}
5040
5041	status = context.result.status;
5042
5043	if (status != IB_SUCCESS) {
5044		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0111: "
5045			"ib_query failed (%s)\n", ib_get_err_str(status));
5046
5047		if (status == IB_REMOTE_ERROR) {
5048			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5049				"Remote error = %s\n",
5050				ib_get_mad_status_str(osm_madw_get_mad_ptr
5051						      (context.result.
5052						       p_result_madw)));
5053		}
5054		goto Exit;
5055	}
5056
5057	num_recs = context.result.result_cnt;
5058	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "%zu records\n", num_recs);
5059
5060	for (i = 0; i < num_recs; i++) {
5061		p_rec =
5062		    osmv_get_query_path_rec(context.result.p_result_madw, i);
5063
5064		/*
5065		 * Make sure the GUID values are correct
5066		 */
5067		if (p_rec->dgid.unicast.interface_id != p_pair->dest_guid) {
5068			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0112: "
5069				"Destination GUID mismatch\n"
5070				"\t\t\t\texpected 0x%016" PRIx64
5071				", received 0x%016" PRIx64 "\n",
5072				cl_ntoh64(p_pair->dest_guid),
5073				cl_ntoh64(p_rec->dgid.unicast.interface_id));
5074			got_error = TRUE;
5075		}
5076
5077		if (p_rec->sgid.unicast.interface_id != p_pair->src_guid) {
5078			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0113: "
5079				"Source GUID mismatch\n"
5080				"\t\t\t\texpected 0x%016" PRIx64
5081				", received 0x%016" PRIx64 ".\n",
5082				cl_ntoh64(p_pair->src_guid),
5083				cl_ntoh64(p_rec->sgid.unicast.interface_id));
5084			got_error = TRUE;
5085		}
5086
5087		status = osmtest_validate_path_rec(p_osmt, p_rec);
5088		if (status != IB_SUCCESS) {
5089			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0114: "
5090				"osmtest_validate_path_rec failed (%s)\n",
5091				ib_get_err_str(status));
5092			got_error = TRUE;
5093		}
5094		if (got_error || (status != IB_SUCCESS)) {
5095			osm_dump_path_record(&p_osmt->log, p_rec,
5096					     OSM_LOG_VERBOSE);
5097			if (status == IB_SUCCESS)
5098				status = IB_ERROR;
5099			goto Exit;
5100		}
5101	}
5102
5103Exit:
5104	/*
5105	 * Return the IB query MAD to the pool as necessary.
5106	 */
5107	if (context.result.p_result_madw != NULL) {
5108		osm_mad_pool_put(&p_osmt->mad_pool,
5109				 context.result.p_result_madw);
5110		context.result.p_result_madw = NULL;
5111	}
5112
5113	OSM_LOG_EXIT(&p_osmt->log);
5114	return (status);
5115}
5116
5117/**********************************************************************
5118 **********************************************************************/
5119static ib_api_status_t
5120osmtest_validate_single_path_recs(IN osmtest_t * const p_osmt)
5121{
5122	path_t *p_path;
5123	cl_status_t status = IB_SUCCESS;
5124	const cl_qmap_t *p_path_tbl;
5125/* We skip node to node path record validation since it might contains
5126   NONEXISTENT PATHS, i.e. when using UPDN */
5127	osmv_guid_pair_t guid_pair;
5128	uint16_t cnt;
5129
5130	OSM_LOG_ENTER(&p_osmt->log);
5131
5132	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5133		"Validating individual path record queries\n");
5134	p_path_tbl = &p_osmt->exp_subn.path_tbl;
5135
5136	osmtest_prepare_db(p_osmt);
5137
5138	/*
5139	 * Walk the list of all path records, and ask for each one
5140	 * specifically.  Make sure we get it.
5141	 */
5142	cnt = 0;
5143	p_path = (path_t *) cl_qmap_head(p_path_tbl);
5144	while (p_path != (path_t *) cl_qmap_end(p_path_tbl)) {
5145		status =
5146		    osmtest_validate_single_path_rec_lid_pair(p_osmt, p_path);
5147		if (status != IB_SUCCESS)
5148			goto Exit;
5149		cnt++;
5150		p_path = (path_t *) cl_qmap_next(&p_path->map_item);
5151	}
5152
5153	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5154		"Total of %u path records validated using LID based query\n",
5155		cnt);
5156
5157	status = osmtest_check_missing_paths(p_osmt);
5158	if (status != IB_SUCCESS) {
5159		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0115: "
5160			"osmtest_check_missing_paths failed (%s)\n",
5161			ib_get_err_str(status));
5162		goto Exit;
5163	}
5164
5165	/*
5166	 * Do the whole thing again with port GUID pairs.
5167	 * Note that multiple path records may be returned
5168	 * for each guid pair if LMC > 0.
5169	 */
5170	osmtest_prepare_db(p_osmt);
5171	cnt = 0;
5172	p_path = (path_t *) cl_qmap_head(p_path_tbl);
5173	while (p_path != (path_t *) cl_qmap_end(p_path_tbl)) {
5174		guid_pair.src_guid = p_path->rec.sgid.unicast.interface_id;
5175		guid_pair.dest_guid = p_path->rec.dgid.unicast.interface_id;
5176		status = osmtest_validate_single_path_rec_guid_pair(p_osmt,
5177								    &guid_pair);
5178		if (status != IB_SUCCESS)
5179			goto Exit;
5180		cnt++;
5181		p_path = (path_t *) cl_qmap_next(&p_path->map_item);
5182	}
5183
5184	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5185		"Total of %u path records validated using GUID based query\n",
5186		cnt);
5187
5188	status = osmtest_check_missing_paths(p_osmt);
5189	if (status != IB_SUCCESS) {
5190		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0116: "
5191			"osmtest_check_missing_paths failed (%s)\n",
5192			ib_get_err_str(status));
5193		goto Exit;
5194	}
5195
5196Exit:
5197	OSM_LOG_EXIT(&p_osmt->log);
5198	return (status);
5199}
5200
5201/**********************************************************************
5202 **********************************************************************/
5203static ib_api_status_t
5204osmtest_validate_single_node_recs(IN osmtest_t * const p_osmt)
5205{
5206	node_t *p_node;
5207	cl_status_t status = IB_SUCCESS;
5208	const cl_qmap_t *p_node_lid_tbl;
5209	uint16_t cnt = 0;
5210
5211	OSM_LOG_ENTER(&p_osmt->log);
5212
5213	p_node_lid_tbl = &p_osmt->exp_subn.node_lid_tbl;
5214
5215	osmtest_prepare_db(p_osmt);
5216
5217	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5218		"Validating individual node record queries\n");
5219
5220	/*
5221	 * Walk the list of all node records, and ask for each one
5222	 * specifically.  Make sure we get it.
5223	 */
5224	p_node = (node_t *) cl_qmap_head(p_node_lid_tbl);
5225	while (p_node != (node_t *) cl_qmap_end(p_node_lid_tbl)) {
5226		status = osmtest_validate_single_node_rec_lid(p_osmt,
5227							      (ib_net16_t)
5228							      cl_qmap_key((cl_map_item_t *) p_node), p_node);
5229		if (status != IB_SUCCESS) {
5230			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 011A: "
5231				"osmtest_validate_single_node_rec_lid (%s)\n",
5232				ib_get_err_str(status));
5233			goto Exit;
5234		}
5235		cnt++;
5236		p_node = (node_t *) cl_qmap_next(&p_node->map_item);
5237	}
5238
5239	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5240		"Total of %u node records validated\n", cnt);
5241
5242	status = osmtest_check_missing_nodes(p_osmt);
5243	if (status != IB_SUCCESS) {
5244		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0117: "
5245			"osmtest_check_missing_nodes (%s)\n",
5246			ib_get_err_str(status));
5247		goto Exit;
5248	}
5249
5250Exit:
5251	OSM_LOG_EXIT(&p_osmt->log);
5252	return (status);
5253}
5254
5255/**********************************************************************
5256 **********************************************************************/
5257static ib_api_status_t
5258osmtest_validate_single_port_recs(IN osmtest_t * const p_osmt)
5259{
5260	port_t *p_port;
5261	cl_status_t status = IB_SUCCESS;
5262	const cl_qmap_t *p_port_key_tbl;
5263	uint16_t cnt = 0;
5264
5265	OSM_LOG_ENTER(&p_osmt->log);
5266
5267	p_port_key_tbl = &p_osmt->exp_subn.port_key_tbl;
5268
5269	osmtest_prepare_db(p_osmt);
5270
5271	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5272		"Validating individual port record queries\n");
5273
5274	/*
5275	 * Walk the list of all port records, and ask for each one
5276	 * specifically.  Make sure we get it.
5277	 */
5278	p_port = (port_t *) cl_qmap_head(p_port_key_tbl);
5279	while (p_port != (port_t *) cl_qmap_end(p_port_key_tbl)) {
5280		status = osmtest_validate_single_port_rec_lid(p_osmt, p_port);
5281		if (status != IB_SUCCESS) {
5282			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 011B: "
5283				"osmtest_validate_single_port_rec_lid (%s)\n",
5284				ib_get_err_str(status));
5285			goto Exit;
5286		}
5287		cnt++;
5288		p_port = (port_t *) cl_qmap_next(&p_port->map_item);
5289	}
5290
5291	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
5292		"Total of %u port records validated\n", cnt);
5293
5294	status = osmtest_check_missing_ports(p_osmt);
5295	if (status != IB_SUCCESS) {
5296		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0118: "
5297			"osmtest_check_missing_paths failed (%s)\n",
5298			ib_get_err_str(status));
5299		goto Exit;
5300	}
5301
5302Exit:
5303	OSM_LOG_EXIT(&p_osmt->log);
5304	return (status);
5305}
5306
5307/**********************************************************************
5308 **********************************************************************/
5309static ib_api_status_t osmtest_validate_against_db(IN osmtest_t * const p_osmt)
5310{
5311	ib_api_status_t status = IB_SUCCESS;
5312	ib_gid_t portgid, mgid;
5313	osmtest_sm_info_rec_t sm_info_rec_opt;
5314	osmtest_inform_info_t inform_info_opt;
5315	osmtest_inform_info_rec_t inform_info_rec_opt;
5316#ifdef VENDOR_RMPP_SUPPORT
5317	ib_net64_t sm_key;
5318	ib_net16_t test_lid;
5319	uint8_t lmc;
5320	osmtest_req_context_t context;
5321#ifdef DUAL_SIDED_RMPP
5322	osmv_multipath_req_t request;
5323#endif
5324	uint8_t i;
5325#endif
5326
5327	OSM_LOG_ENTER(&p_osmt->log);
5328
5329#ifdef VENDOR_RMPP_SUPPORT
5330	status = osmtest_validate_all_node_recs(p_osmt);
5331	if (status != IB_SUCCESS)
5332		goto Exit;
5333#endif
5334
5335	status = osmtest_validate_single_node_recs(p_osmt);
5336	if (status != IB_SUCCESS)
5337		goto Exit;
5338
5339	/* Exercise SA PathRecord multicast destination code */
5340	memset(&context, 0, sizeof(context));
5341	ib_gid_set_default(&portgid, portguid);
5342	/* Set IPoIB broadcast MGID */
5343	mgid.unicast.prefix = CL_HTON64(0xff12401bffff0000ULL);
5344	mgid.unicast.interface_id = CL_HTON64(0x00000000ffffffffULL);
5345	/* Can't check status as don't know whether port is running IPoIB */
5346	osmtest_get_path_rec_by_gid_pair(p_osmt, portgid, mgid, &context);
5347
5348	/* Other link local unicast PathRecord */
5349	memset(&context, 0, sizeof(context));
5350	ib_gid_set_default(&portgid, portguid);
5351	ib_gid_set_default(&mgid, portguid);
5352	mgid.raw[7] = 0xff;	/* not default GID prefix */
5353	/* Can't check status as don't know whether ??? */
5354	osmtest_get_path_rec_by_gid_pair(p_osmt, portgid, mgid, &context);
5355
5356	/* Off subnet (site local) unicast PathRecord */
5357	memset(&context, 0, sizeof(context));
5358	ib_gid_set_default(&portgid, portguid);
5359	ib_gid_set_default(&mgid, portguid);
5360	mgid.raw[1] = 0xc0;	/* site local */
5361	/* Can't check status as don't know whether ??? */
5362	osmtest_get_path_rec_by_gid_pair(p_osmt, portgid, mgid, &context);
5363
5364	/* More than link local scope multicast PathRecord */
5365	memset(&context, 0, sizeof(context));
5366	ib_gid_set_default(&portgid, portguid);
5367	/* Set IPoIB broadcast MGID */
5368	mgid.unicast.prefix = CL_HTON64(0xff15401bffff0000ULL);	/* site local */
5369	mgid.unicast.interface_id = CL_HTON64(0x00000000ffffffffULL);
5370	/* Can't check status as don't know whether port is running IPoIB */
5371	osmtest_get_path_rec_by_gid_pair(p_osmt, portgid, mgid, &context);
5372
5373#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
5374	memset(&context, 0, sizeof(context));
5375	memset(&request, 0, sizeof(request));
5376	request.comp_mask =
5377	    IB_MPR_COMPMASK_SGIDCOUNT | IB_MPR_COMPMASK_DGIDCOUNT;
5378	request.sgid_count = 1;
5379	request.dgid_count = 1;
5380	ib_gid_set_default(&request.gids[0], portguid);
5381	ib_gid_set_default(&request.gids[1], portguid);
5382	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5383	if (status != IB_SUCCESS)
5384		goto Exit;
5385
5386	memset(&context, 0, sizeof(context));
5387	memset(&request, 0, sizeof(request));
5388
5389	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
5390	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5391	if (status != IB_SUCCESS) {
5392		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5393			"Got error %s\n", ib_get_err_str(status));
5394	}
5395	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
5396
5397	if (status == IB_SUCCESS) {
5398		status = IB_ERROR;
5399		goto Exit;
5400	}
5401
5402	memset(&context, 0, sizeof(context));
5403	memset(&request, 0, sizeof(request));
5404	request.comp_mask = IB_MPR_COMPMASK_SGIDCOUNT;
5405	request.sgid_count = 1;
5406	ib_gid_set_default(&request.gids[0], portguid);
5407
5408	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
5409	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5410	if (status != IB_SUCCESS) {
5411		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5412			"Got error %s\n", ib_get_err_str(status));
5413	}
5414	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
5415
5416	if (status == IB_SUCCESS) {
5417		status = IB_ERROR;
5418		goto Exit;
5419	}
5420
5421	memset(&context, 0, sizeof(context));
5422	memset(&request, 0, sizeof(request));
5423	request.comp_mask =
5424	    IB_MPR_COMPMASK_SGIDCOUNT | IB_MPR_COMPMASK_DGIDCOUNT;
5425	request.sgid_count = 1;
5426	request.dgid_count = 1;
5427	ib_gid_set_default(&request.gids[0], portguid);
5428	/* Set IPoIB broadcast MGID as DGID */
5429	request.gids[1].unicast.prefix = CL_HTON64(0xff12401bffff0000ULL);
5430	request.gids[1].unicast.interface_id = CL_HTON64(0x00000000ffffffffULL);
5431
5432	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
5433	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5434	if (status != IB_SUCCESS) {
5435		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5436			"Got error %s\n", ib_get_err_str(status));
5437	}
5438	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
5439
5440	if (status == IB_SUCCESS) {
5441		status = IB_ERROR;
5442		goto Exit;
5443	}
5444
5445	memset(&context, 0, sizeof(context));
5446	request.comp_mask =
5447	    IB_MPR_COMPMASK_SGIDCOUNT | IB_MPR_COMPMASK_DGIDCOUNT;
5448	request.sgid_count = 1;
5449	request.dgid_count = 1;
5450	/* Set IPoIB broadcast MGID as SGID */
5451	request.gids[0].unicast.prefix = CL_HTON64(0xff12401bffff0000ULL);
5452	request.gids[0].unicast.interface_id = CL_HTON64(0x00000000ffffffffULL);
5453	ib_gid_set_default(&request.gids[1], portguid);
5454
5455	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
5456	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5457	if (status != IB_SUCCESS) {
5458		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5459			"Got error %s\n", ib_get_err_str(status));
5460	}
5461	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
5462
5463	if (status == IB_SUCCESS) {
5464		status = IB_ERROR;
5465		goto Exit;
5466	}
5467
5468	memset(&context, 0, sizeof(context));
5469	memset(&request, 0, sizeof(request));
5470	request.comp_mask =
5471	    IB_MPR_COMPMASK_SGIDCOUNT | IB_MPR_COMPMASK_DGIDCOUNT |
5472	    IB_MPR_COMPMASK_NUMBPATH;
5473	request.sgid_count = 2;
5474	request.dgid_count = 2;
5475	request.num_path = 2;
5476	ib_gid_set_default(&request.gids[0], portguid);
5477	ib_gid_set_default(&request.gids[1], portguid);
5478	ib_gid_set_default(&request.gids[2], portguid);
5479	ib_gid_set_default(&request.gids[3], portguid);
5480	status = osmtest_get_multipath_rec(p_osmt, &request, &context);
5481	if (status != IB_SUCCESS)
5482		goto Exit;
5483#endif
5484
5485#ifdef VENDOR_RMPP_SUPPORT
5486	/* GUIDInfoRecords */
5487	status = osmtest_validate_all_guidinfo_recs(p_osmt);
5488	if (status != IB_SUCCESS)
5489		goto Exit;
5490
5491	/* If LMC > 0, test non base LID SA PortInfoRecord request */
5492	status =
5493	    osmtest_get_local_port_lmc(p_osmt, p_osmt->local_port.lid, &lmc);
5494	if (status != IB_SUCCESS)
5495		goto Exit;
5496
5497	if (lmc != 0) {
5498		status =
5499		    osmtest_get_local_port_lmc(p_osmt,
5500					       p_osmt->local_port.lid + 1,
5501					       NULL);
5502		if (status != IB_SUCCESS)
5503			goto Exit;
5504	}
5505
5506	status = osmtest_get_local_port_lmc(p_osmt, 0xffff, NULL);
5507	if (status != IB_SUCCESS)
5508		goto Exit;
5509
5510	test_lid = cl_ntoh16(p_osmt->local_port.lid);
5511
5512	/* More GUIDInfo Record tests */
5513	memset(&context, 0, sizeof(context));
5514	status = osmtest_get_guidinfo_rec_by_lid(p_osmt, test_lid, &context);
5515	if (status != IB_SUCCESS)
5516		goto Exit;
5517
5518	memset(&context, 0, sizeof(context));
5519	status = osmtest_get_guidinfo_rec_by_lid(p_osmt, 0xffff, &context);
5520	if (status != IB_SUCCESS)
5521		goto Exit;
5522
5523	/* Some PKeyTable Record tests */
5524	sm_key = OSM_DEFAULT_SM_KEY;
5525	memset(&context, 0, sizeof(context));
5526	status =
5527	    osmtest_get_pkeytbl_rec_by_lid(p_osmt, test_lid, sm_key, &context);
5528	if (status != IB_SUCCESS)
5529		goto Exit;
5530
5531	memset(&context, 0, sizeof(context));
5532
5533	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
5534	status = osmtest_get_pkeytbl_rec_by_lid(p_osmt, test_lid, 0, &context);
5535	if (status != IB_SUCCESS) {
5536		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5537			"Got error %s\n", ib_get_err_str(status));
5538	}
5539	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
5540
5541	if (status == IB_SUCCESS) {
5542		status = IB_ERROR;
5543		goto Exit;
5544	}
5545
5546	memset(&context, 0, sizeof(context));
5547	status =
5548	    osmtest_get_pkeytbl_rec_by_lid(p_osmt, 0xffff, sm_key, &context);
5549	if (status != IB_SUCCESS)
5550		goto Exit;
5551
5552	/* SwitchInfo Record tests */
5553	memset(&context, 0, sizeof(context));
5554	status = osmtest_get_sw_info_rec_by_lid(p_osmt, 0, &context);
5555	if (status != IB_SUCCESS)
5556		goto Exit;
5557
5558	memset(&context, 0, sizeof(context));
5559	status = osmtest_get_sw_info_rec_by_lid(p_osmt, test_lid, &context);
5560	if (status != IB_SUCCESS)
5561		goto Exit;
5562
5563	/* LFT Record tests */
5564	memset(&context, 0, sizeof(context));
5565	status = osmtest_get_lft_rec_by_lid(p_osmt, 0, &context);
5566	if (status != IB_SUCCESS)
5567		goto Exit;
5568
5569	memset(&context, 0, sizeof(context));
5570	status = osmtest_get_lft_rec_by_lid(p_osmt, test_lid, &context);
5571	if (status != IB_SUCCESS)
5572		goto Exit;
5573
5574	/* MFT Record tests */
5575	memset(&context, 0, sizeof(context));
5576	status = osmtest_get_mft_rec_by_lid(p_osmt, 0, &context);
5577	if (status != IB_SUCCESS)
5578		goto Exit;
5579
5580	memset(&context, 0, sizeof(context));
5581	status = osmtest_get_mft_rec_by_lid(p_osmt, test_lid, &context);
5582	if (status != IB_SUCCESS)
5583		goto Exit;
5584
5585	/* Some LinkRecord tests */
5586	/* FromLID */
5587	memset(&context, 0, sizeof(context));
5588	status = osmtest_get_link_rec_by_lid(p_osmt, test_lid, 0, &context);
5589	if (status != IB_SUCCESS)
5590		goto Exit;
5591
5592	/* ToLID */
5593	memset(&context, 0, sizeof(context));
5594	status = osmtest_get_link_rec_by_lid(p_osmt, 0, test_lid, &context);
5595	if (status != IB_SUCCESS)
5596		goto Exit;
5597
5598	/* FromLID & ToLID */
5599	memset(&context, 0, sizeof(context));
5600	status =
5601	    osmtest_get_link_rec_by_lid(p_osmt, test_lid, test_lid, &context);
5602	if (status != IB_SUCCESS)
5603		goto Exit;
5604
5605	/* NodeRecord test */
5606	memset(&context, 0, sizeof(context));
5607	status = osmtest_get_node_rec_by_lid(p_osmt, 0xffff, &context);
5608	if (status != IB_SUCCESS)
5609		goto Exit;
5610
5611	/* SMInfoRecord tests */
5612	memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5613	memset(&context, 0, sizeof(context));
5614	status = osmtest_sminfo_record_request(p_osmt, IB_MAD_METHOD_SET,
5615					       &sm_info_rec_opt, &context);
5616	if (status == IB_SUCCESS) {
5617		status = IB_ERROR;
5618		goto Exit;
5619	} else {
5620		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "IS EXPECTED ERROR ^^^^\n");
5621	}
5622
5623	memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5624	memset(&context, 0, sizeof(context));
5625	status = osmtest_sminfo_record_request(p_osmt, IB_MAD_METHOD_GETTABLE,
5626					       &sm_info_rec_opt, &context);
5627	if (status != IB_SUCCESS)
5628		goto Exit;
5629
5630	memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5631	sm_info_rec_opt.lid = test_lid;	/* local LID */
5632	memset(&context, 0, sizeof(context));
5633	status = osmtest_sminfo_record_request(p_osmt, IB_MAD_METHOD_GETTABLE,
5634					       &sm_info_rec_opt, &context);
5635	if (status != IB_SUCCESS)
5636		goto Exit;
5637
5638	if (portguid != 0) {
5639		memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5640		sm_info_rec_opt.sm_guid = portguid;	/* local GUID */
5641		memset(&context, 0, sizeof(context));
5642		status =
5643		    osmtest_sminfo_record_request(p_osmt,
5644						  IB_MAD_METHOD_GETTABLE,
5645						  &sm_info_rec_opt, &context);
5646		if (status != IB_SUCCESS)
5647			goto Exit;
5648	}
5649
5650	for (i = 1; i < 16; i++) {
5651		memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5652		sm_info_rec_opt.priority = i;
5653		memset(&context, 0, sizeof(context));
5654		status =
5655		    osmtest_sminfo_record_request(p_osmt,
5656						  IB_MAD_METHOD_GETTABLE,
5657						  &sm_info_rec_opt, &context);
5658		if (status != IB_SUCCESS)
5659			goto Exit;
5660	}
5661
5662	for (i = 1; i < 4; i++) {
5663		memset(&sm_info_rec_opt, 0, sizeof(sm_info_rec_opt));
5664		sm_info_rec_opt.sm_state = i;
5665		memset(&context, 0, sizeof(context));
5666		status =
5667		    osmtest_sminfo_record_request(p_osmt,
5668						  IB_MAD_METHOD_GETTABLE,
5669						  &sm_info_rec_opt, &context);
5670		if (status != IB_SUCCESS)
5671			goto Exit;
5672	}
5673
5674	/* InformInfoRecord tests */
5675	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5676		"Sending a BAD - Set Unsubscribe request\n");
5677	memset(&inform_info_opt, 0, sizeof(inform_info_opt));
5678	memset(&inform_info_rec_opt, 0, sizeof(inform_info_rec_opt));
5679	memset(&context, 0, sizeof(context));
5680	status =
5681	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5682				       IB_MAD_METHOD_SET, &inform_info_rec_opt,
5683				       &context);
5684	if (status == IB_SUCCESS) {
5685		status = IB_ERROR;
5686		goto Exit;
5687	} else {
5688		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "InformInfoRecord "
5689			"IS EXPECTED ERROR ^^^^\n");
5690	}
5691
5692	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5693		"Sending a Good - Empty GetTable request\n");
5694	memset(&context, 0, sizeof(context));
5695	status =
5696	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5697				       IB_MAD_METHOD_GETTABLE,
5698				       &inform_info_rec_opt, &context);
5699	if (status != IB_SUCCESS)
5700		goto Exit;
5701
5702	/* InformInfo tests */
5703	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5704		"Sending a BAD - Empty Get request "
5705		"(should fail with NO_RECORDS)\n");
5706	memset(&context, 0, sizeof(context));
5707	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5708					    IB_MAD_METHOD_GET, &inform_info_opt,
5709					    &context);
5710	if (status == IB_SUCCESS) {
5711		status = IB_ERROR;
5712		goto Exit;
5713	} else {
5714		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "InformInfo "
5715			"IS EXPECTED ERROR ^^^^\n");
5716	}
5717
5718	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5719		"Sending a BAD - Set Unsubscribe request\n");
5720	memset(&context, 0, sizeof(context));
5721	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5722					    IB_MAD_METHOD_SET, &inform_info_opt,
5723					    &context);
5724	if (status == IB_SUCCESS) {
5725		status = IB_ERROR;
5726		goto Exit;
5727	} else {
5728		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "InformInfo UnSubscribe "
5729			"IS EXPECTED ERROR ^^^^\n");
5730	}
5731
5732	/* Now subscribe */
5733	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5734		"Sending a Good - Set Subscribe request\n");
5735	inform_info_opt.subscribe = TRUE;
5736	memset(&context, 0, sizeof(context));
5737	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5738					    IB_MAD_METHOD_SET, &inform_info_opt,
5739					    &context);
5740	if (status != IB_SUCCESS)
5741		goto Exit;
5742
5743	/* Now unsubscribe (QPN needs to be 1 to work) */
5744	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5745		"Sending a Good - Set Unsubscribe request\n");
5746	inform_info_opt.subscribe = FALSE;
5747	inform_info_opt.qpn = 1;
5748	memset(&context, 0, sizeof(context));
5749	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5750					    IB_MAD_METHOD_SET, &inform_info_opt,
5751					    &context);
5752	if (status != IB_SUCCESS)
5753		goto Exit;
5754
5755	/* Now subscribe again */
5756	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5757		"Sending a Good - Set Subscribe request\n");
5758	inform_info_opt.subscribe = TRUE;
5759	inform_info_opt.qpn = 1;
5760	memset(&context, 0, sizeof(context));
5761	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5762					    IB_MAD_METHOD_SET, &inform_info_opt,
5763					    &context);
5764	if (status != IB_SUCCESS)
5765		goto Exit;
5766
5767	/* Subscribe over existing subscription */
5768	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5769		"Sending a Good - Set Subscribe (again) request\n");
5770	inform_info_opt.qpn = 0;
5771	memset(&context, 0, sizeof(context));
5772	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5773					    IB_MAD_METHOD_SET, &inform_info_opt,
5774					    &context);
5775	if (status != IB_SUCCESS)
5776		goto Exit;
5777
5778	/* More InformInfoRecord tests */
5779	/* RID lookup (with currently invalid enum) */
5780	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5781		"Sending a Good - GetTable by GID\n");
5782	ib_gid_set_default(&inform_info_rec_opt.subscriber_gid,
5783			   p_osmt->local_port.port_guid);
5784	inform_info_rec_opt.subscriber_enum = 1;
5785	memset(&context, 0, sizeof(context));
5786	status =
5787	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5788				       IB_MAD_METHOD_GETTABLE,
5789				       &inform_info_rec_opt, &context);
5790	if (status != IB_SUCCESS)
5791		goto Exit;
5792
5793	/* Enum lookup */
5794	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5795		"Sending a Good - GetTable (subscriber_enum == 0) request\n");
5796	inform_info_rec_opt.subscriber_enum = 0;
5797	memset(&context, 0, sizeof(context));
5798	status =
5799	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5800				       IB_MAD_METHOD_GETTABLE,
5801				       &inform_info_rec_opt, &context);
5802	if (status != IB_SUCCESS)
5803		goto Exit;
5804
5805	/* Get all InformInfoRecords */
5806	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5807		"Sending a Good - GetTable (ALL records) request\n");
5808	memset(&inform_info_rec_opt, 0, sizeof(inform_info_rec_opt));
5809	memset(&context, 0, sizeof(context));
5810	status =
5811	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5812				       IB_MAD_METHOD_GETTABLE,
5813				       &inform_info_rec_opt, &context);
5814	if (status != IB_SUCCESS)
5815		goto Exit;
5816
5817	/* Another subscription */
5818	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5819		"Sending another Good - Set Subscribe (again) request\n");
5820	inform_info_opt.qpn = 0;
5821	inform_info_opt.trap = 0x1234;
5822	memset(&context, 0, sizeof(context));
5823	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5824					    IB_MAD_METHOD_SET, &inform_info_opt,
5825					    &context);
5826	if (status != IB_SUCCESS)
5827		goto Exit;
5828
5829	/* Get all InformInfoRecords again */
5830	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5831		"Sending a Good - GetTable (ALL records) request\n");
5832	memset(&inform_info_rec_opt, 0, sizeof(inform_info_rec_opt));
5833	memset(&context, 0, sizeof(context));
5834	status =
5835	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5836				       IB_MAD_METHOD_GETTABLE,
5837				       &inform_info_rec_opt, &context);
5838	if (status != IB_SUCCESS)
5839		goto Exit;
5840
5841	/* Cleanup subscriptions before further testing */
5842	/* Does order of deletion matter ? Test this !!! */
5843	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo "
5844		"Sending a Good - Set (cleanup) request\n");
5845	inform_info_opt.subscribe = FALSE;
5846	inform_info_opt.qpn = 1;
5847	memset(&context, 0, sizeof(context));
5848	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5849					    IB_MAD_METHOD_SET,
5850					    &inform_info_opt, &context);
5851	if (status != IB_SUCCESS)
5852		goto Exit;
5853
5854	/* Get all InformInfoRecords again */
5855	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5856		"Sending a Good - GetTable (ALL records) request\n");
5857	memset(&inform_info_rec_opt, 0, sizeof(inform_info_rec_opt));
5858	memset(&context, 0, sizeof(context));
5859	status =
5860	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5861				       IB_MAD_METHOD_GETTABLE,
5862				       &inform_info_rec_opt, &context);
5863	if (status != IB_SUCCESS)
5864		goto Exit;
5865
5866	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfo"
5867		"Sending a Good - Set (cleanup) request\n");
5868	inform_info_opt.subscribe = FALSE;
5869	inform_info_opt.qpn = 1;
5870	inform_info_opt.trap = 0;
5871	memset(&context, 0, sizeof(context));
5872	status = osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO,
5873					    IB_MAD_METHOD_SET,
5874					    &inform_info_opt, &context);
5875	if (status != IB_SUCCESS)
5876		goto Exit;
5877
5878	/* Get all InformInfoRecords a final time */
5879	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "InformInfoRecord "
5880		"Sending a Good - GetTable (ALL records) request\n");
5881	memset(&inform_info_rec_opt, 0, sizeof(inform_info_rec_opt));
5882	memset(&context, 0, sizeof(context));
5883	status =
5884	    osmtest_informinfo_request(p_osmt, IB_MAD_ATTR_INFORM_INFO_RECORD,
5885				       IB_MAD_METHOD_GETTABLE,
5886				       &inform_info_rec_opt, &context);
5887	if (status != IB_SUCCESS)
5888		goto Exit;
5889
5890	if (lmc != 0) {
5891		test_lid = cl_ntoh16(p_osmt->local_port.lid + 1);
5892
5893		/* Another GUIDInfo Record test */
5894		memset(&context, 0, sizeof(context));
5895		status =
5896		    osmtest_get_guidinfo_rec_by_lid(p_osmt, test_lid, &context);
5897		if (status != IB_SUCCESS)
5898			goto Exit;
5899
5900		/* Another PKeyTable Record test */
5901		memset(&context, 0, sizeof(context));
5902		status =
5903		    osmtest_get_pkeytbl_rec_by_lid(p_osmt, test_lid, sm_key,
5904						   &context);
5905		if (status != IB_SUCCESS)
5906			goto Exit;
5907
5908		/* Another SwitchInfo Record test */
5909		memset(&context, 0, sizeof(context));
5910		status =
5911		    osmtest_get_sw_info_rec_by_lid(p_osmt, test_lid, &context);
5912		if (status != IB_SUCCESS)
5913			goto Exit;
5914
5915		/* Another LFT Record test */
5916		memset(&context, 0, sizeof(context));
5917		status = osmtest_get_lft_rec_by_lid(p_osmt, test_lid, &context);
5918		if (status != IB_SUCCESS)
5919			goto Exit;
5920
5921		/* Another MFT Record test */
5922		memset(&context, 0, sizeof(context));
5923		status = osmtest_get_mft_rec_by_lid(p_osmt, test_lid, &context);
5924		if (status != IB_SUCCESS)
5925			goto Exit;
5926
5927		/* More LinkRecord tests */
5928		/* FromLID */
5929		memset(&context, 0, sizeof(context));
5930		status =
5931		    osmtest_get_link_rec_by_lid(p_osmt, test_lid, 0, &context);
5932		if (status != IB_SUCCESS)
5933			goto Exit;
5934
5935		/* ToLID */
5936		memset(&context, 0, sizeof(context));
5937		status =
5938		    osmtest_get_link_rec_by_lid(p_osmt, 0, test_lid, &context);
5939		if (status != IB_SUCCESS)
5940			goto Exit;
5941
5942		/* Another NodeRecord test */
5943		memset(&context, 0, sizeof(context));
5944		status =
5945		    osmtest_get_node_rec_by_lid(p_osmt, test_lid, &context);
5946		if (status != IB_SUCCESS)
5947			goto Exit;
5948	}
5949
5950	/* PathRecords */
5951	if (!p_osmt->opt.ignore_path_records) {
5952		status = osmtest_validate_all_path_recs(p_osmt);
5953		if (status != IB_SUCCESS)
5954			goto Exit;
5955
5956		if (lmc != 0) {
5957			memset(&context, 0, sizeof(context));
5958			status =
5959			    osmtest_get_path_rec_by_lid_pair(p_osmt, test_lid,
5960							     test_lid,
5961							     &context);
5962			if (status != IB_SUCCESS)
5963				goto Exit;
5964
5965			memset(&context, 0, sizeof(context));
5966			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5967				EXPECTING_ERRORS_START "\n");
5968			status =
5969			    osmtest_get_path_rec_by_lid_pair(p_osmt, 0xffff,
5970							     0xffff, &context);
5971			if (status != IB_SUCCESS) {
5972				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5973					"Got error %s\n",
5974					ib_get_err_str(status));
5975			}
5976			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5977				EXPECTING_ERRORS_END "\n");
5978
5979			if (status == IB_SUCCESS) {
5980				status = IB_ERROR;
5981				goto Exit;
5982			}
5983
5984			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5985				EXPECTING_ERRORS_START "\n");
5986
5987			status =
5988			    osmtest_get_path_rec_by_lid_pair(p_osmt, test_lid,
5989							     0xffff, &context);
5990			if (status != IB_SUCCESS) {
5991				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5992					"Got error %s\n",
5993					ib_get_err_str(status));
5994			}
5995			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
5996				EXPECTING_ERRORS_END "\n");
5997
5998			if (status == IB_SUCCESS) {
5999				status = IB_ERROR;
6000				goto Exit;
6001			}
6002		}
6003	}
6004#endif
6005
6006	status = osmtest_validate_single_port_recs(p_osmt);
6007	if (status != IB_SUCCESS)
6008		goto Exit;
6009
6010	if (!p_osmt->opt.ignore_path_records) {
6011		status = osmtest_validate_single_path_recs(p_osmt);
6012		if (status != IB_SUCCESS)
6013			goto Exit;
6014	}
6015
6016Exit:
6017	OSM_LOG_EXIT(&p_osmt->log);
6018	return (status);
6019}
6020
6021/**********************************************************************
6022 **********************************************************************/
6023static const osmtest_token_t *str_get_token(IN char *const p_str)
6024{
6025	const osmtest_token_t *p_tok;
6026	uint32_t index = 0;
6027
6028	p_tok = &token_array[index];
6029
6030	while (p_tok->val != OSMTEST_TOKEN_UNKNOWN) {
6031		if (strnicmp(p_str, p_tok->str, p_tok->str_size) == 0)
6032			return (p_tok);
6033
6034		p_tok = &token_array[++index];
6035	}
6036
6037	return (NULL);
6038}
6039
6040/**********************************************************************
6041   Returns true if not whitespace character encountered before EOL.
6042**********************************************************************/
6043static boolean_t
6044str_skip_white(IN char line[], IN OUT uint32_t * const p_offset)
6045{
6046	while (((line[*p_offset] == '\t') ||
6047		(line[*p_offset] == ' ')) &&
6048	       (line[*p_offset] != '\n') && (line[*p_offset] != '\0')) {
6049		++*p_offset;
6050	}
6051
6052	if ((line[*p_offset] == '\n') || (line[*p_offset] == '\0'))
6053		return (FALSE);
6054	else
6055		return (TRUE);
6056}
6057
6058/**********************************************************************
6059   Returns true if not whitespace character encountered before EOL.
6060**********************************************************************/
6061static void str_skip_token(IN char line[], IN OUT uint32_t * const p_offset)
6062{
6063	while ((line[*p_offset] != '\t') &&
6064	       (line[*p_offset] != ' ') && (line[*p_offset] != '\0')) {
6065		++*p_offset;
6066	}
6067}
6068
6069/**********************************************************************
6070 **********************************************************************/
6071static ib_api_status_t
6072osmtest_parse_node(IN osmtest_t * const p_osmt,
6073		   IN FILE * const fh, IN OUT uint32_t * const p_line_num)
6074{
6075	ib_api_status_t status = IB_SUCCESS;
6076	uint32_t offset;
6077	char line[OSMTEST_MAX_LINE_LEN];
6078	boolean_t done = FALSE;
6079	node_t *p_node;
6080	node_t *p_guid_node;
6081	const osmtest_token_t *p_tok;
6082
6083	OSM_LOG_ENTER(&p_osmt->log);
6084
6085	p_node = node_new();
6086	CL_ASSERT(p_node != NULL);
6087
6088	/*
6089	 * Parse the inventory file and create the database.
6090	 */
6091	while (!done) {
6092		if (fgets(line, OSMTEST_MAX_LINE_LEN, fh) == NULL) {
6093			/*
6094			 * End of file in the middle of a definition.
6095			 */
6096			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0119: "
6097				"Unexpected end of file\n");
6098			status = IB_ERROR;
6099			goto Exit;
6100		}
6101
6102		++*p_line_num;
6103
6104		/*
6105		 * Skip whitespace
6106		 */
6107		offset = 0;
6108		if (!str_skip_white(line, &offset))
6109			continue;	/* whole line was whitespace */
6110
6111		p_tok = str_get_token(&line[offset]);
6112		if (p_tok == NULL) {
6113			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0120: "
6114				"Ignoring line %u with unknown token: %s\n",
6115				*p_line_num, &line[offset]);
6116			continue;
6117		}
6118
6119		OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6120			"Found '%s' (line %u)\n", p_tok->str, *p_line_num);
6121
6122		str_skip_token(line, &offset);
6123
6124		switch (p_tok->val) {
6125		case OSMTEST_TOKEN_COMMENT:
6126			break;
6127
6128		case OSMTEST_TOKEN_LID:
6129			p_node->comp.lid = 0xFFFF;
6130			p_node->rec.lid =
6131			    cl_hton16((uint16_t)
6132				      strtoul(&line[offset], NULL, 0));
6133			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "lid = 0x%X\n",
6134				cl_ntoh16(p_node->rec.lid));
6135			break;
6136
6137		case OSMTEST_TOKEN_BASE_VERSION:
6138			p_node->comp.node_info.base_version = 0xFF;
6139			p_node->rec.node_info.base_version =
6140			    (uint8_t) strtoul(&line[offset], NULL, 0);
6141			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6142				"base_version = 0x%X\n",
6143				p_node->rec.node_info.base_version);
6144			break;
6145
6146		case OSMTEST_TOKEN_CLASS_VERSION:
6147			p_node->comp.node_info.class_version = 0xFF;
6148			p_node->rec.node_info.class_version =
6149			    (uint8_t) strtoul(&line[offset], NULL, 0);
6150			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6151				"class_version = 0x%X\n",
6152				p_node->rec.node_info.class_version);
6153			break;
6154
6155		case OSMTEST_TOKEN_NODE_TYPE:
6156			p_node->comp.node_info.node_type = 0xFF;
6157			p_node->rec.node_info.node_type =
6158			    (uint8_t) strtoul(&line[offset], NULL, 0);
6159			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6160				"node_type = 0x%X\n",
6161				p_node->rec.node_info.node_type);
6162			break;
6163
6164		case OSMTEST_TOKEN_NUM_PORTS:
6165			p_node->comp.node_info.num_ports = 0xFF;
6166			p_node->rec.node_info.num_ports =
6167			    (uint8_t) strtoul(&line[offset], NULL, 0);
6168			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6169				"num_ports = 0x%X\n",
6170				p_node->rec.node_info.num_ports);
6171			break;
6172
6173		case OSMTEST_TOKEN_SYS_GUID:
6174			p_node->comp.node_info.sys_guid = 0xFFFFFFFFFFFFFFFFULL;
6175			p_node->rec.node_info.sys_guid =
6176			    cl_hton64(strtoull(&line[offset], NULL, 0));
6177			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6178				"sys_guid = 0x%016" PRIx64 "\n",
6179				cl_ntoh64(p_node->rec.node_info.sys_guid));
6180			break;
6181
6182		case OSMTEST_TOKEN_NODE_GUID:
6183			p_node->comp.node_info.node_guid =
6184			    0xFFFFFFFFFFFFFFFFULL;
6185			p_node->rec.node_info.node_guid =
6186			    cl_hton64(strtoull(&line[offset], NULL, 0));
6187			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6188				"node_guid = 0x%016" PRIx64 "\n",
6189				cl_ntoh64(p_node->rec.node_info.node_guid));
6190			break;
6191
6192		case OSMTEST_TOKEN_PORT_GUID:
6193			p_node->comp.node_info.port_guid =
6194			    0xFFFFFFFFFFFFFFFFULL;
6195			p_node->rec.node_info.port_guid =
6196			    cl_hton64(strtoull(&line[offset], NULL, 0));
6197			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6198				"port_guid = 0x%016" PRIx64 "\n",
6199				cl_ntoh64(p_node->rec.node_info.port_guid));
6200			break;
6201
6202		case OSMTEST_TOKEN_PARTITION_CAP:
6203			p_node->comp.node_info.partition_cap = 0xFFFF;
6204			p_node->rec.node_info.partition_cap =
6205			    cl_hton16((uint16_t)
6206				      strtoul(&line[offset], NULL, 0));
6207			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6208				"partition_cap = 0x%X\n",
6209				cl_ntoh16(p_node->rec.node_info.partition_cap));
6210			break;
6211
6212		case OSMTEST_TOKEN_DEVICE_ID:
6213			p_node->comp.node_info.device_id = 0xFFFF;
6214			p_node->rec.node_info.device_id = cl_hton16((uint16_t)
6215								    strtoul
6216								    (&line
6217								     [offset],
6218								     NULL, 0));
6219			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6220				"device_id = 0x%X\n",
6221				cl_ntoh16(p_node->rec.node_info.device_id));
6222			break;
6223
6224		case OSMTEST_TOKEN_REVISION:
6225			p_node->comp.node_info.revision = 0xFFFFFFFF;
6226			p_node->rec.node_info.revision =
6227			    cl_hton32(strtoul(&line[offset], NULL, 0));
6228			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6229				"revision = 0x%X\n",
6230				cl_ntoh32(p_node->rec.node_info.revision));
6231			break;
6232
6233		case OSMTEST_TOKEN_PORT_NUM:
6234			p_node->comp.node_info.port_num_vendor_id |=
6235			    IB_NODE_INFO_PORT_NUM_MASK;
6236			p_node->rec.node_info.port_num_vendor_id |=
6237			    (uint8_t) strtoul(&line[offset], NULL, 0);
6238			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6239				"local_port_num = 0x%X\n",
6240				ib_node_info_get_local_port_num
6241				(&p_node->rec.node_info));
6242			break;
6243
6244		case OSMTEST_TOKEN_VENDOR_ID:
6245			p_node->comp.node_info.port_num_vendor_id |=
6246			    IB_NODE_INFO_VEND_ID_MASK;
6247			p_node->rec.node_info.port_num_vendor_id |=
6248			    cl_hton32(strtoul(&line[offset], NULL, 0));
6249			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6250				"vendor_id = 0x%X\n",
6251				cl_ntoh32(ib_node_info_get_vendor_id
6252					  (&p_node->rec.node_info)));
6253			break;
6254
6255		case OSMTEST_TOKEN_END:
6256			done = TRUE;
6257			break;
6258
6259		default:
6260			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0121: "
6261				"Ignoring line %u with unknown token: %s\n",
6262				*p_line_num, &line[offset]);
6263
6264			break;
6265		}
6266	}
6267
6268	/*
6269	 * Make sure the user specified enough information, then
6270	 * add this object to the database.
6271	 */
6272	if (p_node->comp.lid == 0) {
6273		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0122: "
6274			"LID must be specified for defined nodes\n");
6275		node_delete(p_node);
6276		goto Exit;
6277	}
6278
6279	cl_qmap_insert(&p_osmt->exp_subn.node_lid_tbl,
6280		       p_node->rec.lid, &p_node->map_item);
6281
6282	p_guid_node = node_new();
6283	CL_ASSERT(p_node != NULL);
6284
6285	*p_guid_node = *p_node;
6286
6287	cl_qmap_insert(&p_osmt->exp_subn.node_guid_tbl,
6288		       p_guid_node->rec.node_info.node_guid,
6289		       &p_guid_node->map_item);
6290
6291Exit:
6292	OSM_LOG_EXIT(&p_osmt->log);
6293	return (status);
6294}
6295
6296/**********************************************************************
6297 **********************************************************************/
6298static ib_api_status_t
6299osmtest_parse_port(IN osmtest_t * const p_osmt,
6300		   IN FILE * const fh, IN OUT uint32_t * const p_line_num)
6301{
6302	ib_api_status_t status = IB_SUCCESS;
6303	uint32_t offset;
6304	char line[OSMTEST_MAX_LINE_LEN];
6305	boolean_t done = FALSE;
6306	port_t *p_port;
6307	const osmtest_token_t *p_tok;
6308
6309	OSM_LOG_ENTER(&p_osmt->log);
6310
6311	p_port = port_new();
6312	CL_ASSERT(p_port != NULL);
6313
6314	/*
6315	 * Parse the inventory file and create the database.
6316	 */
6317	while (!done) {
6318		if (fgets(line, OSMTEST_MAX_LINE_LEN, fh) == NULL) {
6319			/*
6320			 * End of file in the middle of a definition.
6321			 */
6322			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0123: "
6323				"Unexpected end of file\n");
6324			status = IB_ERROR;
6325			goto Exit;
6326		}
6327
6328		++*p_line_num;
6329
6330		/*
6331		 * Skip whitespace
6332		 */
6333		offset = 0;
6334		if (!str_skip_white(line, &offset))
6335			continue;	/* whole line was whitespace */
6336
6337		p_tok = str_get_token(&line[offset]);
6338		if (p_tok == NULL) {
6339			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0124: "
6340				"Ignoring line %u with unknown token: %s\n",
6341				*p_line_num, &line[offset]);
6342			continue;
6343		}
6344
6345		OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6346			"Found '%s' (line %u)\n", p_tok->str, *p_line_num);
6347
6348		str_skip_token(line, &offset);
6349
6350		switch (p_tok->val) {
6351		case OSMTEST_TOKEN_COMMENT:
6352			break;
6353
6354		case OSMTEST_TOKEN_LID:
6355			p_port->comp.lid = 0xFFFF;
6356			p_port->rec.lid =
6357			    cl_hton16((uint16_t)
6358				      strtoul(&line[offset], NULL, 0));
6359			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "lid = 0x%X\n",
6360				cl_ntoh16(p_port->rec.lid));
6361			break;
6362
6363		case OSMTEST_TOKEN_PORT_NUM:
6364			p_port->comp.port_num = 0xFF;
6365			p_port->rec.port_num =
6366			    (uint8_t) strtoul(&line[offset], NULL, 0);
6367			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6368				"port_num = 0x%u\n", p_port->rec.port_num);
6369			break;
6370
6371		case OSMTEST_TOKEN_MKEY:
6372			p_port->comp.port_info.m_key = 0xFFFFFFFFFFFFFFFFULL;
6373			p_port->rec.port_info.m_key =
6374			    cl_hton64(strtoull(&line[offset], NULL, 0));
6375			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6376				"m_key = 0x%016" PRIx64 "\n",
6377				cl_ntoh64(p_port->rec.port_info.m_key));
6378			break;
6379
6380		case OSMTEST_TOKEN_SUBN_PREF:
6381			p_port->comp.port_info.subnet_prefix =
6382			    0xFFFFFFFFFFFFFFFFULL;
6383			p_port->rec.port_info.subnet_prefix =
6384			    cl_hton64(strtoull(&line[offset], NULL, 0));
6385			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6386				"subnet_prefix = 0x%016" PRIx64 "\n",
6387				cl_ntoh64(p_port->rec.port_info.subnet_prefix));
6388			break;
6389
6390		case OSMTEST_TOKEN_BASE_LID:
6391			p_port->comp.port_info.base_lid = 0xFFFF;
6392			p_port->rec.port_info.base_lid =
6393			    cl_hton16((uint16_t)
6394				      strtoul(&line[offset], NULL, 0));
6395			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6396				"base_lid = 0x%X\n",
6397				cl_ntoh16(p_port->rec.port_info.base_lid));
6398			break;
6399
6400		case OSMTEST_TOKEN_SM_BASE_LID:
6401			p_port->comp.port_info.master_sm_base_lid = 0xFFFF;
6402			p_port->rec.port_info.master_sm_base_lid =
6403			    cl_hton16((uint16_t)
6404				      strtoul(&line[offset], NULL, 0));
6405			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6406				"master_sm_base_lid = 0x%X\n",
6407				cl_ntoh16(p_port->rec.port_info.master_sm_base_lid));
6408			break;
6409
6410		case OSMTEST_TOKEN_CAP_MASK:
6411			p_port->comp.port_info.capability_mask = 0xFFFFFFFF;
6412			p_port->rec.port_info.capability_mask =
6413			    cl_hton32((uint32_t)
6414				      strtoul(&line[offset], NULL, 0));
6415			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6416				"capability_mask = 0x%X\n",
6417				cl_ntoh32(p_port->rec.port_info.capability_mask));
6418			break;
6419
6420		case OSMTEST_TOKEN_DIAG_CODE:
6421			p_port->comp.port_info.diag_code = 0xFFFF;
6422			p_port->rec.port_info.diag_code =
6423			    cl_hton16((uint16_t)
6424				      strtoul(&line[offset], NULL, 0));
6425			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6426				"diag_code = 0x%X\n",
6427				cl_ntoh16(p_port->rec.port_info.diag_code));
6428			break;
6429
6430		case OSMTEST_TOKEN_MKEY_LEASE_PER:
6431			p_port->comp.port_info.m_key_lease_period = 0xFFFF;
6432			p_port->rec.port_info.m_key_lease_period =
6433			    cl_hton16((uint16_t)
6434				      strtoul(&line[offset], NULL, 0));
6435			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6436				"m_key_lease_period = 0x%X\n",
6437				cl_ntoh16(p_port->rec.port_info.m_key_lease_period));
6438			break;
6439
6440		case OSMTEST_TOKEN_LOC_PORT_NUM:
6441			p_port->comp.port_info.local_port_num = 0xFF;
6442			p_port->rec.port_info.local_port_num =
6443			    (uint8_t) strtoul(&line[offset], NULL, 0);
6444			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6445				"local_port_num = 0x%u\n",
6446				p_port->rec.port_info.local_port_num);
6447			break;
6448
6449		case OSMTEST_TOKEN_LINK_WID_EN:
6450			p_port->comp.port_info.link_width_enabled = 0xFF;
6451			p_port->rec.port_info.link_width_enabled =
6452			    (uint8_t) strtoul(&line[offset], NULL, 0);
6453			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6454				"link_width_enabled = 0x%u\n",
6455				p_port->rec.port_info.link_width_enabled);
6456			break;
6457
6458		case OSMTEST_TOKEN_LINK_WID_SUP:
6459			p_port->comp.port_info.link_width_supported = 0xFF;
6460			p_port->rec.port_info.link_width_supported =
6461			    (uint8_t) strtoul(&line[offset], NULL, 0);
6462			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6463				"link_width_supported = 0x%u\n",
6464				p_port->rec.port_info.link_width_supported);
6465			break;
6466
6467		case OSMTEST_TOKEN_LINK_WID_ACT:
6468			p_port->comp.port_info.link_width_active = 0xFF;
6469			p_port->rec.port_info.link_width_active =
6470			    (uint8_t) strtoul(&line[offset], NULL, 0);
6471			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6472				"link_width_active = 0x%u\n",
6473				p_port->rec.port_info.link_width_active);
6474			break;
6475
6476		case OSMTEST_TOKEN_LINK_SPEED_SUP:
6477			p_port->comp.port_info.state_info1 = 0xFF;
6478			ib_port_info_set_link_speed_sup((uint8_t)
6479							strtoul(&line[offset],
6480								NULL, 0),
6481							&p_port->rec.port_info);
6482			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6483				"link_speed_supported = 0x%u\n",
6484				ib_port_info_get_link_speed_sup(&p_port->rec.port_info));
6485			break;
6486
6487		case OSMTEST_TOKEN_PORT_STATE:
6488			str_skip_white(line, &offset);
6489			p_port->comp.port_info.state_info1 = 0xFF;
6490			ib_port_info_set_port_state(&p_port->rec.port_info,
6491						    ib_get_port_state_from_str
6492						    (&line[offset]));
6493			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6494				"port_state = 0x%u\n",
6495				ib_port_info_get_port_state(&p_port->rec.port_info));
6496			break;
6497
6498		case OSMTEST_TOKEN_STATE_INFO2:
6499			p_port->comp.port_info.state_info2 = 0xFF;
6500			p_port->rec.port_info.state_info2 =
6501			    (uint8_t) strtoul(&line[offset], NULL, 0);
6502			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6503				"state_info2 = 0x%u\n",
6504				p_port->rec.port_info.state_info2);
6505			break;
6506
6507		case OSMTEST_TOKEN_MKEY_PROT_BITS:
6508			p_port->comp.port_info.mkey_lmc = 0xFF;
6509			ib_port_info_set_mpb(&p_port->rec.port_info,
6510					     (uint8_t) strtoul(&line[offset],
6511							       NULL, 0));
6512			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "mpb = 0x%u\n",
6513				ib_port_info_get_mpb(&p_port->rec.port_info));
6514			break;
6515
6516		case OSMTEST_TOKEN_LMC:
6517			p_port->comp.port_info.mkey_lmc = 0xFF;
6518			ib_port_info_set_lmc(&p_port->rec.port_info,
6519					     (uint8_t) strtoul(&line[offset],
6520							       NULL, 0));
6521			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "lmc = 0x%u\n",
6522				ib_port_info_get_lmc(&p_port->rec.port_info));
6523			break;
6524
6525		case OSMTEST_TOKEN_LINK_SPEED:
6526			p_port->comp.port_info.link_speed = 0xFF;
6527			p_port->rec.port_info.link_speed =
6528			    (uint8_t) strtoul(&line[offset], NULL, 0);
6529			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6530				"link_speed = 0x%u\n",
6531				p_port->rec.port_info.link_speed);
6532			break;
6533
6534		case OSMTEST_TOKEN_MTU_SMSL:
6535			p_port->comp.port_info.mtu_smsl = 0xFF;
6536			p_port->rec.port_info.mtu_smsl =
6537			    (uint8_t) strtoul(&line[offset], NULL, 0);
6538			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6539				"mtu_smsl = 0x%u\n",
6540				p_port->rec.port_info.mtu_smsl);
6541			break;
6542
6543		case OSMTEST_TOKEN_VL_CAP:
6544			p_port->comp.port_info.vl_cap = 0xFF;
6545			p_port->rec.port_info.vl_cap =
6546			    (uint8_t) strtoul(&line[offset], NULL, 0);
6547			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "vl_cap = 0x%u\n",
6548				p_port->rec.port_info.vl_cap);
6549			break;
6550
6551		case OSMTEST_TOKEN_VL_HIGH_LIMIT:
6552			p_port->comp.port_info.vl_high_limit = 0xFF;
6553			p_port->rec.port_info.vl_high_limit =
6554			    (uint8_t) strtoul(&line[offset], NULL, 0);
6555			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6556				"vl_high_limit = 0x%u\n",
6557				p_port->rec.port_info.vl_high_limit);
6558			break;
6559
6560		case OSMTEST_TOKEN_VL_ARB_HIGH_CAP:
6561			p_port->comp.port_info.vl_arb_high_cap = 0xFF;
6562			p_port->rec.port_info.vl_arb_high_cap =
6563			    (uint8_t) strtoul(&line[offset], NULL, 0);
6564			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6565				"vl_arb_high_cap = 0x%u\n",
6566				p_port->rec.port_info.vl_arb_high_cap);
6567			break;
6568
6569		case OSMTEST_TOKEN_VL_ARB_LOW_CAP:
6570			p_port->comp.port_info.vl_arb_low_cap = 0xFF;
6571			p_port->rec.port_info.vl_arb_low_cap =
6572			    (uint8_t) strtoul(&line[offset], NULL, 0);
6573			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6574				"vl_arb_low_cap = 0x%u\n",
6575				p_port->rec.port_info.vl_arb_low_cap);
6576			break;
6577
6578		case OSMTEST_TOKEN_MTU_CAP:
6579			p_port->comp.port_info.mtu_cap = 0xFF;
6580			p_port->rec.port_info.mtu_cap =
6581			    (uint8_t) strtoul(&line[offset], NULL, 0);
6582			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "mtu_cap = 0x%u\n",
6583				p_port->rec.port_info.mtu_cap);
6584			break;
6585
6586		case OSMTEST_TOKEN_VL_STALL_LIFE:
6587			p_port->comp.port_info.vl_stall_life = 0xFF;
6588			p_port->rec.port_info.vl_stall_life =
6589			    (uint8_t) strtoul(&line[offset], NULL, 0);
6590			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6591				"vl_stall_life = 0x%u\n",
6592				p_port->rec.port_info.vl_stall_life);
6593			break;
6594
6595		case OSMTEST_TOKEN_VL_ENFORCE:
6596			p_port->comp.port_info.vl_enforce = 0xFF;
6597			p_port->rec.port_info.vl_enforce =
6598			    (uint8_t) strtoul(&line[offset], NULL, 0);
6599			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6600				"vl_enforce = 0x%u\n",
6601				p_port->rec.port_info.vl_enforce);
6602			break;
6603
6604		case OSMTEST_TOKEN_MKEY_VIOL:
6605			p_port->comp.port_info.m_key_violations = 0xFFFF;
6606			p_port->rec.port_info.m_key_violations =
6607			    cl_hton16((uint16_t)
6608				      strtoul(&line[offset], NULL, 0));
6609			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6610				"m_key_violations = 0x%X\n",
6611				cl_ntoh16(p_port->rec.port_info.m_key_violations));
6612			break;
6613
6614		case OSMTEST_TOKEN_PKEY_VIOL:
6615			p_port->comp.port_info.p_key_violations = 0xFFFF;
6616			p_port->rec.port_info.p_key_violations =
6617			    cl_hton16((uint16_t)
6618				      strtoul(&line[offset], NULL, 0));
6619			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6620				"p_key_violations = 0x%X\n",
6621				cl_ntoh16(p_port->rec.port_info.p_key_violations));
6622			break;
6623
6624		case OSMTEST_TOKEN_QKEY_VIOL:
6625			p_port->comp.port_info.q_key_violations = 0xFFFF;
6626			p_port->rec.port_info.q_key_violations =
6627			    cl_hton16((uint16_t)
6628				      strtoul(&line[offset], NULL, 0));
6629			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6630				"q_key_violations = 0x%X\n",
6631				cl_ntoh16(p_port->rec.port_info.q_key_violations));
6632			break;
6633
6634		case OSMTEST_TOKEN_GUID_CAP:
6635			p_port->comp.port_info.guid_cap = 0xFF;
6636			p_port->rec.port_info.guid_cap =
6637			    (uint8_t) strtoul(&line[offset], NULL, 0);
6638			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6639				"guid_cap = 0x%u\n",
6640				p_port->rec.port_info.guid_cap);
6641			break;
6642
6643		case OSMTEST_TOKEN_SUBN_TIMEOUT:
6644			p_port->comp.port_info.subnet_timeout = 0x1F;
6645			p_port->rec.port_info.subnet_timeout =
6646			    (uint8_t) strtoul(&line[offset], NULL, 0);
6647			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6648				"subnet_timeout = 0x%u\n",
6649				ib_port_info_get_timeout(&p_port->rec.port_info));
6650			break;
6651
6652		case OSMTEST_TOKEN_RESP_TIME_VAL:
6653			p_port->comp.port_info.resp_time_value = 0xFF;
6654			p_port->rec.port_info.resp_time_value =
6655			    (uint8_t) strtoul(&line[offset], NULL, 0);
6656			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6657				"resp_time_value = 0x%u\n",
6658				p_port->rec.port_info.resp_time_value);
6659			break;
6660
6661		case OSMTEST_TOKEN_ERR_THRESHOLD:
6662			p_port->comp.port_info.error_threshold = 0xFF;
6663			p_port->rec.port_info.error_threshold =
6664			    (uint8_t) strtoul(&line[offset], NULL, 0);
6665			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6666				"error_threshold = 0x%u\n",
6667				p_port->rec.port_info.error_threshold);
6668			break;
6669
6670		case OSMTEST_TOKEN_END:
6671			done = TRUE;
6672			break;
6673
6674		default:
6675			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0125: "
6676				"Ignoring line %u with unknown token: %s\n",
6677				*p_line_num, &line[offset]);
6678			break;
6679		}
6680	}
6681
6682	/*
6683	 * Make sure the user specified enough information, then
6684	 * add this object to the database.
6685	 */
6686	if (p_port->comp.lid == 0) {
6687		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0126: "
6688			"LID must be specified for defined ports\n");
6689		port_delete(p_port);
6690		status = IB_ERROR;
6691		goto Exit;
6692	}
6693
6694	cl_qmap_insert(&p_osmt->exp_subn.port_key_tbl,
6695		       port_gen_id(p_port->rec.lid, p_port->rec.port_num),
6696		       &p_port->map_item);
6697
6698Exit:
6699	OSM_LOG_EXIT(&p_osmt->log);
6700	return (status);
6701}
6702
6703/**********************************************************************
6704 **********************************************************************/
6705static ib_api_status_t
6706osmtest_parse_path(IN osmtest_t * const p_osmt,
6707		   IN FILE * const fh, IN OUT uint32_t * const p_line_num)
6708{
6709	ib_api_status_t status = IB_SUCCESS;
6710	uint32_t offset;
6711	char line[OSMTEST_MAX_LINE_LEN];
6712	boolean_t done = FALSE;
6713	path_t *p_path;
6714	const osmtest_token_t *p_tok;
6715	boolean_t got_error = FALSE;
6716
6717	OSM_LOG_ENTER(&p_osmt->log);
6718
6719	p_path = path_new();
6720	CL_ASSERT(p_path != NULL);
6721
6722	/*
6723	 * Parse the inventory file and create the database.
6724	 */
6725	while (!done) {
6726		if (fgets(line, OSMTEST_MAX_LINE_LEN, fh) == NULL) {
6727			/*
6728			 * End of file in the middle of a definition.
6729			 */
6730			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: "
6731				"Unexpected end of file\n");
6732			status = IB_ERROR;
6733			goto Exit;
6734		}
6735
6736		++*p_line_num;
6737
6738		/*
6739		 * Skip whitespace
6740		 */
6741		offset = 0;
6742		if (!str_skip_white(line, &offset))
6743			continue;	/* whole line was whitespace */
6744
6745		p_tok = str_get_token(&line[offset]);
6746		if (p_tok == NULL) {
6747			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0128: "
6748				"Ignoring line %u with unknown token: %s\n",
6749				*p_line_num, &line[offset]);
6750			got_error = TRUE;
6751			continue;
6752		}
6753
6754		OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6755			"Found '%s' (line %u)\n", p_tok->str, *p_line_num);
6756
6757		str_skip_token(line, &offset);
6758
6759		switch (p_tok->val) {
6760		case OSMTEST_TOKEN_COMMENT:
6761			break;
6762
6763		case OSMTEST_TOKEN_DGID:
6764			p_path->comp.dgid.unicast.prefix =
6765			    0xFFFFFFFFFFFFFFFFULL;
6766			p_path->comp.dgid.unicast.interface_id =
6767			    0xFFFFFFFFFFFFFFFFULL;
6768
6769			str_skip_white(line, &offset);
6770			p_path->rec.dgid.unicast.prefix =
6771			    cl_hton64(strtoull(&line[offset], NULL, 0));
6772			str_skip_token(line, &offset);
6773			p_path->rec.dgid.unicast.interface_id =
6774			    cl_hton64(strtoull(&line[offset], NULL, 0));
6775
6776			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6777				"dgid = 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
6778				cl_ntoh64(p_path->rec.dgid.unicast.prefix),
6779				cl_ntoh64(p_path->rec.dgid.unicast.interface_id));
6780			break;
6781
6782		case OSMTEST_TOKEN_SGID:
6783			p_path->comp.sgid.unicast.prefix =
6784			    0xFFFFFFFFFFFFFFFFULL;
6785			p_path->comp.sgid.unicast.interface_id =
6786			    0xFFFFFFFFFFFFFFFFULL;
6787
6788			str_skip_white(line, &offset);
6789			p_path->rec.sgid.unicast.prefix =
6790			    cl_hton64(strtoull(&line[offset], NULL, 0));
6791			str_skip_token(line, &offset);
6792			p_path->rec.sgid.unicast.interface_id =
6793			    cl_hton64(strtoull(&line[offset], NULL, 0));
6794
6795			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6796				"sgid = 0x%016" PRIx64 " 0x%016" PRIx64 "\n",
6797				cl_ntoh64(p_path->rec.sgid.unicast.prefix),
6798				cl_ntoh64(p_path->rec.sgid.unicast.interface_id));
6799			break;
6800
6801		case OSMTEST_TOKEN_DLID:
6802			p_path->comp.dlid = 0xFFFF;
6803			p_path->rec.dlid =
6804			    cl_hton16((uint16_t)
6805				      strtoul(&line[offset], NULL, 0));
6806			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "dlid = 0x%X\n",
6807				cl_ntoh16(p_path->rec.dlid));
6808			break;
6809
6810		case OSMTEST_TOKEN_SLID:
6811			p_path->comp.slid = 0xFFFF;
6812			p_path->rec.slid =
6813			    cl_hton16((uint16_t)
6814				      strtoul(&line[offset], NULL, 0));
6815			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "slid = 0x%X\n",
6816				cl_ntoh16(p_path->rec.slid));
6817			break;
6818
6819		case OSMTEST_TOKEN_PKEY:
6820			p_path->comp.pkey = 0xFFFF;
6821			p_path->rec.pkey =
6822			    cl_hton16((uint16_t)
6823				      strtoul(&line[offset], NULL, 0));
6824			OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "pkey = 0x%X\n",
6825				cl_ntoh16(p_path->rec.pkey));
6826			break;
6827
6828		case OSMTEST_TOKEN_END:
6829			done = TRUE;
6830			break;
6831
6832		default:
6833			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0129: "
6834				"Ignoring line %u with unknown token: %s\n",
6835				*p_line_num, &line[offset]);
6836			got_error = TRUE;
6837			break;
6838		}
6839	}
6840
6841	if (got_error) {
6842		status = IB_ERROR;
6843		goto Exit;
6844	}
6845	/*
6846	 * Make sure the user specified enough information, then
6847	 * add this object to the database.
6848	 */
6849	if (osmtest_path_rec_kay_is_valid(p_osmt, p_path) == FALSE) {
6850		path_delete(p_path);
6851		status = IB_ERROR;
6852		goto Exit;
6853	}
6854
6855	cl_qmap_insert(&p_osmt->exp_subn.path_tbl,
6856		       osmtest_path_rec_key_get(&p_path->rec),
6857		       &p_path->map_item);
6858
6859Exit:
6860	OSM_LOG_EXIT(&p_osmt->log);
6861	return (status);
6862}
6863
6864/**********************************************************************
6865 **********************************************************************/
6866static ib_api_status_t
6867osmtest_parse_link(IN osmtest_t * const p_osmt,
6868		   IN FILE * const fh, IN OUT uint32_t * const p_line_num)
6869{
6870	ib_api_status_t status = IB_SUCCESS;
6871	uint32_t offset;
6872	char line[OSMTEST_MAX_LINE_LEN];
6873	boolean_t done = FALSE;
6874	const osmtest_token_t *p_tok;
6875	boolean_t got_error = FALSE;
6876
6877	OSM_LOG_ENTER(&p_osmt->log);
6878
6879	/*
6880	 * Parse the inventory file and create the database.
6881	 */
6882	while (!done) {
6883		if (fgets(line, OSMTEST_MAX_LINE_LEN, fh) == NULL) {
6884			/*
6885			 * End of file in the middle of a definition.
6886			 */
6887			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 012A: "
6888				"Unexpected end of file\n");
6889			status = IB_ERROR;
6890			goto Exit;
6891		}
6892
6893		++*p_line_num;
6894
6895		/*
6896		 * Skip whitespace
6897		 */
6898		offset = 0;
6899		if (!str_skip_white(line, &offset))
6900			continue;	/* whole line was whitespace */
6901
6902		p_tok = str_get_token(&line[offset]);
6903		if (p_tok == NULL) {
6904			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 012B: "
6905				"Ignoring line %u with unknown token: %s\n",
6906				*p_line_num, &line[offset]);
6907			got_error = TRUE;
6908			continue;
6909		}
6910
6911		OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6912			"Found '%s' (line %u)\n", p_tok->str, *p_line_num);
6913
6914		str_skip_token(line, &offset);
6915
6916		switch (p_tok->val) {
6917		case OSMTEST_TOKEN_FROMLID:
6918		case OSMTEST_TOKEN_FROMPORTNUM:
6919		case OSMTEST_TOKEN_TOPORTNUM:
6920		case OSMTEST_TOKEN_TOLID:
6921			/* For now */
6922			break;
6923
6924		case OSMTEST_TOKEN_END:
6925			done = TRUE;
6926			break;
6927
6928		default:
6929			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 012C: "
6930				"Ignoring line %u with unknown token: %s\n",
6931				*p_line_num, &line[offset]);
6932			got_error = TRUE;
6933			break;
6934		}
6935	}
6936
6937	if (got_error)
6938		status = IB_ERROR;
6939
6940Exit:
6941	OSM_LOG_EXIT(&p_osmt->log);
6942	return (status);
6943}
6944
6945/**********************************************************************
6946 **********************************************************************/
6947static ib_api_status_t osmtest_create_db(IN osmtest_t * const p_osmt)
6948{
6949	FILE *fh;
6950	ib_api_status_t status = IB_SUCCESS;
6951	uint32_t offset;
6952	char line[OSMTEST_MAX_LINE_LEN];
6953	uint32_t line_num = 0;
6954	const osmtest_token_t *p_tok;
6955	boolean_t got_error = FALSE;
6956
6957	OSM_LOG_ENTER(&p_osmt->log);
6958
6959	fh = fopen(p_osmt->opt.file_name, "r");
6960	if (fh == NULL) {
6961		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0130: "
6962			"Unable to open inventory file (%s)\n",
6963			p_osmt->opt.file_name);
6964		status = IB_ERROR;
6965		goto Exit;
6966	}
6967
6968	/*
6969	 * Parse the inventory file and create the database.
6970	 */
6971	while (fgets(line, OSMTEST_MAX_LINE_LEN, fh) != NULL) {
6972		line_num++;
6973
6974		/*
6975		 * Skip whitespace
6976		 */
6977		offset = 0;
6978		if (!str_skip_white(line, &offset))
6979			continue;	/* whole line was whitespace */
6980
6981		p_tok = str_get_token(&line[offset]);
6982		if (p_tok == NULL) {
6983			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0131: "
6984				"Ignoring line %u: %s\n", line_num,
6985				&line[offset]);
6986			got_error = TRUE;
6987			continue;
6988		}
6989
6990		OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
6991			"Found '%s' (line %u)\n", p_tok->str, line_num);
6992
6993		switch (p_tok->val) {
6994		case OSMTEST_TOKEN_COMMENT:
6995			break;
6996
6997		case OSMTEST_TOKEN_DEFINE_NODE:
6998			status = osmtest_parse_node(p_osmt, fh, &line_num);
6999			break;
7000
7001		case OSMTEST_TOKEN_DEFINE_PORT:
7002			status = osmtest_parse_port(p_osmt, fh, &line_num);
7003			break;
7004
7005		case OSMTEST_TOKEN_DEFINE_PATH:
7006			status = osmtest_parse_path(p_osmt, fh, &line_num);
7007			break;
7008
7009		case OSMTEST_TOKEN_DEFINE_LINK:
7010			status = osmtest_parse_link(p_osmt, fh, &line_num);
7011			break;
7012
7013		default:
7014			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0132: "
7015				"Ignoring line %u: %s\n", line_num,
7016				&line[offset]);
7017			got_error = TRUE;
7018			break;
7019		}
7020
7021		if (got_error)
7022			status = IB_ERROR;
7023
7024		if (status != IB_SUCCESS) {
7025			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0133: "
7026				"Bad status received during parsing (%s)\n",
7027				ib_get_err_str(status));
7028			fclose(fh);
7029			goto Exit;
7030		}
7031	}
7032
7033	fclose(fh);
7034
7035Exit:
7036	OSM_LOG_EXIT(&p_osmt->log);
7037	return (status);
7038}
7039
7040/**********************************************************************
7041   Returns the index in the local port attribute array for the
7042   user's selection.
7043**********************************************************************/
7044static uint32_t
7045osmtest_get_user_port(IN osmtest_t * const p_osmt,
7046		      IN const ib_port_attr_t p_attr_array[],
7047		      IN uint32_t const num_ports)
7048{
7049	uint32_t i;
7050	uint32_t choice = 0;
7051	boolean_t done_flag = FALSE;
7052
7053	OSM_LOG_ENTER(&p_osmt->log);
7054
7055	/*
7056	 * User needs prompting for the local port GUID with which
7057	 * to bind.
7058	 */
7059
7060	while (done_flag == FALSE) {
7061		printf("\nChoose a local port number with which to bind:\n\n");
7062		for (i = 0; i < num_ports; i++) {
7063			/*
7064			 * Print the index + 1 since by convention, port numbers
7065			 * start with 1 on host channel adapters.
7066			 */
7067
7068			printf("\t%u: GUID = 0x%8" PRIx64
7069			       ", lid = 0x%04X, state = %s\n", i + 1,
7070			       cl_ntoh64(p_attr_array[i].port_guid),
7071			       p_attr_array[i].lid,
7072			       ib_get_port_state_str(p_attr_array[i].
7073						     link_state));
7074		}
7075
7076		printf("\nEnter choice (1-%u): ", i);
7077		scanf("%u", &choice);
7078		if (choice > num_ports)
7079			printf("\nError: Lame choice!\n");
7080		else
7081			done_flag = TRUE;
7082
7083	}
7084	printf("\n");
7085	OSM_LOG_EXIT(&p_osmt->log);
7086	return (choice - 1);
7087}
7088
7089/**********************************************************************
7090 **********************************************************************/
7091ib_api_status_t
7092osmtest_bind(IN osmtest_t * p_osmt,
7093	     IN uint16_t max_lid, IN ib_net64_t guid OPTIONAL)
7094{
7095	uint32_t port_index;
7096	ib_api_status_t status;
7097	uint32_t num_ports = GUID_ARRAY_SIZE;
7098	ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
7099
7100	OSM_LOG_ENTER(&p_osmt->log);
7101
7102	/*
7103	 * Call the transport layer for a list of local port
7104	 * GUID values.
7105	 */
7106	status = osm_vendor_get_all_port_attr(p_osmt->p_vendor,
7107					      attr_array, &num_ports);
7108	if (status != IB_SUCCESS) {
7109		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0134: "
7110			"Failure getting local port attributes (%s)\n",
7111			ib_get_err_str(status));
7112		goto Exit;
7113	}
7114
7115	if (guid == 0) {
7116		/*
7117		 * User needs prompting for the local port GUID with which
7118		 * to bind.
7119		 */
7120		port_index =
7121		    osmtest_get_user_port(p_osmt, attr_array, num_ports);
7122
7123		if (num_ports == 0) {
7124			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0135: "
7125				"No local ports.  Unable to proceed\n");
7126			goto Exit;
7127		}
7128		guid = attr_array[port_index].port_guid;
7129	} else {
7130		for (port_index = 0; port_index < num_ports; port_index++) {
7131			if (attr_array[port_index].port_guid == guid)
7132				break;
7133		}
7134
7135		if (port_index == num_ports) {
7136			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0136: "
7137				"No local port with guid 0x%016" PRIx64 "\n",
7138				cl_ntoh64(guid));
7139			status = IB_NOT_FOUND;
7140			goto Exit;
7141		}
7142	}
7143
7144	/*
7145	 * Copy the port info for the selected port.
7146	 */
7147	memcpy(&p_osmt->local_port, &attr_array[port_index],
7148	       sizeof(p_osmt->local_port));
7149
7150	/* bind to the SA */
7151	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG,
7152		"Using port with SM LID:0x%04X\n", p_osmt->local_port.sm_lid);
7153	p_osmt->max_lid = max_lid;
7154
7155	p_osmt->h_bind =
7156	    osmv_bind_sa(p_osmt->p_vendor, &p_osmt->mad_pool, guid);
7157
7158	if (p_osmt->h_bind == OSM_BIND_INVALID_HANDLE) {
7159		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0137: "
7160			"Unable to bind to SA\n");
7161		status = IB_ERROR;
7162		goto Exit;
7163	}
7164
7165Exit:
7166	OSM_LOG_EXIT(&p_osmt->log);
7167	return (status);
7168}
7169
7170/**********************************************************************
7171 **********************************************************************/
7172ib_api_status_t osmtest_run(IN osmtest_t * const p_osmt)
7173{
7174	ib_api_status_t status = IB_SUCCESS;
7175
7176	OSM_LOG_ENTER(&p_osmt->log);
7177
7178	status = osmtest_validate_sa_class_port_info(p_osmt);
7179	if (status != IB_SUCCESS) {
7180		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0138: "
7181			"Could not obtain SA ClassPortInfo (%s)\n",
7182			ib_get_err_str(status));
7183		goto Exit;
7184	}
7185
7186	if (p_osmt->opt.flow == OSMT_FLOW_CREATE_INVENTORY) {
7187		/*
7188		 * Creating an inventory file with all nodes, ports and paths
7189		 */
7190		status = osmtest_create_inventory_file(p_osmt);
7191		if (status != IB_SUCCESS) {
7192			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0139: "
7193				"Inventory file create failed (%s)\n",
7194				ib_get_err_str(status));
7195			goto Exit;
7196		}
7197	} else {
7198		if (p_osmt->opt.flow == OSMT_FLOW_STRESS_SA) {
7199			/*
7200			 * Stress SA - flood the SA with queries
7201			 */
7202			switch (p_osmt->opt.stress) {
7203			case 0:
7204			case 1:	/* small response SA query stress */
7205				status = osmtest_stress_small_rmpp(p_osmt);
7206				if (status != IB_SUCCESS) {
7207					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7208						"ERR 0140: "
7209						"Small RMPP stress test failed (%s)\n",
7210						ib_get_err_str(status));
7211					goto Exit;
7212				}
7213				break;
7214			case 2:	/* large response SA query stress */
7215				status = osmtest_stress_large_rmpp(p_osmt);
7216				if (status != IB_SUCCESS) {
7217					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7218						"ERR 0141: "
7219						"Large RMPP stress test failed (%s)\n",
7220						ib_get_err_str(status));
7221					goto Exit;
7222				}
7223				break;
7224			case 3:	/* large response Path Record SA query stress */
7225				status = osmtest_create_db(p_osmt);
7226				if (status != IB_SUCCESS) {
7227					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7228						"ERR 0142: "
7229						"Database creation failed (%s)\n",
7230						ib_get_err_str(status));
7231					goto Exit;
7232				}
7233
7234				status = osmtest_stress_large_rmpp_pr(p_osmt);
7235				if (status != IB_SUCCESS) {
7236					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7237						"ERR 0143: "
7238						"Large RMPP stress test failed (%s)\n",
7239						ib_get_err_str(status));
7240					goto Exit;
7241				}
7242				break;
7243			default:
7244				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7245					"ERR 0144: "
7246					"Unknown stress test value %u\n",
7247					p_osmt->opt.stress);
7248				break;
7249			}
7250		} else {
7251
7252			/*
7253			 * Run normal validation tests.
7254			 */
7255			if (p_osmt->opt.flow == OSMT_FLOW_ALL ||
7256			    p_osmt->opt.flow == OSMT_FLOW_VALIDATE_INVENTORY) {
7257				/*
7258				 * Only validate the given inventory file
7259				 */
7260				status = osmtest_create_db(p_osmt);
7261				if (status != IB_SUCCESS) {
7262					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7263						"ERR 0145: "
7264						"Database creation failed (%s)\n",
7265						ib_get_err_str(status));
7266					goto Exit;
7267				}
7268
7269				status = osmtest_validate_against_db(p_osmt);
7270				if (status != IB_SUCCESS) {
7271					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7272						"ERR 0146: "
7273						"SA validation database failure (%s)\n",
7274						ib_get_err_str(status));
7275					goto Exit;
7276				}
7277			}
7278
7279			if (p_osmt->opt.flow == OSMT_FLOW_ALL) {
7280				status = osmtest_wrong_sm_key_ignored(p_osmt);
7281				if (status != IB_SUCCESS) {
7282					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7283						"ERR 0147: "
7284						"Try wrong SM_Key failed (%s)\n",
7285						ib_get_err_str(status));
7286					goto Exit;
7287				}
7288			}
7289
7290			if (p_osmt->opt.flow == OSMT_FLOW_ALL ||
7291			    p_osmt->opt.flow == OSMT_FLOW_SERVICE_REGISTRATION)
7292			{
7293				/*
7294				 * run service registration, deregistration, and lease test
7295				 */
7296				status = osmt_run_service_records_flow(p_osmt);
7297				if (status != IB_SUCCESS) {
7298					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7299						"ERR 0148: "
7300						"Service Flow failed (%s)\n",
7301						ib_get_err_str(status));
7302					goto Exit;
7303				}
7304			}
7305
7306			if (p_osmt->opt.flow == OSMT_FLOW_ALL ||
7307			    p_osmt->opt.flow == OSMT_FLOW_EVENT_FORWARDING) {
7308				/*
7309				 * Run event forwarding test
7310				 */
7311#ifdef OSM_VENDOR_INTF_MTL
7312				status = osmt_run_inform_info_flow(p_osmt);
7313
7314				if (status != IB_SUCCESS) {
7315					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7316						"ERR 0149: "
7317						"Inform Info Flow failed: (%s)\n",
7318						ib_get_err_str(status));
7319					goto Exit;
7320				}
7321#else
7322				OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
7323					"The event forwarding flow "
7324					"is not implemented yet!\n");
7325				status = IB_SUCCESS;
7326				goto Exit;
7327#endif
7328			}
7329
7330			if (p_osmt->opt.flow == OSMT_FLOW_QOS) {
7331				/*
7332				 * QoS info: dump VLArb and SLtoVL tables.
7333				 * Since it generates a huge file, we run it only
7334				 * if explicitly required to
7335				 */
7336				status = osmtest_create_db(p_osmt);
7337				if (status != IB_SUCCESS) {
7338					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7339						"ERR 014A: "
7340						"Database creation failed (%s)\n",
7341						ib_get_err_str(status));
7342					goto Exit;
7343				}
7344
7345				status =
7346				    osmt_run_slvl_and_vlarb_records_flow
7347				    (p_osmt);
7348				if (status != IB_SUCCESS) {
7349					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7350						"ERR 0150: "
7351						"Failed to get SLtoVL and VL Arbitration Tables (%s)\n",
7352						ib_get_err_str(status));
7353					goto Exit;
7354				}
7355			}
7356
7357			if (p_osmt->opt.flow == OSMT_FLOW_TRAP) {
7358				/*
7359				 * Run trap 64/65 flow (this flow requires running of external tool)
7360				 */
7361#ifdef OSM_VENDOR_INTF_MTL
7362				status = osmt_run_trap64_65_flow(p_osmt);
7363				if (status != IB_SUCCESS) {
7364					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7365						"ERR 0151: "
7366						"Trap 64/65 Flow failed: (%s)\n",
7367						ib_get_err_str(status));
7368					goto Exit;
7369				}
7370#else
7371				OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
7372					"The event forwarding flow "
7373					"is not implemented yet!\n");
7374				status = IB_SUCCESS;
7375				goto Exit;
7376#endif
7377			}
7378
7379			if (p_osmt->opt.flow == OSMT_FLOW_ALL ||
7380			    p_osmt->opt.flow == OSMT_FLOW_MULTICAST) {
7381				/*
7382				 * Multicast flow
7383				 */
7384				status = osmt_run_mcast_flow(p_osmt);
7385				if (status != IB_SUCCESS) {
7386					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
7387						"ERR 0152: "
7388						"Multicast Flow failed: (%s)\n",
7389						ib_get_err_str(status));
7390					goto Exit;
7391				}
7392			}
7393
7394			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
7395				"\n\n***************** ALL TESTS PASS *****************\n\n");
7396
7397		}
7398	}
7399
7400Exit:
7401	OSM_LOG_EXIT(&p_osmt->log);
7402	return (status);
7403}
7404