]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/osmtest/main.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / osmtest / main.c
1 /*
2  * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4  *
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:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
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.
23  *
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
31  * SOFTWARE.
32  *
33  */
34
35 /*
36  * Abstract:
37  *      Command line interface for osmtest.
38  *
39  */
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <getopt.h>
44 #include <complib/cl_debug.h>
45 #include "osmtest.h"
46
47 /********************************************************************
48        D E F I N E    G L O B A L    V A R I A B L E S
49 *********************************************************************/
50
51 /*
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.
56 */
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)
62
63 /**********************************************************************
64  **********************************************************************/
65 boolean_t osmt_is_debug(void)
66 {
67 #if defined( _DEBUG_ )
68         return TRUE;
69 #else
70         return FALSE;
71 #endif                          /* defined( _DEBUG_ ) */
72 }
73
74 /**********************************************************************
75  **********************************************************************/
76 void show_usage(void);
77
78 void show_usage()
79 {
80         printf
81             ("\n------- osmtest - Usage and options ----------------------\n");
82         printf("Usage:    osmtest [options]\n");
83         printf("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"
87                "          FLOW  DESCRIPTION\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");
98
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"
105                "--debug <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"
110                "          OPT   Description\n"
111                "          ---    -----------------\n"
112                "          -d0  - Unused.\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");
125         printf("-p \n"
126                "--port\n"
127                "          This option displays a menu of possible local port GUID values\n"
128                "          with which osmtest could bind\n\n");
129         printf("-h\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"
138                "          'osmtest.dat'\n"
139                "          See -c option for related information\n\n");
140         printf("-s\n"
141                "--stress\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"
145                "          OPT    Description\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");
151         printf("-M\n"
152                "--Multicast_Mode\n"
153                "          This option specify length of Multicast test:\n"
154                "          OPT    Description\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"
163                "   OpenSM."
164                " Without -M, default flow testing is performed\n\n");
165
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"
171                "          1 second\n\n");
172         printf("-l\n"
173                "--log_file\n"
174                "          This option defines the log to be the given file\n"
175                "          By default the log goes to stdout\n\n");
176         printf("-v\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");
182         printf("-V\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");
208 }
209
210 /**********************************************************************
211  **********************************************************************/
212 static void print_all_guids(IN osmtest_t * p_osmt);
213 static void print_all_guids(IN osmtest_t * p_osmt)
214 {
215         ib_api_status_t status;
216         uint32_t num_ports = GUID_ARRAY_SIZE;
217         ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
218         int i;
219
220         /*
221            Call the transport layer for a list of local port
222            GUID values.
223          */
224         status =
225             osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array,
226                                          &num_ports);
227         if (status != IB_SUCCESS) {
228                 printf("\nError from osm_vendor_get_all_port_attr (%x)\n",
229                        status);
230                 return;
231         }
232
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));
237 }
238
239 /**********************************************************************
240  **********************************************************************/
241 ib_net64_t get_port_guid(IN osmtest_t * p_osmt, uint64_t port_guid)
242 {
243         ib_api_status_t status;
244         uint32_t num_ports = GUID_ARRAY_SIZE;
245         ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
246         int i;
247
248         /*
249            Call the transport layer for a list of local port
250            GUID values.
251          */
252 /* "local ports" is(?) phys, shouldn't this exclude port 0 then ? */
253         status =
254             osm_vendor_get_all_port_attr(p_osmt->p_vendor, attr_array,
255                                          &num_ports);
256         if (status != IB_SUCCESS) {
257                 printf("\nError from osm_vendor_get_all_port_attr (%x)\n",
258                        status);
259                 return (0);
260         }
261
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);
266         }
267
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;
272         }
273
274         return 0;
275 }
276
277 /**********************************************************************
278  **********************************************************************/
279 int main(int argc, char *argv[])
280 {
281         static osmtest_t osm_test;
282         osmtest_opt_t opt = { 0 };
283         ib_net64_t guid = 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;
288         char flow_name[64];
289         uint32_t next_option;
290         const char *const short_option = "f:l:m:M:d:g:s:t:i:pcvVh";
291
292         /*
293          * In the array below, the 2nd parameter specified the number
294          * of arguments as follows:
295          * 0: no arguments
296          * 1: argument
297          * 2: optional
298          */
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'},
315                 {"V", 0, NULL, 'V'},
316
317                 {NULL, 0, NULL, 0}      /* Required at end of array */
318         };
319
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()) {
324                 fprintf(stderr,
325                         "-E- OpenSM, Complib and OsmTest were compiled using different modes\n");
326                 fprintf(stderr,
327                         "-E- OpenSM debug:%d Complib debug:%d OsmTest debug:%d \n",
328                         osm_is_debug(), cl_is_debug(), osmt_is_debug());
329                 exit(1);
330         }
331
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;
336         opt.stress = 0;
337         opt.log_file = NULL;
338         opt.create = FALSE;
339         opt.mmode = 1;
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");
344
345         printf("\nCommand Line Arguments\n");
346         do {
347                 next_option = getopt_long_only(argc, argv, short_option,
348                                                long_option, NULL);
349                 switch (next_option) {
350                 case 'c':
351                         /*
352                          * Create the inventory file.
353                          */
354                         opt.create = TRUE;
355                         printf("\tCreating inventory file\n");
356                         break;
357
358                 case 'i':
359                         /*
360                          * Specifies inventory file name.
361                          */
362                         if (strlen(optarg) > OSMTEST_FILE_PATH_MAX)
363                                 printf
364                                     ("\nError: path name too long (ignored)\n");
365                         else
366                                 strcpy(opt.file_name, optarg);
367
368                         printf("\tFile = %s\n", opt.file_name);
369                         break;
370
371                 case 'f':
372                         /*
373                          * Specifies Flow .
374                          */
375                         if (strlen(optarg) > OSMTEST_FILE_PATH_MAX)
376                                 printf
377                                     ("\nError: path name too long (ignored)\n");
378                         else
379                                 strcpy(flow_name, optarg);
380
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;
408                         } else {
409                                 printf("\nError: unknown flow %s\n", flow_name);
410                                 exit(2);
411                         }
412                         break;
413
414                 case 'w':
415                         /*
416                          * Specifies trap 64/65 wait time
417                          */
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);
421                         break;
422
423                 case 'm':
424                         /*
425                          * Specifies the max LID to search for during exploration.
426                          */
427                         max_lid = atoi(optarg);
428                         printf("\tMAX-LID %u\n", max_lid);
429                         break;
430
431                 case 'g':
432                         /*
433                          * Specifies port guid with which to bind.
434                          */
435                         guid = cl_hton64(strtoull(optarg, NULL, 16));
436                         printf(" Guid <0x%" PRIx64 ">\n", cl_hton64(guid));
437                         break;
438
439                 case 'p':
440                         /*
441                          * Display current port guids
442                          */
443                         guid = INVALID_GUID;
444                         break;
445
446                 case 't':
447                         /*
448                          * Specifies transaction timeout.
449                          */
450                         opt.transaction_timeout = strtol(optarg, NULL, 0);
451                         printf("\tTransaction timeout = %d\n",
452                                opt.transaction_timeout);
453                         break;
454
455                 case 'l':
456                         opt.log_file = optarg;
457                         printf("\tLog File:%s\n", opt.log_file);
458                         break;
459
460                 case 'v':
461                         /*
462                          * Increases log verbosity.
463                          */
464                         log_flags = (log_flags << 1) | 1;
465                         printf("\tVerbose option -v (log flags = 0x%X)\n",
466                                log_flags);
467                         break;
468
469                 case 'V':
470                         /*
471                          * Specifies maximum log verbosity.
472                          */
473                         log_flags = 0xFFFFFFFF;
474                         opt.force_log_flush = TRUE;
475                         printf("\tEnabling maximum log verbosity\n");
476                         break;
477
478                 case 's':
479                         /*
480                          * Perform stress test.
481                          */
482                         opt.stress = strtol(optarg, NULL, 0);
483                         printf("\tStress test enabled: ");
484                         switch (opt.stress) {
485                         case 1:
486                                 printf("Small SA queries\n");
487                                 break;
488                         case 2:
489                                 printf("Large SA queries\n");
490                                 break;
491                         case 3:
492                                 printf("Large Path Record SA queries\n");
493                                 break;
494                         default:
495                                 printf("Unknown value %u (ignored)\n",
496                                        opt.stress);
497                                 opt.stress = 0;
498                                 break;
499                         }
500                         break;
501
502                 case 'M':
503                         /*
504                          * Perform multicast test.
505                          */
506                         opt.mmode = strtol(optarg, NULL, 0);
507                         printf("\tMulticast test enabled: ");
508                         switch (opt.mmode) {
509                         case 1:
510                                 printf
511                                     ("Short MC Flow - single mode (default)\n");
512                                 break;
513                         case 2:
514                                 printf("Short MC Flow - multiple mode\n");
515                                 break;
516                         case 3:
517                                 printf("Long MC Flow - single mode\n");
518                                 break;
519                         case 4:
520                                 printf("Long MC Flow - multiple mode\n");
521                                 break;
522                         default:
523                                 printf("Unknown value %u (ignored)\n",
524                                        opt.stress);
525                                 opt.mmode = 0;
526                                 break;
527                         }
528                         break;
529
530                 case 'd':
531                         /*
532                          * Debug Options
533                          */
534                         printf("\tDebug Option: ");
535                         switch (strtol(optarg, NULL, 0)) {
536                         case 1:
537                                 printf("Ignore Path Records\n");
538                                 opt.ignore_path_records = TRUE;
539                                 break;
540                         case 2:
541                                 printf("Force Log Flush\n");
542                                 opt.force_log_flush = TRUE;
543                                 break;
544                         case 3:
545                                 /* Used to be memory tracking */
546                         default:
547                                 printf("Unknown value %ld (ignored)\n",
548                                        strtol(optarg, NULL, 0));
549                                 break;
550                         }
551                         break;
552
553                 case 'h':
554                         show_usage();
555                         return 0;
556
557                 case 'x':
558                         log_flags = strtol(optarg, NULL, 0);
559                         printf
560                             ("\t\t\t\tVerbose option -vf (log flags = 0x%X)\n",
561                              log_flags);
562                         break;
563
564                 case -1:
565                         printf("Done with args\n");
566                         break;
567
568                 default:        /* something wrong */
569                         abort();
570                 }
571
572         }
573         while (next_option != -1);
574
575         printf("\tFlow = %s\n", flow_name);
576
577         if (vendor_debug)
578                 osm_vendor_set_debug(osm_test.p_vendor, vendor_debug);
579
580         complib_init();
581
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));
586                 goto Exit;
587         }
588         if (cl_hton64(guid) == cl_hton64(INVALID_GUID)) {
589                 print_all_guids(&osm_test);
590                 complib_exit();
591                 return (status);
592         }
593
594         /*
595            If the user didn't specify a GUID on the command line,
596            then get a port GUID value with which to bind.
597          */
598         if (guid == 0 && !(guid = get_port_guid(&osm_test, guid))) {
599                 printf("\nError: port guid 0x%" PRIx64 " not found\n", guid);
600                 goto Exit;
601         }
602
603         /*
604          * Guid may be zero going into this function if the user
605          * hasn't specified a binding port on the command line.
606          */
607         status = osmtest_bind(&osm_test, max_lid, guid);
608         if (status != IB_SUCCESS)
609                 exit(status);
610
611         status = osmtest_run(&osm_test);
612         if (status != IB_SUCCESS) {
613                 printf("OSMTEST: TEST \"%s\" FAIL\n", flow_name);
614         } else {
615                 printf("OSMTEST: TEST \"%s\" PASS\n", flow_name);
616         }
617         osmtest_destroy(&osm_test);
618
619         complib_exit();
620
621 Exit:
622         return (status);
623 }