1/*
2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2006 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/*
37 * Abstract:
38 *    Implementation of service records testing flow..
39 *    Top level is osmt_run_service_records_flow:
40 *     osmt_register_service
41 *     osmt_get_service_by_name
42 *     osmt_get_all_services
43 *     osmt_delete_service_by_name
44 *
45 */
46
47#ifndef __WIN__
48#include <unistd.h>
49#else
50#include <time.h>
51#endif
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <complib/cl_debug.h>
56#include "osmtest.h"
57
58/**********************************************************************
59 **********************************************************************/
60
61ib_api_status_t
62osmt_register_service(IN osmtest_t * const p_osmt,
63		      IN ib_net64_t service_id,
64		      IN ib_net16_t service_pkey,
65		      IN ib_net32_t service_lease,
66		      IN uint8_t service_key_lsb, IN char *service_name)
67{
68	osmv_query_req_t req;
69	osmv_user_query_t user;
70	osmtest_req_context_t context;
71	ib_service_record_t svc_rec;
72	osm_log_t *p_log = &p_osmt->log;
73	ib_api_status_t status;
74
75	OSM_LOG_ENTER(p_log);
76
77	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
78		"Registering service: name: %s id: 0x%" PRIx64 "\n",
79		service_name, cl_ntoh64(service_id));
80
81	memset(&req, 0, sizeof(req));
82	memset(&context, 0, sizeof(context));
83	memset(&user, 0, sizeof(user));
84	memset(&svc_rec, 0, sizeof(svc_rec));
85
86	/* set the new service record fields */
87	svc_rec.service_id = service_id;
88	svc_rec.service_pkey = service_pkey;
89	svc_rec.service_gid.unicast.prefix = 0;
90	svc_rec.service_gid.unicast.interface_id = p_osmt->local_port.port_guid;
91	svc_rec.service_lease = service_lease;
92	memset(&svc_rec.service_key, 0, 16 * sizeof(uint8_t));
93	svc_rec.service_key[0] = service_key_lsb;
94	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
95	memcpy(svc_rec.service_name, service_name,
96	       (strlen(service_name) + 1) * sizeof(char));
97
98	/* prepare the data used for this query */
99	/*  sa_mad_data.method = IB_MAD_METHOD_SET; */
100	/*  sa_mad_data.sm_key = 0; */
101
102	context.p_osmt = p_osmt;
103	req.query_context = &context;
104	req.query_type = OSMV_QUERY_USER_DEFINED;
105	req.pfn_query_cb = osmtest_query_res_cb;
106	req.p_query_input = &user;
107	req.flags = OSM_SA_FLAGS_SYNC;
108	req.sm_key = 0;
109	req.timeout_ms = p_osmt->opt.transaction_timeout;
110
111	user.method = IB_MAD_METHOD_SET;
112	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
113	if (ib_pkey_is_invalid(service_pkey)) {
114		/* if given an invalid service_pkey - don't turn the PKEY compmask on */
115		user.comp_mask = IB_SR_COMPMASK_SID |
116		    IB_SR_COMPMASK_SGID |
117		    IB_SR_COMPMASK_SLEASE |
118		    IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME;
119	} else {
120		user.comp_mask = IB_SR_COMPMASK_SID |
121		    IB_SR_COMPMASK_SGID |
122		    IB_SR_COMPMASK_SPKEY |
123		    IB_SR_COMPMASK_SLEASE |
124		    IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME;
125	}
126	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
127	user.p_attr = &svc_rec;
128
129	status = osmv_query_sa(p_osmt->h_bind, &req);
130	if (status != IB_SUCCESS) {
131		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A01: "
132			"ib_query failed (%s)\n", ib_get_err_str(status));
133		goto Exit;
134	}
135
136	status = context.result.status;
137
138	if (status != IB_SUCCESS) {
139		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A02: "
140			"ib_query failed (%s)\n", ib_get_err_str(status));
141
142		if (status == IB_REMOTE_ERROR) {
143			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
144				"Remote error = %s\n",
145				ib_get_mad_status_str(osm_madw_get_mad_ptr
146						      (context.result.
147						       p_result_madw)));
148		}
149		goto Exit;
150	}
151
152Exit:
153	if (context.result.p_result_madw != NULL) {
154		osm_mad_pool_put(&p_osmt->mad_pool,
155				 context.result.p_result_madw);
156		context.result.p_result_madw = NULL;
157	}
158
159	OSM_LOG_EXIT(&p_osmt->log);
160	return status;
161}
162
163/**********************************************************************
164 **********************************************************************/
165
166ib_api_status_t
167osmt_register_service_with_full_key(IN osmtest_t * const p_osmt,
168				    IN ib_net64_t service_id,
169				    IN ib_net16_t service_pkey,
170				    IN ib_net32_t service_lease,
171				    IN uint8_t * service_key,
172				    IN char *service_name)
173{
174	osmv_query_req_t req;
175	osmv_user_query_t user;
176	osmtest_req_context_t context;
177	ib_service_record_t svc_rec, *p_rec;
178	osm_log_t *p_log = &p_osmt->log;
179	ib_api_status_t status;
180	uint8_t i, skey[16];
181
182	OSM_LOG_ENTER(p_log);
183
184	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
185		"Registering service: name: %s id: 0x%" PRIx64 "\n",
186		service_name, cl_ntoh64(service_id));
187
188	memset(&req, 0, sizeof(req));
189	memset(&context, 0, sizeof(context));
190	memset(&user, 0, sizeof(user));
191	memset(&svc_rec, 0, sizeof(svc_rec));
192
193	/* set the new service record fields */
194	svc_rec.service_id = service_id;
195	svc_rec.service_pkey = service_pkey;
196	svc_rec.service_gid.unicast.prefix = 0;
197	svc_rec.service_gid.unicast.interface_id = p_osmt->local_port.port_guid;
198	svc_rec.service_lease = service_lease;
199	memset(&svc_rec.service_key, 0, 16 * sizeof(uint8_t));
200	memcpy(svc_rec.service_key, service_key, 16 * sizeof(uint8_t));
201	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
202	memset(skey, 0, 16 * sizeof(uint8_t));
203	memcpy(svc_rec.service_name, service_name,
204	       (strlen(service_name) + 1) * sizeof(char));
205
206	/* prepare the data used for this query */
207	/*  sa_mad_data.method = IB_MAD_METHOD_SET; */
208	/*  sa_mad_data.sm_key = 0; */
209
210	context.p_osmt = p_osmt;
211	req.query_context = &context;
212	req.query_type = OSMV_QUERY_USER_DEFINED;
213	req.pfn_query_cb = osmtest_query_res_cb;
214	req.p_query_input = &user;
215	req.flags = OSM_SA_FLAGS_SYNC;
216	req.sm_key = 0;
217	req.timeout_ms = p_osmt->opt.transaction_timeout;
218
219	user.method = IB_MAD_METHOD_SET;
220	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
221	if (ib_pkey_is_invalid(service_pkey)) {
222		/* if given an invalid service_pkey - don't turn the PKEY compmask on */
223		user.comp_mask = IB_SR_COMPMASK_SID |
224		    IB_SR_COMPMASK_SGID |
225		    IB_SR_COMPMASK_SLEASE |
226		    IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME;
227	} else {
228		user.comp_mask = IB_SR_COMPMASK_SID |
229		    IB_SR_COMPMASK_SGID |
230		    IB_SR_COMPMASK_SPKEY |
231		    IB_SR_COMPMASK_SLEASE |
232		    IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME;
233	}
234	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
235	user.p_attr = &svc_rec;
236
237	status = osmv_query_sa(p_osmt->h_bind, &req);
238	if (status != IB_SUCCESS) {
239		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A03: "
240			"ib_query failed (%s)\n", ib_get_err_str(status));
241		goto Exit;
242	}
243
244	status = context.result.status;
245	if (status != IB_SUCCESS) {
246		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A04: "
247			"ib_query failed (%s)\n", ib_get_err_str(status));
248
249		if (status == IB_REMOTE_ERROR) {
250			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
251				"Remote error = %s\n",
252				ib_get_mad_status_str(osm_madw_get_mad_ptr
253						      (context.result.
254						       p_result_madw)));
255		}
256		goto Exit;
257	}
258
259	/*  Check service key on context to see if match */
260	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
261	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
262		"Comparing service key...\n" "return key is:\n");
263	for (i = 0; i <= 15; i++) {
264		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
265			"service_key sent[%u] = %u, service_key returned[%u] = %u\n",
266			i, service_key[i], i, p_rec->service_key[i]);
267	}
268	/*  since c15-0.1.14 not supported all key association queries should bring in return zero in service key */
269	if (memcmp(skey, p_rec->service_key, 16 * sizeof(uint8_t)) != 0) {
270		status = IB_REMOTE_ERROR;
271		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A33: "
272			"Data mismatch in service_key\n");
273		goto Exit;
274	}
275
276Exit:
277	if (context.result.p_result_madw != NULL) {
278		osm_mad_pool_put(&p_osmt->mad_pool,
279				 context.result.p_result_madw);
280		context.result.p_result_madw = NULL;
281	}
282
283	OSM_LOG_EXIT(&p_osmt->log);
284	return status;
285}
286
287/**********************************************************************
288 **********************************************************************/
289
290ib_api_status_t
291osmt_register_service_with_data(IN osmtest_t * const p_osmt,
292				IN ib_net64_t service_id,
293				IN ib_net16_t service_pkey,
294				IN ib_net32_t service_lease,
295				IN uint8_t service_key_lsb,
296				IN uint8_t * service_data8,
297				IN ib_net16_t * service_data16,
298				IN ib_net32_t * service_data32,
299				IN ib_net64_t * service_data64,
300				IN char *service_name)
301{
302	osmv_query_req_t req;
303	osmv_user_query_t user;
304	osmtest_req_context_t context;
305	ib_service_record_t svc_rec, *p_rec;
306	osm_log_t *p_log = &p_osmt->log;
307	ib_api_status_t status;
308	/*   ib_service_record_t* p_rec; */
309
310	OSM_LOG_ENTER(p_log);
311
312	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
313		"Registering service: name: %s id: 0x%" PRIx64 "\n",
314		service_name, cl_ntoh64(service_id));
315
316	memset(&req, 0, sizeof(req));
317	memset(&context, 0, sizeof(context));
318	memset(&user, 0, sizeof(user));
319	memset(&svc_rec, 0, sizeof(svc_rec));
320
321	/* set the new service record fields */
322	svc_rec.service_id = service_id;
323	svc_rec.service_pkey = service_pkey;
324	svc_rec.service_gid.unicast.prefix = 0;
325	svc_rec.service_gid.unicast.interface_id = p_osmt->local_port.port_guid;
326	svc_rec.service_lease = service_lease;
327	memset(&svc_rec.service_key, 0, 16 * sizeof(uint8_t));
328	svc_rec.service_key[0] = service_key_lsb;
329
330	/*  Copy data to service_data arrays */
331	memcpy(svc_rec.service_data8, service_data8, 16 * sizeof(uint8_t));
332	memcpy(svc_rec.service_data16, service_data16, 8 * sizeof(ib_net16_t));
333	memcpy(svc_rec.service_data32, service_data32, 4 * sizeof(ib_net32_t));
334	memcpy(svc_rec.service_data64, service_data64, 2 * sizeof(ib_net64_t));
335
336	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
337	memcpy(svc_rec.service_name, service_name,
338	       (strlen(service_name) + 1) * sizeof(char));
339
340	/* prepare the data used for this query */
341	/*  sa_mad_data.method = IB_MAD_METHOD_SET; */
342	/*  sa_mad_data.sm_key = 0; */
343
344	context.p_osmt = p_osmt;
345	req.query_context = &context;
346	req.query_type = OSMV_QUERY_USER_DEFINED;
347	req.pfn_query_cb = osmtest_query_res_cb;
348	req.p_query_input = &user;
349	req.flags = OSM_SA_FLAGS_SYNC;
350	req.sm_key = 0;
351	req.timeout_ms = p_osmt->opt.transaction_timeout;
352
353	user.method = IB_MAD_METHOD_SET;
354	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
355	if (ib_pkey_is_invalid(service_pkey)) {
356		/* if given an invalid service_pkey - don't turn the PKEY compmask on */
357		user.comp_mask = IB_SR_COMPMASK_SID |
358		    IB_SR_COMPMASK_SGID |
359		    IB_SR_COMPMASK_SLEASE |
360		    IB_SR_COMPMASK_SKEY |
361		    IB_SR_COMPMASK_SNAME |
362		    IB_SR_COMPMASK_SDATA8_0 |
363		    IB_SR_COMPMASK_SDATA8_1 |
364		    IB_SR_COMPMASK_SDATA16_0 |
365		    IB_SR_COMPMASK_SDATA16_1 |
366		    IB_SR_COMPMASK_SDATA32_0 |
367		    IB_SR_COMPMASK_SDATA32_1 |
368		    IB_SR_COMPMASK_SDATA64_0 | IB_SR_COMPMASK_SDATA64_1;
369	} else {
370		user.comp_mask = IB_SR_COMPMASK_SID |
371		    IB_SR_COMPMASK_SGID |
372		    IB_SR_COMPMASK_SPKEY |
373		    IB_SR_COMPMASK_SLEASE |
374		    IB_SR_COMPMASK_SKEY |
375		    IB_SR_COMPMASK_SNAME |
376		    IB_SR_COMPMASK_SDATA8_0 |
377		    IB_SR_COMPMASK_SDATA8_1 |
378		    IB_SR_COMPMASK_SDATA16_0 |
379		    IB_SR_COMPMASK_SDATA16_1 |
380		    IB_SR_COMPMASK_SDATA32_0 |
381		    IB_SR_COMPMASK_SDATA32_1 |
382		    IB_SR_COMPMASK_SDATA64_0 | IB_SR_COMPMASK_SDATA64_1;
383	}
384	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
385	user.p_attr = &svc_rec;
386
387	/*  Dump to Service Data b4 send */
388	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
389		"Dumping service data b4 send\n");
390	osm_dump_service_record(&p_osmt->log, &svc_rec, OSM_LOG_VERBOSE);
391
392	status = osmv_query_sa(p_osmt->h_bind, &req);
393	if (status != IB_SUCCESS) {
394		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A05: "
395			"ib_query failed (%s)\n", ib_get_err_str(status));
396		goto Exit;
397	}
398
399	status = context.result.status;
400
401	if (status != IB_SUCCESS) {
402		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A06: "
403			"ib_query failed (%s)\n", ib_get_err_str(status));
404
405		if (status == IB_REMOTE_ERROR) {
406			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
407				"Remote error = %s\n",
408				ib_get_mad_status_str(osm_madw_get_mad_ptr
409						      (context.result.
410						       p_result_madw)));
411		}
412		goto Exit;
413	}
414
415	/*  Check data on context to see if match */
416	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
417	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Comparing service data...\n");
418	if (memcmp(service_data8, p_rec->service_data8, 16 * sizeof(uint8_t)) !=
419	    0
420	    || memcmp(service_data16, p_rec->service_data16,
421		      8 * sizeof(uint16_t)) != 0
422	    || memcmp(service_data32, p_rec->service_data32,
423		      4 * sizeof(uint32_t)) != 0
424	    || memcmp(service_data64, p_rec->service_data64,
425		      2 * sizeof(uint64_t)) != 0) {
426		status = IB_REMOTE_ERROR;
427		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
428			"Data mismatch in service_data8\n");
429		goto Exit;
430	}
431
432Exit:
433	if (context.result.p_result_madw != NULL) {
434		osm_mad_pool_put(&p_osmt->mad_pool,
435				 context.result.p_result_madw);
436		context.result.p_result_madw = NULL;
437	}
438
439	OSM_LOG_EXIT(&p_osmt->log);
440	return status;
441}
442
443/**********************************************************************
444 **********************************************************************/
445
446ib_api_status_t
447osmt_get_service_by_id_and_name(IN osmtest_t * const p_osmt,
448				IN uint32_t rec_num,
449				IN ib_net64_t sid,
450				IN char *sr_name,
451				OUT ib_service_record_t * p_out_rec)
452{
453
454	ib_api_status_t status = IB_SUCCESS;
455	osmtest_req_context_t context;
456	osmv_query_req_t req;
457	ib_service_record_t svc_rec, *p_rec;
458	uint32_t num_recs = 0;
459	osmv_user_query_t user;
460
461	OSM_LOG_ENTER(&p_osmt->log);
462
463	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
464		"Getting service record: id: 0x%016" PRIx64
465		" and name: %s\n", cl_ntoh64(sid), sr_name);
466
467	/*
468	 * Do a blocking query for this record in the subnet.
469	 * The result is returned in the result field of the caller's
470	 * context structure.
471	 *
472	 * The query structures are locals.
473	 */
474	memset(&req, 0, sizeof(req));
475	memset(&context, 0, sizeof(context));
476
477	context.p_osmt = p_osmt;
478
479	/* prepare the data used for this query */
480	req.query_type = OSMV_QUERY_USER_DEFINED;
481	req.timeout_ms = p_osmt->opt.transaction_timeout;
482	req.retry_cnt = p_osmt->opt.retry_count;
483	req.flags = OSM_SA_FLAGS_SYNC;
484	req.query_context = &context;
485	req.pfn_query_cb = osmtest_query_res_cb;
486	req.sm_key = 0;
487
488	memset(&svc_rec, 0, sizeof(svc_rec));
489	memset(&user, 0, sizeof(user));
490	/* set the new service record fields */
491	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
492	memcpy(svc_rec.service_name, sr_name,
493	       (strlen(sr_name) + 1) * sizeof(char));
494	svc_rec.service_id = sid;
495	req.p_query_input = &user;
496
497	user.method = IB_MAD_METHOD_GET;
498	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
499	user.comp_mask = IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SNAME;
500	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
501	user.p_attr = &svc_rec;
502
503	status = osmv_query_sa(p_osmt->h_bind, &req);
504	if (status != IB_SUCCESS) {
505		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A07: "
506			"ib_query failed (%s)\n", ib_get_err_str(status));
507		goto Exit;
508	}
509
510	status = context.result.status;
511	num_recs = context.result.result_cnt;
512
513	if (status != IB_SUCCESS) {
514		char mad_stat_err[256];
515
516		/* If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
517		   then this is fine */
518		if (status == IB_REMOTE_ERROR)
519			strcpy(mad_stat_err,
520			       ib_get_mad_status_str(osm_madw_get_mad_ptr
521						     (context.result.
522						      p_result_madw)));
523		else
524			strcpy(mad_stat_err, ib_get_err_str(status));
525		if (status == IB_REMOTE_ERROR &&
526		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&
527		    rec_num == 0) {
528			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
529				"IS EXPECTED ERROR ^^^^\n");
530			status = IB_SUCCESS;
531		} else {
532			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A08: "
533				"Query failed: %s (%s)\n",
534				ib_get_err_str(status), mad_stat_err);
535			goto Exit;
536		}
537	}
538
539	if (rec_num && num_recs != rec_num) {
540		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
541			"Unmatched number of records: expected: %d, received: %d\n",
542			rec_num, num_recs);
543		status = IB_REMOTE_ERROR;
544		goto Exit;
545	}
546
547	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
548	*p_out_rec = *p_rec;
549
550	if (num_recs) {
551		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
552			"Found service record: name: %s id: 0x%016" PRIx64 "\n",
553			p_rec->service_name, cl_ntoh64(p_rec->service_id));
554
555		osm_dump_service_record(&p_osmt->log, p_rec, OSM_LOG_DEBUG);
556	}
557
558Exit:
559	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
560		"Expected and found %d records\n", rec_num);
561
562	if (context.result.p_result_madw != NULL) {
563		osm_mad_pool_put(&p_osmt->mad_pool,
564				 context.result.p_result_madw);
565		context.result.p_result_madw = NULL;
566	}
567
568	OSM_LOG_EXIT(&p_osmt->log);
569	return status;
570}
571
572/**********************************************************************
573 **********************************************************************/
574
575ib_api_status_t
576osmt_get_service_by_id(IN osmtest_t * const p_osmt,
577		       IN uint32_t rec_num,
578		       IN ib_net64_t sid, OUT ib_service_record_t * p_out_rec)
579{
580
581	ib_api_status_t status = IB_SUCCESS;
582	osmtest_req_context_t context;
583	osmv_query_req_t req;
584	ib_service_record_t svc_rec, *p_rec;
585	uint32_t num_recs = 0;
586	osmv_user_query_t user;
587
588	OSM_LOG_ENTER(&p_osmt->log);
589
590	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
591		"Getting service record: id: 0x%016" PRIx64 "\n",
592		cl_ntoh64(sid));
593
594	/*
595	 * Do a blocking query for this record in the subnet.
596	 * The result is returned in the result field of the caller's
597	 * context structure.
598	 *
599	 * The query structures are locals.
600	 */
601	memset(&req, 0, sizeof(req));
602	memset(&context, 0, sizeof(context));
603
604	context.p_osmt = p_osmt;
605
606	/* prepare the data used for this query */
607	req.query_type = OSMV_QUERY_USER_DEFINED;
608	req.timeout_ms = p_osmt->opt.transaction_timeout;
609	req.retry_cnt = p_osmt->opt.retry_count;
610	req.flags = OSM_SA_FLAGS_SYNC;
611	req.query_context = &context;
612	req.pfn_query_cb = osmtest_query_res_cb;
613	req.sm_key = 0;
614
615	memset(&svc_rec, 0, sizeof(svc_rec));
616	memset(&user, 0, sizeof(user));
617	/* set the new service record fields */
618	svc_rec.service_id = sid;
619	req.p_query_input = &user;
620
621	user.method = IB_MAD_METHOD_GET;
622	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
623	user.comp_mask = IB_SR_COMPMASK_SID;
624	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
625	user.p_attr = &svc_rec;
626
627	status = osmv_query_sa(p_osmt->h_bind, &req);
628	if (status != IB_SUCCESS) {
629		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A09: "
630			"ib_query failed (%s)\n", ib_get_err_str(status));
631		goto Exit;
632	}
633
634	status = context.result.status;
635	num_recs = context.result.result_cnt;
636
637	if (status != IB_SUCCESS) {
638		char mad_stat_err[256];
639
640		/* If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
641		   then this is fine */
642		if (status == IB_REMOTE_ERROR)
643			strcpy(mad_stat_err,
644			       ib_get_mad_status_str(osm_madw_get_mad_ptr
645						     (context.result.
646						      p_result_madw)));
647		else
648			strcpy(mad_stat_err, ib_get_err_str(status));
649
650		if (status == IB_REMOTE_ERROR &&
651		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&
652		    rec_num == 0) {
653			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
654				"IS EXPECTED ERROR ^^^^\n");
655			status = IB_SUCCESS;
656		} else {
657			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0A: "
658				"Query failed: %s (%s)\n",
659				ib_get_err_str(status), mad_stat_err);
660			goto Exit;
661		}
662	}
663
664	if (rec_num && num_recs != rec_num) {
665		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0B: "
666			"Unmatched number of records: expected: %d received: %d\n",
667			rec_num, num_recs);
668		status = IB_REMOTE_ERROR;
669		goto Exit;
670	}
671
672	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
673	*p_out_rec = *p_rec;
674
675	if (num_recs) {
676		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
677			"Found service record: name: %s id: 0x%016" PRIx64 "\n",
678			p_rec->service_name, cl_ntoh64(p_rec->service_id));
679
680		osm_dump_service_record(&p_osmt->log, p_rec, OSM_LOG_DEBUG);
681	}
682
683Exit:
684	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
685		"Expected and found %d records\n", rec_num);
686
687	if (context.result.p_result_madw != NULL) {
688		osm_mad_pool_put(&p_osmt->mad_pool,
689				 context.result.p_result_madw);
690		context.result.p_result_madw = NULL;
691	}
692
693	OSM_LOG_EXIT(&p_osmt->log);
694	return status;
695}
696
697/**********************************************************************
698 **********************************************************************/
699
700ib_api_status_t
701osmt_get_service_by_name_and_key(IN osmtest_t * const p_osmt,
702				 IN char *sr_name,
703				 IN uint32_t rec_num,
704				 IN uint8_t * skey,
705				 OUT ib_service_record_t * p_out_rec)
706{
707
708	ib_api_status_t status = IB_SUCCESS;
709	osmtest_req_context_t context;
710	osmv_query_req_t req;
711	ib_service_record_t svc_rec, *p_rec;
712	uint32_t num_recs = 0, i;
713	osmv_user_query_t user;
714
715	OSM_LOG_ENTER(&p_osmt->log);
716
717	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
718		"Getting service record: name: %s and key: "
719		"0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
720		sr_name, skey[0], skey[1], skey[2], skey[3], skey[4], skey[5],
721		skey[6], skey[7], skey[8], skey[9], skey[10], skey[11],
722		skey[12], skey[13], skey[14], skey[15]);
723
724	/*
725	 * Do a blocking query for this record in the subnet.
726	 * The result is returned in the result field of the caller's
727	 * context structure.
728	 *
729	 * The query structures are locals.
730	 */
731	memset(&req, 0, sizeof(req));
732	memset(&context, 0, sizeof(context));
733
734	context.p_osmt = p_osmt;
735
736	/* prepare the data used for this query */
737	req.query_type = OSMV_QUERY_USER_DEFINED;
738	req.timeout_ms = p_osmt->opt.transaction_timeout;
739	req.retry_cnt = p_osmt->opt.retry_count;
740	req.flags = OSM_SA_FLAGS_SYNC;
741	req.query_context = &context;
742	req.pfn_query_cb = osmtest_query_res_cb;
743	req.sm_key = 0;
744
745	memset(&svc_rec, 0, sizeof(svc_rec));
746	memset(&user, 0, sizeof(user));
747	/* set the new service record fields */
748	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
749	memcpy(svc_rec.service_name, sr_name,
750	       (strlen(sr_name) + 1) * sizeof(char));
751	for (i = 0; i <= 15; i++)
752		svc_rec.service_key[i] = skey[i];
753
754	req.p_query_input = &user;
755
756	user.method = IB_MAD_METHOD_GET;
757	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
758	user.comp_mask = IB_SR_COMPMASK_SNAME | IB_SR_COMPMASK_SKEY;
759	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
760	user.p_attr = &svc_rec;
761	status = osmv_query_sa(p_osmt->h_bind, &req);
762	if (status != IB_SUCCESS) {
763		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0C: "
764			"ib_query failed (%s)\n", ib_get_err_str(status));
765		goto Exit;
766	}
767
768	status = context.result.status;
769	num_recs = context.result.result_cnt;
770
771	if (status != IB_SUCCESS) {
772		char mad_stat_err[256];
773
774		/* If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
775		   then this is fine */
776		if (status == IB_REMOTE_ERROR)
777			strcpy(mad_stat_err,
778			       ib_get_mad_status_str(osm_madw_get_mad_ptr
779						     (context.result.
780						      p_result_madw)));
781		else
782			strcpy(mad_stat_err, ib_get_err_str(status));
783
784		if (status == IB_REMOTE_ERROR &&
785		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&
786		    rec_num == 0) {
787			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
788				"IS EXPECTED ERROR ^^^^\n");
789			status = IB_SUCCESS;
790		} else {
791			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0D: "
792				"Query failed:%s (%s)\n",
793				ib_get_err_str(status), mad_stat_err);
794			goto Exit;
795		}
796	}
797
798	if (rec_num && num_recs != rec_num) {
799		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
800			"Unmatched number of records: expected: %d, received: %d\n",
801			rec_num, num_recs);
802		status = IB_REMOTE_ERROR;
803		goto Exit;
804	}
805
806	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
807	*p_out_rec = *p_rec;
808
809	if (num_recs) {
810		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
811			"Found service record: name: %s id: 0x%016" PRIx64 "\n",
812			sr_name, cl_ntoh64(p_rec->service_id));
813
814		osm_dump_service_record(&p_osmt->log, p_rec, OSM_LOG_DEBUG);
815	}
816
817Exit:
818	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
819		"Expected and found %d records\n", rec_num);
820
821	if (context.result.p_result_madw != NULL) {
822		osm_mad_pool_put(&p_osmt->mad_pool,
823				 context.result.p_result_madw);
824		context.result.p_result_madw = NULL;
825	}
826
827	OSM_LOG_EXIT(&p_osmt->log);
828	return status;
829}
830
831/**********************************************************************
832 **********************************************************************/
833
834ib_api_status_t
835osmt_get_service_by_name(IN osmtest_t * const p_osmt,
836			 IN char *sr_name,
837			 IN uint32_t rec_num,
838			 OUT ib_service_record_t * p_out_rec)
839{
840
841	ib_api_status_t status = IB_SUCCESS;
842	osmtest_req_context_t context;
843	osmv_query_req_t req;
844	ib_service_record_t *p_rec;
845	ib_svc_name_t service_name;
846	uint32_t num_recs = 0;
847
848	OSM_LOG_ENTER(&p_osmt->log);
849
850	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
851		"Getting service record: name: %s\n", sr_name);
852
853	/*
854	 * Do a blocking query for this record in the subnet.
855	 * The result is returned in the result field of the caller's
856	 * context structure.
857	 *
858	 * The query structures are locals.
859	 */
860	memset(&req, 0, sizeof(req));
861	memset(&context, 0, sizeof(context));
862
863	context.p_osmt = p_osmt;
864
865	/* prepare the data used for this query */
866	req.query_type = OSMV_QUERY_SVC_REC_BY_NAME;
867	req.timeout_ms = p_osmt->opt.transaction_timeout;
868	req.retry_cnt = p_osmt->opt.retry_count;
869	req.flags = OSM_SA_FLAGS_SYNC;
870	req.query_context = &context;
871	req.pfn_query_cb = osmtest_query_res_cb;
872	req.sm_key = 0;
873
874	memset(service_name, 0, sizeof(service_name));
875	memcpy(service_name, sr_name, (strlen(sr_name) + 1) * sizeof(char));
876	req.p_query_input = service_name;
877
878	status = osmv_query_sa(p_osmt->h_bind, &req);
879	if (status != IB_SUCCESS) {
880		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0E: "
881			"ib_query failed (%s)\n", ib_get_err_str(status));
882		goto Exit;
883	}
884
885	status = context.result.status;
886	num_recs = context.result.result_cnt;
887
888	if (status != IB_SUCCESS) {
889		char mad_stat_err[256];
890
891		/*  If the failure is due to IB_SA_MAD_STATUS_NO_RECORDS and rec_num is 0,
892		   then this is fine */
893		if (status == IB_REMOTE_ERROR)
894			strcpy(mad_stat_err,
895			       ib_get_mad_status_str(osm_madw_get_mad_ptr
896						     (context.result.
897						      p_result_madw)));
898		else
899			strcpy(mad_stat_err, ib_get_err_str(status));
900
901		if (status == IB_REMOTE_ERROR &&
902		    !strcmp(mad_stat_err, "IB_SA_MAD_STATUS_NO_RECORDS") &&
903		    rec_num == 0) {
904			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
905				"IS EXPECTED ERROR ^^^^\n");
906			status = IB_SUCCESS;
907		} else {
908			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A0F: "
909				"Query failed: %s (%s)\n",
910				ib_get_err_str(status), mad_stat_err);
911			goto Exit;
912		}
913	}
914
915	if (rec_num && num_recs != rec_num) {
916		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A10: "
917			"Unmatched number of records: expected: %d, received: %d\n",
918			rec_num, num_recs);
919		status = IB_REMOTE_ERROR;
920		goto Exit;
921	}
922
923	p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, 0);
924	*p_out_rec = *p_rec;
925
926	if (num_recs) {
927		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
928			"Found service record: name: %s id: 0x%016" PRIx64 "\n",
929			sr_name, cl_ntoh64(p_rec->service_id));
930
931		osm_dump_service_record(&p_osmt->log, p_rec, OSM_LOG_DEBUG);
932	}
933
934Exit:
935	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
936		"Expected and found %d records\n", rec_num);
937
938	if (context.result.p_result_madw != NULL) {
939		osm_mad_pool_put(&p_osmt->mad_pool,
940				 context.result.p_result_madw);
941		context.result.p_result_madw = NULL;
942	}
943
944	OSM_LOG_EXIT(&p_osmt->log);
945	return status;
946}
947
948/**********************************************************************
949 **********************************************************************/
950
951#ifdef VENDOR_RMPP_SUPPORT
952ib_api_status_t
953osmt_get_all_services_and_check_names(IN osmtest_t * const p_osmt,
954				      IN ib_svc_name_t *
955				      const p_valid_service_names_arr,
956				      IN uint8_t num_of_valid_names,
957				      OUT uint32_t * num_services)
958{
959	ib_api_status_t status = IB_SUCCESS;
960	osmtest_req_context_t context;
961	osmv_query_req_t req;
962	ib_service_record_t *p_rec;
963	uint32_t num_recs = 0, i, j;
964	uint8_t *p_checked_names;
965
966	OSM_LOG_ENTER(&p_osmt->log);
967
968	/* Prepare tracker for the checked names */
969	p_checked_names =
970	    (uint8_t *) malloc(sizeof(uint8_t) * num_of_valid_names);
971	for (j = 0; j < num_of_valid_names; j++) {
972		p_checked_names[j] = 0;
973	}
974
975	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Getting all service records\n");
976
977	/*
978	 * Do a blocking query for this record in the subnet.
979	 * The result is returned in the result field of the caller's
980	 * context structure.
981	 *
982	 * The query structures are locals.
983	 */
984	memset(&req, 0, sizeof(req));
985	memset(&context, 0, sizeof(context));
986
987	context.p_osmt = p_osmt;
988
989	req.query_type = OSMV_QUERY_ALL_SVC_RECS;
990	req.timeout_ms = p_osmt->opt.transaction_timeout;
991	req.retry_cnt = p_osmt->opt.retry_count;
992	req.flags = OSM_SA_FLAGS_SYNC;
993	req.query_context = &context;
994	req.pfn_query_cb = osmtest_query_res_cb;
995	req.sm_key = 0;
996
997	status = osmv_query_sa(p_osmt->h_bind, &req);
998	if (status != IB_SUCCESS) {
999		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A12: "
1000			"ib_query failed (%s)\n", ib_get_err_str(status));
1001		goto Exit;
1002	}
1003
1004	status = context.result.status;
1005
1006	if (status != IB_SUCCESS) {
1007		if (status != IB_INVALID_PARAMETER) {
1008			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A13: "
1009				"ib_query failed (%s)\n", ib_get_err_str(status));
1010		}
1011		if (status == IB_REMOTE_ERROR) {
1012			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1013				"Remote error = %s\n",
1014				ib_get_mad_status_str(osm_madw_get_mad_ptr
1015						      (context.result.
1016						       p_result_madw)));
1017		}
1018		goto Exit;
1019	}
1020
1021	num_recs = context.result.result_cnt;
1022	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1023		"Received %u records\n", num_recs);
1024
1025	for (i = 0; i < num_recs; i++) {
1026		p_rec = osmv_get_query_svc_rec(context.result.p_result_madw, i);
1027		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1028			"Found service record: name: %s id: 0x%016" PRIx64 "\n",
1029			p_rec->service_name, cl_ntoh64(p_rec->service_id));
1030		osm_dump_service_record(&p_osmt->log, p_rec, OSM_LOG_VERBOSE);
1031		for (j = 0; j < num_of_valid_names; j++) {
1032			/* If the service names exist in the record, mark it as checked (1) */
1033			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1034				"-I- Comparing source name : >%s<, with record name : >%s<, idx : %d\n",
1035				p_valid_service_names_arr[j],
1036				p_rec->service_name, p_checked_names[j]);
1037			if (strcmp
1038			    ((char *)p_valid_service_names_arr[j],
1039			     (char *)p_rec->service_name) == 0) {
1040				OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1041					"-I- The service %s is valid\n",
1042					p_valid_service_names_arr[j]);
1043				p_checked_names[j] = 1;
1044				break;
1045			}
1046		}
1047	}
1048	/* Check that all service names have been identified */
1049	for (j = 0; j < num_of_valid_names; j++)
1050		if (p_checked_names[j] == 0) {
1051			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A14: "
1052				"Missing valid service: name: %s\n",
1053				p_valid_service_names_arr[j]);
1054			status = IB_ERROR;
1055			goto Exit;
1056		}
1057	*num_services = num_recs;
1058
1059Exit:
1060	if (context.result.p_result_madw != NULL) {
1061		osm_mad_pool_put(&p_osmt->mad_pool,
1062				 context.result.p_result_madw);
1063		context.result.p_result_madw = NULL;
1064	}
1065
1066	OSM_LOG_EXIT(&p_osmt->log);
1067	return status;
1068}
1069#endif
1070
1071/**********************************************************************
1072 **********************************************************************/
1073
1074ib_api_status_t
1075osmt_delete_service_by_name(IN osmtest_t * const p_osmt,
1076			    IN uint8_t IsServiceExist,
1077			    IN char *sr_name, IN uint32_t rec_num)
1078{
1079	osmv_query_req_t req;
1080	osmv_user_query_t user;
1081	osmtest_req_context_t context;
1082	ib_service_record_t svc_rec;
1083	ib_api_status_t status;
1084
1085	OSM_LOG_ENTER(&p_osmt->log);
1086
1087	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1088		"Trying to Delete service name: %s\n", sr_name);
1089
1090	memset(&svc_rec, 0, sizeof(svc_rec));
1091
1092	status = osmt_get_service_by_name(p_osmt, sr_name, rec_num, &svc_rec);
1093	if (status != IB_SUCCESS) {
1094		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A15: "
1095			"Failed to get service: name: %s\n", sr_name);
1096		goto ExitNoDel;
1097	}
1098
1099	memset(&req, 0, sizeof(req));
1100	memset(&context, 0, sizeof(context));
1101	memset(&user, 0, sizeof(user));
1102
1103	/* set the new service record fields */
1104	memset(svc_rec.service_name, 0, sizeof(svc_rec.service_name));
1105	memcpy(svc_rec.service_name, sr_name,
1106	       (strlen(sr_name) + 1) * sizeof(char));
1107
1108	/* prepare the data used for this query */
1109	context.p_osmt = p_osmt;
1110	req.timeout_ms = p_osmt->opt.transaction_timeout;
1111	req.query_context = &context;
1112	req.query_type = OSMV_QUERY_USER_DEFINED;	/*  basically a don't care here */
1113	req.pfn_query_cb = osmtest_query_res_cb;
1114	req.p_query_input = &user;
1115	req.flags = OSM_SA_FLAGS_SYNC;
1116	req.sm_key = 0;
1117
1118	user.method = IB_MAD_METHOD_DELETE;
1119	user.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
1120	user.comp_mask = IB_SR_COMPMASK_SNAME;
1121	user.attr_offset = ib_get_attr_offset(sizeof(ib_service_record_t));
1122	user.p_attr = &svc_rec;
1123
1124	status = osmv_query_sa(p_osmt->h_bind, &req);
1125	if (status != IB_SUCCESS) {
1126		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A16: "
1127			"ib_query failed (%s)\n", ib_get_err_str(status));
1128		goto Exit;
1129	}
1130
1131	status = context.result.status;
1132	if (IsServiceExist) {
1133		/* If IsServiceExist = 1 then we should succeed here */
1134		if (status != IB_SUCCESS) {
1135			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A17: "
1136				"ib_query failed (%s)\n",
1137				ib_get_err_str(status));
1138
1139			if (status == IB_REMOTE_ERROR) {
1140				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1141					"ERR 4A18: Remote error = %s\n",
1142					ib_get_mad_status_str
1143					(osm_madw_get_mad_ptr
1144					 (context.result.p_result_madw)));
1145			}
1146		}
1147	} else {
1148		/* If IsServiceExist = 0 then we should fail here */
1149		if (status == IB_SUCCESS) {
1150			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A19: "
1151				"Succeeded to delete service: %s which "
1152				"shouldn't exist", sr_name);
1153			status = IB_ERROR;
1154		} else {
1155			/* The deletion should have failed, since the service_name
1156			   shouldn't exist. */
1157			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
1158				"IS EXPECTED ERROR ^^^^\n");
1159			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1160				"Failed to delete service_name: %s\n", sr_name);
1161			status = IB_SUCCESS;
1162		}
1163	}
1164
1165Exit:
1166	if (context.result.p_result_madw != NULL) {
1167		osm_mad_pool_put(&p_osmt->mad_pool,
1168				 context.result.p_result_madw);
1169		context.result.p_result_madw = NULL;
1170	}
1171
1172ExitNoDel:
1173	OSM_LOG_EXIT(&p_osmt->log);
1174	return status;
1175}
1176
1177/**********************************************************************
1178 **********************************************************************/
1179
1180/*
1181 * Run a complete service records flow:
1182 * - register a service
1183 * - register a service (with a lease period)
1184 * - get a service by name
1185 * - get all services / must be 2
1186 * - delete a service
1187 * - get all services / must be 1
1188 * - wait for the lease to expire
1189 * - get all services / must be 0
1190 * - get / set service by data
1191 */
1192ib_api_status_t osmt_run_service_records_flow(IN osmtest_t * const p_osmt)
1193{
1194	ib_service_record_t srv_rec;
1195	ib_api_status_t status;
1196	uint8_t instance, i;
1197	uint8_t service_data8[16], service_key[16];
1198	ib_net16_t service_data16[8];
1199	ib_net32_t service_data32[4];
1200	ib_net64_t service_data64[2];
1201	uint64_t pid = getpid();
1202	uint64_t id[7];
1203	/* We use up to seven service names - we use the extra for bad flow */
1204	ib_svc_name_t service_name[7];
1205#ifdef VENDOR_RMPP_SUPPORT
1206	/* This array contain only the valid names after registering vs SM */
1207	ib_svc_name_t service_valid_names[3];
1208	uint32_t num_recs = 0;
1209#endif
1210
1211	OSM_LOG_ENTER(&p_osmt->log);
1212
1213	/* Init Service names */
1214	for (i = 0; i < 7; i++) {
1215#ifdef __WIN__
1216		uint64_t rand_val = rand() - (uint64_t) i;
1217#else
1218		uint64_t rand_val = random() - (uint64_t) i;
1219#endif
1220		id[i] = abs((int)(pid - rand_val));
1221		/* Just to be unique any place on any host */
1222		sprintf((char *)(service_name[i]),
1223			"osmt.srvc.%" PRIu64 ".%" PRIu64, rand_val, pid);
1224		/*printf("-I- Service Name is : %s, ID is : 0x%" PRIx64 "\n",service_name[i],id[i]); */
1225	}
1226
1227	status = osmt_register_service(p_osmt, cl_ntoh64(id[0]),	/*  IN ib_net64_t      service_id, */
1228				       IB_DEFAULT_PKEY,	/*  IN ib_net16_t      service_pkey, */
1229				       0xFFFFFFFF,	/*  IN ib_net32_t      service_lease, */
1230				       11,	/*  IN uint8_t         service_key_lsb, */
1231				       (char *)service_name[0]	/*  IN char            *service_name */
1232	    );
1233	if (status != IB_SUCCESS) {
1234		goto Exit;
1235	}
1236
1237	status = osmt_register_service(p_osmt, cl_ntoh64(id[1]),	/*  IN ib_net64_t      service_id, */
1238				       IB_DEFAULT_PKEY,	/*  IN ib_net16_t      service_pkey, */
1239				       cl_hton32(0x00000004),	/*  IN ib_net32_t     service_lease, */
1240				       11,	/*  IN uint8_t         service_key_lsb, */
1241				       (char *)service_name[1]	/*  IN char            *service_name */
1242	    );
1243	if (status != IB_SUCCESS) {
1244		goto Exit;
1245	}
1246
1247	status = osmt_register_service(p_osmt, cl_ntoh64(id[2]),	/*  IN ib_net64_t      service_id, */
1248				       0,	/*  IN ib_net16_t      service_pkey, */
1249				       0xFFFFFFFF,	/*  IN ib_net32_t      service_lease, */
1250				       11,	/* Remove Service Record IN uint8_t service_key_lsb, */
1251				       (char *)service_name[2]	/*  IN char            *service_name */
1252	    );
1253
1254	if (status != IB_SUCCESS) {
1255		goto Exit;
1256	}
1257
1258	/*  Generate 2 instances of service record with consecutive data */
1259	for (instance = 0; instance < 2; instance++) {
1260		/*  First, clear all arrays */
1261		memset(service_data8, 0, 16 * sizeof(uint8_t));
1262		memset(service_data16, 0, 8 * sizeof(uint16_t));
1263		memset(service_data32, 0, 4 * sizeof(uint32_t));
1264		memset(service_data64, 0, 2 * sizeof(uint64_t));
1265		service_data8[instance] = instance + 1;
1266		service_data16[instance] = cl_hton16(instance + 2);
1267		service_data32[instance] = cl_hton32(instance + 3);
1268		service_data64[instance] = cl_hton64(instance + 4);
1269		status = osmt_register_service_with_data(p_osmt, cl_ntoh64(id[3]),	/*  IN ib_net64_t      service_id, */
1270							 IB_DEFAULT_PKEY,	/*  IN ib_net16_t      service_pkey, */
1271							 cl_ntoh32(10),	/*  IN ib_net32_t      service_lease, */
1272							 12,	/*  IN uint8_t         service_key_lsb, */
1273							 service_data8, service_data16, service_data32, service_data64,	/* service data structures */
1274							 (char *)service_name[3]	/*  IN char            *service_name */
1275		    );
1276
1277		if (status != IB_SUCCESS) {
1278			goto Exit;
1279		}
1280
1281	}
1282
1283	/*  Trying to create service with zero key */
1284	memset(service_key, 0, 16 * sizeof(uint8_t));
1285	status = osmt_register_service_with_full_key(p_osmt, cl_ntoh64(id[5]),	/*  IN ib_net64_t      service_id, */
1286						     0,	/*  IN ib_net16_t      service_pkey, */
1287						     0xFFFFFFFF,	/*  IN ib_net32_t      service_lease, */
1288						     service_key,	/*  full service_key, */
1289						     (char *)service_name[5]	/*  IN char            *service_name */
1290	    );
1291
1292	if (status != IB_SUCCESS) {
1293		goto Exit;
1294	}
1295
1296	/*  Now update it with Unique key and different service name */
1297	for (i = 0; i <= 15; i++) {
1298		service_key[i] = i + 1;
1299	}
1300	status = osmt_register_service_with_full_key(p_osmt, cl_ntoh64(id[5]),	/*  IN ib_net64_t      service_id, */
1301						     0,	/*  IN ib_net16_t      service_pkey, */
1302						     0xFFFFFFFF,	/*  IN ib_net32_t      service_lease, */
1303						     service_key,	/* full service_key, */
1304						     (char *)service_name[6]	/*  IN char            *service_name */
1305	    );
1306	if (status != IB_SUCCESS) {
1307		goto Exit;
1308	}
1309
1310	/* Let OpenSM handle it */
1311	usleep(100);
1312
1313	/* Make sure service_name[0] exists */
1314	status = osmt_get_service_by_name(p_osmt,
1315					  (char *)service_name[0], 1, &srv_rec);
1316	if (status != IB_SUCCESS) {
1317		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1A: "
1318			"Fail to find service: name: %s\n",
1319			(char *)service_name[0]);
1320		status = IB_ERROR;
1321		goto Exit;
1322	}
1323
1324	/* Make sure service_name[1] exists */
1325	status = osmt_get_service_by_name(p_osmt,
1326					  (char *)service_name[1], 1, &srv_rec);
1327	if (status != IB_SUCCESS) {
1328		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1B: "
1329			"Fail to find service: name: %s\n",
1330			(char *)service_name[1]);
1331		status = IB_ERROR;
1332		goto Exit;
1333	}
1334
1335	/* Make sure service_name[2] exists */
1336	status = osmt_get_service_by_name(p_osmt,
1337					  (char *)service_name[2], 1, &srv_rec);
1338	if (status != IB_SUCCESS) {
1339		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1C: "
1340			"Fail to find service: name: %s\n",
1341			(char *)service_name[2]);
1342		status = IB_ERROR;
1343		goto Exit;
1344	}
1345
1346	/* Make sure service_name[3] exists. */
1347	/* After 10 seconds the service should not exist: service_lease = 10 */
1348	status = osmt_get_service_by_name(p_osmt,
1349					  (char *)service_name[3], 1, &srv_rec);
1350	if (status != IB_SUCCESS) {
1351		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1D: "
1352			"Fail to find service: name: %s\n",
1353			(char *)service_name[3]);
1354		status = IB_ERROR;
1355		goto Exit;
1356	}
1357
1358	sleep(10);
1359
1360	status = osmt_get_service_by_name(p_osmt,
1361					  (char *)service_name[3], 0, &srv_rec);
1362	if (status != IB_SUCCESS) {
1363		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1E: "
1364			"Found service: name: %s that should have been "
1365			"deleted due to service lease expiring\n",
1366			(char *)service_name[3]);
1367		status = IB_ERROR;
1368		goto Exit;
1369	}
1370
1371	/*  Check that for service: id[5] only one record exists */
1372	status = osmt_get_service_by_id(p_osmt, 1, cl_ntoh64(id[5]), &srv_rec);
1373	if (status != IB_SUCCESS) {
1374		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A1F: "
1375			"Found number of records != 1 for "
1376			"service: id: 0x%016" PRIx64 "\n", id[5]);
1377		status = IB_ERROR;
1378		goto Exit;
1379	}
1380
1381	/*  Bad Flow of Get with invalid Service ID: id[6] */
1382	status = osmt_get_service_by_id(p_osmt, 0, cl_ntoh64(id[6]), &srv_rec);
1383	if (status != IB_SUCCESS) {
1384		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A20: "
1385			"Found service: id: 0x%016" PRIx64 " "
1386			"that is invalid\n", id[6]);
1387		status = IB_ERROR;
1388		goto Exit;
1389	}
1390
1391	/*  Check by both id and service name: id[0], service_name[0] */
1392	status = osmt_get_service_by_id_and_name(p_osmt, 1, cl_ntoh64(id[0]),
1393						 (char *)service_name[0],
1394						 &srv_rec);
1395	if (status != IB_SUCCESS) {
1396		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A21: "
1397			"Fail to find service: id: 0x%016" PRIx64 " "
1398			"name: %s\n", id[0], (char *)service_name[0]);
1399		status = IB_ERROR;
1400		goto Exit;
1401	}
1402
1403	/*  Check by both id and service name: id[5], service_name[6] */
1404	status = osmt_get_service_by_id_and_name(p_osmt, 1, cl_ntoh64(id[5]),
1405						 (char *)service_name[6],
1406						 &srv_rec);
1407	if (status != IB_SUCCESS) {
1408		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A22: "
1409			"Fail to find service: id: 0x%016" PRIx64 " "
1410			"name: %s\n", id[5], (char *)service_name[6]);
1411		status = IB_ERROR;
1412		goto Exit;
1413	}
1414
1415	/* Bad Flow of Get with invalid name(service_name[3]) and valid ID(id[0]) */
1416	status = osmt_get_service_by_id_and_name(p_osmt, 0, cl_ntoh64(id[0]),
1417						 (char *)service_name[3],
1418						 &srv_rec);
1419	if (status != IB_SUCCESS) {
1420		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A23: "
1421			"Found service: id: 0x%016" PRIx64
1422			"name: %s which is an invalid service\n",
1423			id[0], (char *)service_name[3]);
1424		status = IB_ERROR;
1425		goto Exit;
1426	}
1427
1428	/*  Bad Flow of Get with unmatched name(service_name[5]) and id(id[3]) (both valid) */
1429	status = osmt_get_service_by_id_and_name(p_osmt, 0, cl_ntoh64(id[3]),
1430						 (char *)service_name[5],
1431						 &srv_rec);
1432	if (status != IB_SUCCESS) {
1433		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A24: "
1434			"Found service: id: 0x%016" PRIx64
1435			"name: %s which is an invalid service\n",
1436			id[3], (char *)service_name[5]);
1437		status = IB_ERROR;
1438		goto Exit;
1439	}
1440
1441	/* Bad Flow of Get with service name that doesn't exist (service_name[4]) */
1442	status = osmt_get_service_by_name(p_osmt,
1443					  (char *)service_name[4], 0, &srv_rec);
1444	if (status != IB_SUCCESS) {
1445		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A25: "
1446			"Found service: name: %s that shouldn't exist\n",
1447			(char *)service_name[4]);
1448		status = IB_ERROR;
1449		goto Exit;
1450	}
1451
1452	/*  Bad Flow : Check that getting service_name[5] brings no records since another service
1453	   has been updated with the same ID (service_name[6] */
1454	status = osmt_get_service_by_name(p_osmt,
1455					  (char *)service_name[5], 0, &srv_rec);
1456	if (status != IB_SUCCESS) {
1457		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A26: "
1458			"Found service: name: %s which is an "
1459			"invalid service\n", (char *)service_name[5]);
1460		status = IB_ERROR;
1461		goto Exit;
1462	}
1463
1464	/*  Check that getting service_name[6] by name ONLY is valid,
1465	   since we do not support key&name association, also trusted queries */
1466	status = osmt_get_service_by_name(p_osmt,
1467					  (char *)service_name[6], 1, &srv_rec);
1468	if (status != IB_SUCCESS) {
1469		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A27: "
1470			"Fail to find service: name: %s\n",
1471			(char *)service_name[6]);
1472		status = IB_ERROR;
1473		goto Exit;
1474	}
1475
1476	/*  Test Service Key */
1477	memset(service_key, 0, 16 * sizeof(uint8_t));
1478
1479	/* Check for service_name[5] with service_key=0 - the service shouldn't
1480	   exist with this name. */
1481	status = osmt_get_service_by_name_and_key(p_osmt,
1482						  (char *)service_name[5],
1483						  0, service_key, &srv_rec);
1484	if (status != IB_SUCCESS) {
1485		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A28: "
1486			"Found service: name: %s key:0 which is an "
1487			"invalid service (wrong name)\n",
1488			(char *)service_name[5]);
1489		status = IB_ERROR;
1490		goto Exit;
1491	}
1492
1493	/* Check for service_name[6] with service_key=0 - the service should
1494	   exist with different key. */
1495	status = osmt_get_service_by_name_and_key(p_osmt,
1496						  (char *)service_name[6],
1497						  0, service_key, &srv_rec);
1498	if (status != IB_SUCCESS) {
1499		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A29: "
1500			"Found service: name: %s key: 0 which is an "
1501			"invalid service (wrong service_key)\n",
1502			(char *)service_name[6]);
1503		status = IB_ERROR;
1504		goto Exit;
1505	}
1506
1507	/* check for service_name[6] with the correct service_key */
1508	for (i = 0; i <= 15; i++)
1509		service_key[i] = i + 1;
1510	status = osmt_get_service_by_name_and_key(p_osmt,
1511						  (char *)service_name[6],
1512						  1, service_key, &srv_rec);
1513	if (status != IB_SUCCESS) {
1514		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2A: "
1515			"Fail to find service: name: %s with "
1516			"correct service key\n", (char *)service_name[6]);
1517		status = IB_ERROR;
1518		goto Exit;
1519	}
1520#ifdef VENDOR_RMPP_SUPPORT
1521	/* These ar the only service_names which are valid */
1522	memcpy(&service_valid_names[0], &service_name[0], sizeof(uint8_t) * 64);
1523	memcpy(&service_valid_names[1], &service_name[2], sizeof(uint8_t) * 64);
1524	memcpy(&service_valid_names[2], &service_name[6], sizeof(uint8_t) * 64);
1525
1526	status =
1527	    osmt_get_all_services_and_check_names(p_osmt, service_valid_names,
1528						  3, &num_recs);
1529	if (status != IB_SUCCESS) {
1530		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2B: "
1531			"Fail to find all services that should exist\n");
1532		status = IB_ERROR;
1533		goto Exit;
1534	}
1535#endif
1536
1537	/* Delete service_name[0] */
1538	status = osmt_delete_service_by_name(p_osmt, 1,
1539					     (char *)service_name[0], 1);
1540	if (status != IB_SUCCESS) {
1541		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2C: "
1542			"Fail to delete service: name: %s\n",
1543			(char *)service_name[0]);
1544		status = IB_ERROR;
1545		goto Exit;
1546	}
1547
1548	/* Make sure deletion of service_name[0] succeeded */
1549	status = osmt_get_service_by_name(p_osmt,
1550					  (char *)service_name[0], 0, &srv_rec);
1551	if (status != IB_SUCCESS) {
1552		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2D: "
1553			"Found service: name: %s that was deleted\n",
1554			(char *)service_name[0]);
1555		status = IB_ERROR;
1556		goto Exit;
1557	}
1558
1559	/* Make sure service_name[1] doesn't exist (expired service lease) */
1560	status = osmt_get_service_by_name(p_osmt,
1561					  (char *)service_name[1], 0, &srv_rec);
1562	if (status != IB_SUCCESS) {
1563		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2E: "
1564			"Found service: name: %s that should have expired\n",
1565			(char *)service_name[1]);
1566		status = IB_ERROR;
1567		goto Exit;
1568	}
1569
1570	/* Make sure service_name[2] exists */
1571	status = osmt_get_service_by_name(p_osmt,
1572					  (char *)service_name[2], 1, &srv_rec);
1573	if (status != IB_SUCCESS) {
1574		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A2F: "
1575			"Fail to find service: name: %s\n",
1576			(char *)service_name[2]);
1577		status = IB_ERROR;
1578		goto Exit;
1579	}
1580
1581	/*  Bad Flow - try to delete non-existent service_name[5] */
1582	status = osmt_delete_service_by_name(p_osmt, 0,
1583					     (char *)service_name[5], 0);
1584	if (status != IB_SUCCESS) {
1585		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A30: "
1586			"Succeed to delete non-existent service: name: %s\n",
1587			(char *)service_name[5]);
1588		status = IB_ERROR;
1589		goto Exit;
1590	}
1591
1592	/* Delete service_name[2] */
1593	status = osmt_delete_service_by_name(p_osmt, 1,
1594					     (char *)service_name[2], 1);
1595	if (status != IB_SUCCESS) {
1596		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A31: "
1597			"Fail to delete service: name: %s\n",
1598			(char *)service_name[2]);
1599		status = IB_ERROR;
1600		goto Exit;
1601	}
1602
1603	/* Delete service_name[6] */
1604	status = osmt_delete_service_by_name(p_osmt, 1,
1605					     (char *)service_name[6], 1);
1606	if (status != IB_SUCCESS) {
1607		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 4A32: "
1608			"Failed to delete service name: %s\n",
1609			(char *)service_name[6]);
1610		goto Exit;
1611	}
1612
1613Exit:
1614	OSM_LOG_EXIT(&p_osmt->log);
1615	return status;
1616}
1617