[osmtest] Adding support for default guid selection when running osmtest.
[mirror/winof/.git] / ulp / opensm / user / osmtest / main.c
1 /*
2  * Copyright (c) 2004,2005 Voltaire, Inc. All rights reserved.   
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.   
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.   
5  *  
6  * This software is available to you under the OpenIB.org BSD license  
7  * below:  
8  *  
9  *     Redistribution and use in source and binary forms, with or  
10  *     without modification, are permitted provided that the following  
11  *     conditions are met:  
12  *  
13  *      - Redistributions of source code must retain the above  
14  *        copyright notice, this list of conditions and the following  
15  *        disclaimer.  
16  *  
17  *      - Redistributions in binary form must reproduce the above  
18  *        copyright notice, this list of conditions and the following  
19  *        disclaimer in the documentation and/or other materials  
20  *        provided with the distribution.  
21  *  
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND           
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS  
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN  
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
29  * SOFTWARE.  
30  *  
31  * $Id$
32  */
33
34 /*
35  * Abstract:
36  *      Command line interface for osmtest.
37  *
38  * Environment:
39  *      Linux User Mode
40  *
41  * $Revision: 1.3 $
42  */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <complib/cl_debug.h>
47 #include "osmtest.h"
48
49 /********************************************************************
50        D E F I N E    G L O B A L    V A R I A B L E S
51 *********************************************************************/
52
53 /*
54         This is the global osmtest object.
55         One osmtest object is required per subnet.
56         Future versions could support multiple subents by
57         instantiating more than one osmtest object.
58 */
59 #define GUID_ARRAY_SIZE 64
60 #define OSMT_DEFAULT_RETRY_COUNT 3
61 #define OSMT_DEFAULT_TRANS_TIMEOUT_MILLISEC 1000
62 #define OSMT_DEFAULT_TRAP_WAIT_TIMEOUT_SEC 10
63
64 /**********************************************************************
65  **********************************************************************/
66 boolean_t
67 osmt_is_debug(void)
68 {
69 #if defined( _DEBUG_ )
70   return TRUE;
71 #else
72   return FALSE;
73 #endif /* defined( _DEBUG_ ) */
74 }
75
76 /**********************************************************************
77  **********************************************************************/
78 ib_net64_t
79 get_port_guid(
80   IN osmtest_t *p_osm, uint64_t port_guid,
81   IN boolean_t is_service)
82 {
83   uint32_t i;
84   uint32_t choice = 0;
85   char junk[128];
86   boolean_t done_flag = FALSE;
87   ib_api_status_t status;
88   uint32_t num_ports = GUID_ARRAY_SIZE;
89   ib_port_attr_t attr_array[GUID_ARRAY_SIZE];
90   
91   /*
92     Call the transport layer for a list of local port
93     GUID values.
94   */
95   status = osm_vendor_get_all_port_attr( p_osm->p_vendor, attr_array, &num_ports );
96   if( status != IB_SUCCESS )
97   {
98     printf( "\nError from osm_vendor_get_all_port_attr (%x)\n", status);
99     return( 0 );
100   }
101
102   /* if num_ports is 0 - return 0 */
103   if( num_ports == 0 )
104   {
105     printf( "\nNo local ports detected!\n" );
106     return( 0 );
107   }
108   /* If num_ports is 1, then there is only one possible port to use. Use it. */
109   if ( num_ports == 1 )
110   {
111     printf("Using default GUID 0x%" PRIx64 "\n", cl_hton64(attr_array[0].port_guid));
112     return( attr_array[0].port_guid );
113   }
114
115 #if defined ( OSM_VENDOR_INTF_OPENIB )
116   /* If port_guid is 0, and this is gen2 - use the default port whose info is in attr_array[0] */
117   if ( port_guid == 0 )
118   {
119     printf("Using default GUID 0x%" PRIx64 "\n", cl_hton64(attr_array[0].port_guid));
120     return( attr_array[0].port_guid );
121   }
122 #endif /* OSM_VENDOR_INTF_OPENIB */
123
124   /* If port_guid is 0, and we are in windows - find the first port with link_state != DOWN and
125      use it as default port. */
126   if ( port_guid == 0 )
127   {
128     for ( i = 0; i < num_ports; i++ )
129     {
130       if (attr_array[i].link_state > IB_LINK_DOWN)
131       {
132         /* Use this port */
133         printf("Using default guid 0x%" PRIx64 "\n", cl_hton64(attr_array[i].port_guid));
134         return( attr_array[i].port_guid );
135       }
136     }
137     /* If we are running as a service, and all ports are down we return the 
138        first port (we can't open a window, as a service)*/
139        if (is_service) {
140          return( attr_array[0].port_guid );
141        }
142   }
143
144   /* More than one possible port - list all ports and let the user to choose. */
145   while( done_flag == FALSE )
146   {
147     printf( "\nChoose a local port number with which to bind:\n\n" );
148     /* If this is gen2 code - then port 0 has details of the default port used. 
149        no need to print it.
150        If this is not gen2 code - need to print details of all ports. */
151 #if defined ( OSM_VENDOR_INTF_OPENIB )
152     for( i = 1; i < num_ports; i++ )
153     {
154       printf("\t%u: GUID = 0x%8" PRIx64 ", lid = 0x%04X, state = %s\n",
155              i, cl_ntoh64( attr_array[i].port_guid ),
156              attr_array[i].lid,
157              ib_get_port_state_str( attr_array[i].link_state ) );
158     }
159     printf( "\nEnter choice (1-%u): ", i-1 );
160 # else
161     for( i = 0; i < num_ports; i++ )
162     {
163       /*
164         Print the index + 1 since by convention, port numbers
165         start with 1 on host channel adapters.
166       */
167
168       printf("\t%u: GUID = 0x%8" PRIx64 ", lid = 0x%04X, state = %s\n",
169              i+1, cl_ntoh64( attr_array[i].port_guid ),
170              attr_array[i].lid,
171              ib_get_port_state_str( attr_array[i].link_state ) );
172     }
173     printf( "\nEnter choice (1-%u): ", i );
174 #endif /* OSM_VENDOR_INTF_OPENIB */
175
176     fflush( stdout );
177     if (scanf( "%u", &choice ))
178     {
179       /* If gen2 code - choice can be between 1 to num_ports-1
180          if not gen2 code - choice can be between 1 to num_ports */
181 #if defined ( OSM_VENDOR_INTF_OPENIB )
182       if( choice >= num_ports )
183 # else
184       if( choice > num_ports || choice < 1 )
185 #endif /* OSM_VENDOR_INTF_OPENIB */
186       {
187         printf("\nError: Lame choice!\n");
188         fflush( stdin );
189       }
190       else
191       {
192         done_flag = TRUE;
193       }
194     }
195     else
196     {
197       /* get rid of the junk in the selection line */
198       scanf( "%s", junk );
199       printf("\nError: Lame choice!\n"); 
200       fflush( stdin );
201     }
202   }
203 #if defined ( OSM_VENDOR_INTF_OPENIB )
204   printf("Choice guid=0x%8" PRIx64 "\n", cl_ntoh64( attr_array[choice].port_guid ));       
205   return( attr_array[choice].port_guid );
206 # else
207   return( attr_array[choice - 1].port_guid );
208 #endif /* OSM_VENDOR_INTF_OPENIB */
209 }
210 /**********************************************************************
211  **********************************************************************/
212 void show_usage(void);
213
214 void
215 show_usage(  )
216 {
217         printf
218                 ( "\n------- osmtest - Usage and options ----------------------\n" );
219         printf( "Usage:   osmtest [options]\n" );
220         printf( "Options:\n" );
221         printf( "-f <c|a|v|s|e|f|m|q|t>\n"
222                         "--flow <c|a|v|s|e|f|m|q|t>\n"
223                         "          This option directs osmtest to run a specific flow:\n"
224                         "          FLOW  DESCRIPTION\n"
225                         "          c = create an inventory file with all nodes, ports and paths.\n"
226                         "          a = run all validation tests (expecting an input inventory)\n"
227                         "          v = only validate the given inventory file.\n"
228                         "          s = run service registration, un-registration and lease.\n"
229                         "          e = run event forwarding test.\n"
230                         "          f = flood the SA with queries accoring to the stress mode.\n"
231                         "          m = multicast flow.\n"
232                         "          q = QoS info - VLArb and SLtoVL tables.\n"
233          "          t = run trap 64/65 flow. This flow requires running of external tool.\n"
234                         "          (default is all but QoS).\n\n" );
235         printf( "-w <trap_wait_time>\n"
236                 "--wait <trap_wait_time>\n"
237                 "          This option specifies the wait time for trap 64/65 in seconds.\n"
238                 "          It is used only when running -f t - the trap 64/65 flow\n"
239                 "          (default to 10 sec).\n" );
240         printf( "-d <number>\n"
241                         "--debug <number>\n"
242                         "          This option specifies a debug option.\n"
243                         "          These options are not normally needed.\n"
244                         "          The number following -d selects the debug\n"
245                         "          option to enable as follows:\n"
246                         "          OPT   Description\n"
247                         "          ---    -----------------\n"
248                         "          -d0  - Unused.\n"
249                         "          -d1  - Do not scan/compare path records.\n"
250                         "          -d2  - Force log flushing after each log message.\n"
251                         "          -d3  - Use mem tracking.\n"
252                         "          Without -d, no debug options are enabled.\n\n" );
253         printf( "-m <LID in hex>\n"
254                         "--max_lid <LID in hex>\n"
255                         "          This option specifies the maximal LID number to be searched\n"
256                    "          for during inventory file build (default to 100).\n");
257         printf( "-g <GUID in hex>\n"
258                         "--guid <GUID in hex>\n"
259                         "          This option specifies the local port GUID value\n"
260                         "          with which osmtest should bind.  osmtest may be\n"
261                         "          bound to 1 port at a time.\n"
262                         "          Without -g, osmtest displays a menu of possible\n"
263                         "          port GUIDs and waits for user input.\n\n" );
264         printf( "-h\n"
265                         "--help\n" "          Display this usage info then exit.\n\n" );
266         printf( "-i <filename>\n"
267                         "--inventory <filename>\n"
268                         "          This option specifies the name of the inventory file.\n"
269                         "          Normally, osmtest expects to find an inventory file,\n"
270                         "          which osmtest uses to validate real-time information\n"
271                         "          received from the SA during testing.\n"
272                         "          If -i is not specified, osmtest defaults to the file\n"
273                         "          'osmtest.dat'.\n"
274                         "          See the -c option for related information.\n\n" );
275         printf( "-s\n"
276                         "--stress\n"
277                         "          This option runs the specified stress test instead\n"
278                         "          of the normal test suite.\n"
279                         "          Stress test options are as follows:\n"
280                         "          OPT    Description\n"
281                         "          ---    -----------------\n"
282                         "          -s1  - Single-MAD response SA queries .\n"
283                         "          -s2  - Multi-MAD (RMPP) response SA queries.\n"
284                         "          -s3  - Multi-MAD (RMPP) Path Record SA queries.\n"
285                         "          Without -s, stress testing is not performed.\n\n" );
286     printf( "-M\n"
287             "--Multicast_Mode\n"
288             "          This option specify length of Multicast test :\n"
289             "          OPT    Description\n"
290             "          ---    -----------------\n"
291             "          -M1  - Short Multicast Flow (default) - single mode.\n"
292             "          -M2  - Short Multicast Flow  - multiple mode.\n"
293             "          -M3  - Long Multicast Flow - single mode.\n"
294             "          -M4  - Long Multicast Flow - multiple mode.\n"
295             " Single mode - Osmtest is tested alone , with no other  \n"
296             "   apps that interact vs. OpenSM MC.\n"
297             " Multiple mode - Could be run with other apps using MC vs.\n"
298             "   OpenSM."
299             " Without -M, default flow testing is performed.\n\n" );
300
301     printf( "-t <milliseconds>\n"
302                         "          This option specifies the time in milliseconds\n"
303                         "          used for transaction timeouts.\n"
304                         "          Specifying -t 0 disables timeouts.\n"
305                         "          Without -t, osmtest defaults to a timeout value of\n"
306                         "          1 second.\n\n" );
307         printf( "-l\n"
308                           "--log_file\n"
309                           "          This option defines the log to be the given file.\n"
310                           "          By default the log goes to stdout.\n\n");
311         printf( "-v\n"
312                         "          This option increases the log verbosity level.\n"
313                         "          The -v option may be specified multiple times\n"
314                         "          to further increase the verbosity level.\n"
315                         "          See the -vf option for more information about.\n"
316                         "          log verbosity.\n\n" );
317         printf( "-V\n"
318                         "          This option sets the maximum verbosity level and\n"
319                         "          forces log flushing.\n"
320                         "          The -V is equivalent to '-vf 0xFF -d 2'.\n"
321                         "          See the -vf option for more information about.\n"
322                         "          log verbosity.\n\n" );
323         printf( "-vf <flags>\n"
324                         "          This option sets the log verbosity level.\n"
325                         "          A flags field must follow the -vf option.\n"
326                         "          A bit set/clear in the flags enables/disables a\n"
327                         "          specific log level as follows:\n"
328                         "          BIT    LOG LEVEL ENABLED\n"
329                         "          ----   -----------------\n"
330                         "          0x01 - ERROR (error messages)\n"
331                         "          0x02 - INFO (basic messages, low volume)\n"
332                         "          0x04 - VERBOSE (interesting stuff, moderate volume)\n"
333                         "          0x08 - DEBUG (diagnostic, high volume)\n"
334                         "          0x10 - FUNCS (function entry/exit, very high volume)\n"
335                         "          0x20 - FRAMES (dumps all SMP and GMP frames)\n"
336                         "          0x40 - currently unused.\n"
337                         "          0x80 - currently unused.\n"
338                         "          Without -vf, osmtest defaults to ERROR + INFO (0x3).\n"
339                         "          Specifying -vf 0 disables all messages.\n"
340                         "          Specifying -vf 0xFF enables all messages (see -V).\n"
341                         "          High verbosity levels may require increasing\n"
342                         "          the transaction timeout with the -t option.\n\n" );
343 }
344
345 /**********************************************************************
346  **********************************************************************/
347 void show_menu(void);
348
349 void
350 show_menu(  )
351 {
352         printf( "\n------- Interactive Menu -------\n" );
353         printf( "X - Exit.\n\n" );
354 }
355 void OsmReportState(IN const char *p_str)
356 {
357 }
358
359 /**********************************************************************
360  **********************************************************************/
361 int OSM_CDECL
362 main( int argc,
363           char *argv[] )
364 {
365         static osmtest_t osm_test;
366         osmtest_opt_t opt = { 0 };
367         ib_net64_t guid = 0;
368         int max_lid = 100;
369         ib_api_status_t status;
370         uint32_t log_flags = OSM_LOG_ERROR | OSM_LOG_INFO;
371         char flow_name[64];
372     boolean_t mem_track = FALSE;
373         uint32_t next_option;
374         const char *const short_option = "f:l:m:M:d:g:s:t:i:cvVh";
375
376     /*
377          * In the array below, the 2nd parameter specified the number
378          * of arguments as follows:
379          * 0: no arguments
380          * 1: argument
381          * 2: optional
382          */
383         const struct option long_option[] = {
384                 {"create",    0, NULL, 'c'},
385                 {"debug",     1, NULL, 'd'},
386                 {"flow",      1, NULL, 'f'},
387                 {"wait",      1, NULL, 'w'},
388                 {"inventory", 1, NULL, 'i'},
389                 {"max_lid",   1, NULL, 'm'},
390                 {"guid",      1, NULL, 'g'},
391                 {"help",      0, NULL, 'h'},
392                 {"stress",    1, NULL, 's'},
393                 {"Multicast_Mode",    1, NULL, 'M'},
394                 {"timeout",   1, NULL, 't'},
395                 {"verbose",   0, NULL, 'v'},
396                 {"log_file",  1, NULL, 'l'},
397                 {"vf",        1, NULL, 'x'},
398                 {"V",         0, NULL, 'V'},
399
400                 {NULL, 0, NULL, 0}              /* Required at end of array */
401         };
402
403         opt.transaction_timeout = OSMT_DEFAULT_TRANS_TIMEOUT_MILLISEC;
404         opt.wait_time = OSMT_DEFAULT_TRAP_WAIT_TIMEOUT_SEC;
405         opt.retry_count = OSMT_DEFAULT_RETRY_COUNT;
406         opt.force_log_flush = FALSE;
407         opt.stress = 0;
408         opt.log_file = NULL;
409         opt.create = FALSE;
410     opt.mmode = 1;
411         opt.ignore_path_records = FALSE; /*  Do path Records too. */
412         opt.flow = 0; /*  run all validation tests */
413         strcpy(flow_name, "All Validations");
414         strcpy( opt.file_name, "osmtest.dat" );
415
416         printf( "\nCommand Line Arguments\n" );
417         do
418         {
419                 next_option = getopt_long_only( argc, argv, short_option,
420                                                                                 long_option, NULL );
421                 switch ( next_option )
422                 {
423                 case 'c':
424                         /*
425                          * Create the inventory file.
426                          */
427                         opt.create = TRUE;
428                         printf( "\tCreating inventory file\n" );
429                         break;
430
431                 case 'i':
432                         /*
433                          * Specifies inventory file name.
434                          */
435                         if( strlen( optarg ) > OSMTEST_FILE_PATH_MAX )
436                                 printf( "\nError: path name too long (ignored).\n" );
437                         else
438                                 strcpy( opt.file_name, optarg );
439
440                         printf( "\tFile = %s\n", opt.file_name );
441                         break;
442
443                 case 'f':
444                         /*
445                          * Specifies Flow .
446                          */
447                   if( strlen( optarg ) > OSMTEST_FILE_PATH_MAX )
448                                 printf( "\nError: path name too long (ignored).\n" );
449                         else
450                                 strcpy( flow_name, optarg );
451
452                   if (!strcmp("c",optarg)) {
453                          strcpy(flow_name, "Create Inventory");
454                          opt.flow = 1;
455                   } else if (!strcmp("v",optarg)) {
456                          strcpy(flow_name, "Validate Inventory");
457                          opt.flow = 2;
458                   } else if (!strcmp("s",optarg)) {
459                          strcpy(flow_name, "Services Registration");
460                          opt.flow = 3;
461                   } else if (!strcmp("e",optarg)) {
462                          strcpy(flow_name, "Event Forwarding");
463                          opt.flow = 4;
464                   } else if (!strcmp("f",optarg)) {
465                          strcpy(flow_name, "Stress SA");
466                          opt.flow = 5;
467                   } else if (!strcmp("m",optarg)) {
468                          strcpy(flow_name, "Multicast");
469                          opt.flow = 6;
470                   } else if (!strcmp("q",optarg)) {
471                          strcpy(flow_name, "QoS: VLArb and SLtoVL");
472                          opt.flow = 7;
473                   } else if (!strcmp("t", optarg)) {
474                     strcpy(flow_name, "Trap 64/65");
475                     opt.flow = 8;
476                   } else if (!strcmp("a",optarg)) {
477                          strcpy(flow_name, "All Validations");
478                          opt.flow = 0;
479                   } else {
480                          printf( "\nError: un-known flow %s.\n",flow_name);
481                          exit(2);
482                   }
483                   break;
484
485                 case 'w':
486                         /*
487                          * Specifies trap 64/65 wait time
488                          */
489         CL_ASSERT( strtol( optarg, NULL, 0 ) < 0x100 );
490                   opt.wait_time = (uint8_t)strtol( optarg, NULL, 0 );
491                   printf( "\tTrap 64/65 wait time = %d\n", opt.wait_time );
492                   break;
493
494                 case 'm':
495                         /*
496                          * Specifies the max LID to search for during exploration.
497                          */
498                         max_lid = atoi( optarg );
499                         printf( "\tMAX-LID %u\n", max_lid );
500                         break;
501
502                 case 'g':
503                         /*
504                          * Specifies port guid with which to bind.
505                          */
506                   guid = cl_hton64( strtoull( optarg, NULL, 16 ));
507                   printf( "\tGUID 0x%016" PRIx64 "\n", guid );
508                   break;
509                 case 't':
510                         /*
511                          * Specifies transaction timeout.
512                          */
513                   opt.transaction_timeout = strtol( optarg, NULL, 0 );
514                   printf( "\tTransaction timeout = %d\n", opt.transaction_timeout );
515                   break;
516
517                 case 'l':
518                   opt.log_file = optarg;
519                   printf("\tLog File:%s\n", opt.log_file );
520                   break;
521
522                 case 'v':
523                         /*
524                          * Increases log verbosity.
525                          */
526                         log_flags = ( log_flags << 1 ) | 1;
527                         printf( "\tVerbose option -v (log flags = 0x%X)\n", log_flags );
528                         break;
529
530                 case 'V':
531                         /*
532                          * Specifies maximum log verbosity.
533                          */
534                         log_flags = 0xFFFFFFFF;
535                         opt.force_log_flush = TRUE;
536                         printf( "\tEnabling maximum log verbosity\n" );
537                         break;
538
539                 case 's':
540                         /*
541                          * Perform stress test.
542                          */
543                         opt.stress = strtol( optarg, NULL, 0 );
544                         printf( "\tStress test enabled: " );
545                         switch ( opt.stress )
546                         {
547                         case 1:
548                                 printf( "Small SA queries\n" );
549                                 break;
550                         case 2:
551                                 printf( "Large SA queries\n" );
552                                 break;
553             case 3:
554                 printf( "Large Path Record SA queries\n" );
555                 break;
556                         default:
557                                 printf( "Unknown value %u (ignored)\n", opt.stress );
558                                 opt.stress = 0;
559                                 break;
560                         }
561                         break;
562
563         case 'M':
564             /*
565              * Perform stress test.
566              */
567             opt.mmode = strtol( optarg, NULL, 0 );
568             printf( "\tMulticast test enabled: " );
569             switch ( opt.mmode )
570             {
571             case 1:
572                 printf( "Short MC Flow - single mode (default)\n" );
573                 break;
574             case 2:
575                 printf( "Short MC Flow - multiple mode\n" );
576                 break;
577             case 3:
578                 printf( "Long MC Flow - single mode\n" );
579                 break;
580             case 4:
581                 printf( "Long MC Flow - multiple mode\n" );
582                 break;
583             default:
584                 printf( "Unknown value %u (ignored)\n", opt.stress );
585                 opt.mmode = 0;
586                 break;
587             }
588             break;
589
590                 case 'd':
591                         /*
592                          * Debug Options
593                          */
594                         printf( "\tDebug Option: " );
595                         switch ( strtol( optarg, NULL, 0 ) )
596                         {
597                         case 1:
598                                 printf( "Ignore Path Records.\n" );
599                                 opt.ignore_path_records = TRUE;
600                                 break;
601                         case 2:
602                                 printf( "Force Log Flush.\n" );
603                                 opt.force_log_flush = TRUE;
604                                 break;
605                         case 3:
606                                 printf( "Use Mem Tracking.\n" );
607                                 mem_track = TRUE;
608                                 break;
609                         default:
610                                 printf( "Unknown value %ld (ignored)\n", strtol( optarg, NULL, 0 ) );
611                                 break;
612                         }
613                         break;
614
615                 case 'h':
616                         show_usage(  );
617                         return 0;
618
619                 case 'x':
620                         log_flags = strtol( optarg, NULL, 0 );
621                         printf( "\t\t\t\tVerbose option -vf (log flags = 0x%X)\n",
622                                         log_flags );
623                         break;
624
625                 case -1:
626                         printf( "Done with args\n" );
627                         break;
628
629                 default:                                /* something wrong */
630                         abort(  );
631                 }
632
633         }
634         while( next_option != -1 );
635
636         printf( "\tFlow = %s\n", flow_name );
637
638    if (mem_track) __cl_mem_track(TRUE);
639
640
641         status = osmtest_init( &osm_test, &opt, ( osm_log_level_t ) log_flags );
642         if( status != IB_SUCCESS )
643         {
644                 printf( "\nError from osmtest_init: %s.\n",
645                                 ib_get_err_str( status ) );
646                 goto Exit;
647         }
648
649         /*
650            If the user didn't specify a GUID on the command line,
651            then get a port GUID value with which to bind.
652          */
653         if (guid == 0 && !(guid = get_port_guid(&osm_test, guid,1))) {
654                 printf("\nError: port guid 0x%" PRIx64 " not found\n", guid);
655                 goto Exit;
656         }
657
658         /*
659          * Guid may be zero going into this function if the user
660          * hasn't specified a binding port on the command line.
661          */
662          
663         status = osmtest_bind( &osm_test, (uint16_t)max_lid, guid );
664         if (status != IB_SUCCESS) exit(status);
665
666         status = osmtest_run( &osm_test );
667         if (status != IB_SUCCESS) {
668           printf("OSMTEST: TEST \"%s\" FAIL\n", flow_name);
669         } else {
670           printf("OSMTEST: TEST \"%s\" PASS\n", flow_name);
671         }
672         osmtest_destroy( &osm_test );
673
674    if (mem_track) cl_mem_display();
675
676   Exit:
677         return ( status );
678 }