2 * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 * Command line interface for osmtest.
44 #include <complib/cl_debug.h>
47 /********************************************************************
48 D E F I N E G L O B A L V A R I A B L E S
49 *********************************************************************/
52 This is the global osmtest object.
53 One osmtest object is required per subnet.
54 Future versions could support multiple subents by
55 instantiating more than one osmtest object.
57 #define GUID_ARRAY_SIZE 64
58 #define OSMT_DEFAULT_RETRY_COUNT 3
59 #define OSMT_DEFAULT_TRANS_TIMEOUT_MILLISEC 1000
60 #define OSMT_DEFAULT_TRAP_WAIT_TIMEOUT_SEC 10
61 #define INVALID_GUID (0xFFFFFFFFFFFFFFFFULL)
63 /**********************************************************************
64 **********************************************************************/
65 boolean_t osmt_is_debug(void)
67 #if defined( _DEBUG_ )
71 #endif /* defined( _DEBUG_ ) */
74 /**********************************************************************
75 **********************************************************************/
76 void show_usage(void);
81 ("\n------- osmtest - Usage and options ----------------------\n");
82 printf("Usage: osmtest [options]\n");
84 printf("-f <c|a|v|s|e|f|m|q|t>\n"
85 "--flow <c|a|v|s|e|f|m|q|t>\n"
86 " This option directs osmtest to run a specific flow:\n"
88 " c = create an inventory file with all nodes, ports and paths\n"
89 " a = run all validation tests (expecting an input inventory)\n"
90 " v = only validate the given inventory file\n"
91 " s = run service registration, deregistration, and lease test\n"
92 " e = run event forwarding test\n"
93 " f = flood the SA with queries according to the stress mode\n"
94 " m = multicast flow\n"
95 " q = QoS info: dump VLArb and SLtoVL tables\n"
96 " t = run trap 64/65 flow (this flow requires running of external tool)\n"
97 " (default is all flows except QoS)\n\n");
99 printf("-w <trap_wait_time>\n"
100 "--wait <trap_wait_time>\n"
101 " This option specifies the wait time for trap 64/65 in seconds\n"
102 " It is used only when running -f t - the trap 64/65 flow\n"
103 " (default to 10 sec)\n\n");
104 printf("-d <number>\n"
106 " This option specifies a debug option\n"
107 " These options are not normally needed\n"
108 " The number following -d selects the debug\n"
109 " option to enable as follows:\n"
111 " --- -----------------\n"
113 " -d1 - Do not scan/compare path records.\n"
114 " -d2 - Force log flushing after each log message.\n"
115 " Without -d, no debug options are enabled\n\n");
116 printf("-m <LID in hex>\n"
117 "--max_lid <LID in hex>\n"
118 " This option specifies the maximal LID number to be searched\n"
119 " for during inventory file build (default to 100)\n\n");
120 printf("-g <GUID in hex>\n"
121 "--guid <GUID in hex>\n"
122 " This option specifies the local port GUID value\n"
123 " with which osmtest should bind. osmtest may be\n"
124 " bound to 1 port at a time\n\n");
127 " This option displays a menu of possible local port GUID values\n"
128 " with which osmtest could bind\n\n");
130 "--help\n" " Display this usage info then exit\n\n");
131 printf("-i <filename>\n"
132 "--inventory <filename>\n"
133 " This option specifies the name of the inventory file\n"
134 " Normally, osmtest expects to find an inventory file,\n"
135 " which osmtest uses to validate real-time information\n"
136 " received from the SA during testing\n"
137 " If -i is not specified, osmtest defaults to the file\n"
139 " See -c option for related information\n\n");
142 " This option runs the specified stress test instead\n"
143 " of the normal test suite\n"
144 " Stress test options are as follows:\n"
146 " --- -----------------\n"
147 " -s1 - Single-MAD response SA queries\n"
148 " -s2 - Multi-MAD (RMPP) response SA queries\n"
149 " -s3 - Multi-MAD (RMPP) Path Record SA queries\n"
150 " Without -s, stress testing is not performed\n\n");
153 " This option specify length of Multicast test:\n"
155 " --- -----------------\n"
156 " -M1 - Short Multicast Flow (default) - single mode\n"
157 " -M2 - Short Multicast Flow - multiple mode\n"
158 " -M3 - Long Multicast Flow - single mode\n"
159 " -M4 - Long Multicast Flow - multiple mode\n"
160 " Single mode - Osmtest is tested alone, with no other\n"
161 " apps that interact with OpenSM MC\n"
162 " Multiple mode - Could be run with other apps using MC with\n"
164 " Without -M, default flow testing is performed\n\n");
166 printf("-t <milliseconds>\n"
167 " This option specifies the time in milliseconds\n"
168 " used for transaction timeouts\n"
169 " Specifying -t 0 disables timeouts\n"
170 " Without -t, osmtest defaults to a timeout value of\n"
174 " This option defines the log to be the given file\n"
175 " By default the log goes to stdout\n\n");
177 " This option increases the log verbosity level\n"
178 " The -v option may be specified multiple times\n"
179 " to further increase the verbosity level\n"
180 " See the -vf option for more information about.\n"
181 " log verbosity\n\n");
183 " This option sets the maximum verbosity level and\n"
184 " forces log flushing\n"
185 " The -V is equivalent to '-vf 0xFF -d 2'\n"
186 " See the -vf option for more information about.\n"
187 " log verbosity\n\n");
188 printf("-vf <flags>\n"
189 " This option sets the log verbosity level\n"
190 " A flags field must follow the -vf option\n"
191 " A bit set/clear in the flags enables/disables a\n"
192 " specific log level as follows:\n"
193 " BIT LOG LEVEL ENABLED\n"
194 " ---- -----------------\n"
195 " 0x01 - ERROR (error messages)\n"
196 " 0x02 - INFO (basic messages, low volume)\n"
197 " 0x04 - VERBOSE (interesting stuff, moderate volume)\n"
198 " 0x08 - DEBUG (diagnostic, high volume)\n"
199 " 0x10 - FUNCS (function entry/exit, very high volume)\n"
200 " 0x20 - FRAMES (dumps all SMP and GMP frames)\n"
201 " 0x40 - currently unused\n"
202 " 0x80 - currently unused\n"
203 " Without -vf, osmtest defaults to ERROR + INFO (0x3)\n"
204 " Specifying -vf 0 disables all messages\n"
205 " Specifying -vf 0xFF enables all messages (see -V)\n"
206 " High verbosity levels may require increasing\n"
207 " the transaction timeout with the -t option\n\n");
210 /**********************************************************************
211 **********************************************************************/
212 static void print_all_guids(IN osmtest_t * p_osmt);
213 static void print_all_guids(IN osmtest_t * p_osmt)
215 ib_api_status_t status;
216 uint32_t num_ports = GUID_ARRAY_SIZE;
217 ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
221 Call the transport layer for a list of local port
225 osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array,
227 if (status != IB_SUCCESS) {
228 printf("\nError from osm_vendor_get_all_port_attr (%x)\n",
233 printf("\nListing GUIDs:\n");
234 for (i = 0; i < num_ports; i++)
235 printf("Port %i: 0x%" PRIx64 "\n", i,
236 cl_hton64(attr_array[i].port_guid));
239 /**********************************************************************
240 **********************************************************************/
241 ib_net64_t get_port_guid(IN osmtest_t * p_osmt, uint64_t port_guid)
243 ib_api_status_t status;
244 uint32_t num_ports = GUID_ARRAY_SIZE;
245 ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
249 Call the transport layer for a list of local port
252 /* "local ports" is(?) phys, shouldn't this exclude port 0 then ? */
254 osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array,
256 if (status != IB_SUCCESS) {
257 printf("\nError from osm_vendor_get_all_port_attr (%x)\n",
262 if (num_ports == 1) {
263 printf("using default guid 0x%" PRIx64 "\n",
264 cl_hton64(attr_array[0].port_guid));
265 return (attr_array[0].port_guid);
268 for (i = 0; i < num_ports; i++) {
269 if (attr_array[i].port_guid == port_guid ||
270 (!port_guid && attr_array[i].link_state > IB_LINK_DOWN))
271 return attr_array[i].port_guid;
277 /**********************************************************************
278 **********************************************************************/
279 int main(int argc, char *argv[])
281 static osmtest_t osm_test;
282 osmtest_opt_t opt = { 0 };
284 uint16_t max_lid = 100;
285 ib_api_status_t status;
286 uint32_t log_flags = OSM_LOG_ERROR | OSM_LOG_INFO;
287 int32_t vendor_debug = 0;
289 uint32_t next_option;
290 const char *const short_option = "f:l:m:M:d:g:s:t:i:pcvVh";
293 * In the array below, the 2nd parameter specified the number
294 * of arguments as follows:
299 const struct option long_option[] = {
300 {"create", 0, NULL, 'c'},
301 {"debug", 1, NULL, 'd'},
302 {"flow", 1, NULL, 'f'},
303 {"wait", 1, NULL, 'w'},
304 {"inventory", 1, NULL, 'i'},
305 {"max_lid", 1, NULL, 'm'},
306 {"guid", 2, NULL, 'g'},
307 {"port", 0, NULL, 'p'},
308 {"help", 0, NULL, 'h'},
309 {"stress", 1, NULL, 's'},
310 {"Multicast_Mode", 1, NULL, 'M'},
311 {"timeout", 1, NULL, 't'},
312 {"verbose", 0, NULL, 'v'},
313 {"log_file", 1, NULL, 'l'},
314 {"vf", 1, NULL, 'x'},
317 {NULL, 0, NULL, 0} /* Required at end of array */
320 /* Make sure that the opensm, complib and osmtest were compiled using
321 same modes (debug/free) */
322 if (osm_is_debug() != cl_is_debug() || osm_is_debug() != osmt_is_debug()
323 || osmt_is_debug() != cl_is_debug()) {
325 "-E- OpenSM, Complib and OsmTest were compiled using different modes\n");
327 "-E- OpenSM debug:%d Complib debug:%d OsmTest debug:%d \n",
328 osm_is_debug(), cl_is_debug(), osmt_is_debug());
332 opt.transaction_timeout = OSMT_DEFAULT_TRANS_TIMEOUT_MILLISEC;
333 opt.wait_time = OSMT_DEFAULT_TRAP_WAIT_TIMEOUT_SEC;
334 opt.retry_count = OSMT_DEFAULT_RETRY_COUNT;
335 opt.force_log_flush = FALSE;
340 opt.ignore_path_records = FALSE; /* Do path Records too */
341 opt.flow = OSMT_FLOW_ALL; /* run all validation tests */
342 strcpy(flow_name, "All Validations");
343 strcpy(opt.file_name, "osmtest.dat");
345 printf("\nCommand Line Arguments\n");
347 next_option = getopt_long_only(argc, argv, short_option,
349 switch (next_option) {
352 * Create the inventory file.
355 printf("\tCreating inventory file\n");
360 * Specifies inventory file name.
362 if (strlen(optarg) > OSMTEST_FILE_PATH_MAX)
364 ("\nError: path name too long (ignored)\n");
366 strcpy(opt.file_name, optarg);
368 printf("\tFile = %s\n", opt.file_name);
375 if (strlen(optarg) > OSMTEST_FILE_PATH_MAX)
377 ("\nError: path name too long (ignored)\n");
379 strcpy(flow_name, optarg);
381 if (!strcmp("c", optarg)) {
382 strcpy(flow_name, "Create Inventory");
383 opt.flow = OSMT_FLOW_CREATE_INVENTORY;
384 } else if (!strcmp("v", optarg)) {
385 strcpy(flow_name, "Validate Inventory");
386 opt.flow = OSMT_FLOW_VALIDATE_INVENTORY;
387 } else if (!strcmp("s", optarg)) {
388 strcpy(flow_name, "Services Registration");
389 opt.flow = OSMT_FLOW_SERVICE_REGISTRATION;
390 } else if (!strcmp("e", optarg)) {
391 strcpy(flow_name, "Event Forwarding");
392 opt.flow = OSMT_FLOW_EVENT_FORWARDING;
393 } else if (!strcmp("f", optarg)) {
394 strcpy(flow_name, "Stress SA");
395 opt.flow = OSMT_FLOW_STRESS_SA;
396 } else if (!strcmp("m", optarg)) {
397 strcpy(flow_name, "Multicast");
398 opt.flow = OSMT_FLOW_MULTICAST;
399 } else if (!strcmp("q", optarg)) {
400 strcpy(flow_name, "QoS: VLArb and SLtoVL");
401 opt.flow = OSMT_FLOW_QOS;
402 } else if (!strcmp("t", optarg)) {
403 strcpy(flow_name, "Trap 64/65");
404 opt.flow = OSMT_FLOW_TRAP;
405 } else if (!strcmp("a", optarg)) {
406 strcpy(flow_name, "All Validations");
407 opt.flow = OSMT_FLOW_ALL;
409 printf("\nError: unknown flow %s\n", flow_name);
416 * Specifies trap 64/65 wait time
418 CL_ASSERT(strtol(optarg, NULL, 0) < 0x100);
419 opt.wait_time = (uint8_t) strtol(optarg, NULL, 0);
420 printf("\tTrap 64/65 wait time = %d\n", opt.wait_time);
425 * Specifies the max LID to search for during exploration.
427 max_lid = atoi(optarg);
428 printf("\tMAX-LID %u\n", max_lid);
433 * Specifies port guid with which to bind.
435 guid = cl_hton64(strtoull(optarg, NULL, 16));
436 printf(" Guid <0x%" PRIx64 ">\n", cl_hton64(guid));
441 * Display current port guids
448 * Specifies transaction timeout.
450 opt.transaction_timeout = strtol(optarg, NULL, 0);
451 printf("\tTransaction timeout = %d\n",
452 opt.transaction_timeout);
456 opt.log_file = optarg;
457 printf("\tLog File:%s\n", opt.log_file);
462 * Increases log verbosity.
464 log_flags = (log_flags << 1) | 1;
465 printf("\tVerbose option -v (log flags = 0x%X)\n",
471 * Specifies maximum log verbosity.
473 log_flags = 0xFFFFFFFF;
474 opt.force_log_flush = TRUE;
475 printf("\tEnabling maximum log verbosity\n");
480 * Perform stress test.
482 opt.stress = strtol(optarg, NULL, 0);
483 printf("\tStress test enabled: ");
484 switch (opt.stress) {
486 printf("Small SA queries\n");
489 printf("Large SA queries\n");
492 printf("Large Path Record SA queries\n");
495 printf("Unknown value %u (ignored)\n",
504 * Perform multicast test.
506 opt.mmode = strtol(optarg, NULL, 0);
507 printf("\tMulticast test enabled: ");
511 ("Short MC Flow - single mode (default)\n");
514 printf("Short MC Flow - multiple mode\n");
517 printf("Long MC Flow - single mode\n");
520 printf("Long MC Flow - multiple mode\n");
523 printf("Unknown value %u (ignored)\n",
534 printf("\tDebug Option: ");
535 switch (strtol(optarg, NULL, 0)) {
537 printf("Ignore Path Records\n");
538 opt.ignore_path_records = TRUE;
541 printf("Force Log Flush\n");
542 opt.force_log_flush = TRUE;
545 /* Used to be memory tracking */
547 printf("Unknown value %ld (ignored)\n",
548 strtol(optarg, NULL, 0));
558 log_flags = strtol(optarg, NULL, 0);
560 ("\t\t\t\tVerbose option -vf (log flags = 0x%X)\n",
565 printf("Done with args\n");
568 default: /* something wrong */
573 while (next_option != -1);
575 printf("\tFlow = %s\n", flow_name);
578 osm_vendor_set_debug(osm_test.p_vendor, vendor_debug);
582 status = osmtest_init(&osm_test, &opt, (osm_log_level_t) log_flags);
583 if (status != IB_SUCCESS) {
584 printf("\nError from osmtest_init: %s\n",
585 ib_get_err_str(status));
588 if (cl_hton64(guid) == cl_hton64(INVALID_GUID)) {
589 print_all_guids(&osm_test);
595 If the user didn't specify a GUID on the command line,
596 then get a port GUID value with which to bind.
598 if (guid == 0 && !(guid = get_port_guid(&osm_test, guid))) {
599 printf("\nError: port guid 0x%" PRIx64 " not found\n", guid);
604 * Guid may be zero going into this function if the user
605 * hasn't specified a binding port on the command line.
607 status = osmtest_bind(&osm_test, max_lid, guid);
608 if (status != IB_SUCCESS)
611 status = osmtest_run(&osm_test);
612 if (status != IB_SUCCESS) {
613 printf("OSMTEST: TEST \"%s\" FAIL\n", flow_name);
615 printf("OSMTEST: TEST \"%s\" PASS\n", flow_name);
617 osmtest_destroy(&osm_test);