~ubuntu-branches/ubuntu/utopic/spew/utopic

« back to all changes in this revision

Viewing changes to src/spew.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Matt Taggart
  • Date: 2005-02-02 01:42:02 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050202014202-mkxgmw1k13b3p5mv
Tags: 1.0.4-1
* New upstream release
* Upstream fixed file conflict with snarf, Closes: #279679, #292316
* Drop libstdc++ build-dep. I should know better, I've filed bugs on
   other packages for the same thing :(,  Closes: #280257
* Add AUTHORS file to debian/docs
* Upstream fixed various DESTDIR problems, removed from diff
* Fix lintian description warnings

Show diffs side-by-side

added added

removed removed

Lines of Context:
76
76
{
77
77
   (char *)NULL,
78
78
   "spew",
79
 
   "snarf",
 
79
   "gorge",
80
80
   "regorge",
81
81
   (char *)NULL,
82
82
 
83
83
};
 
84
static const char SPEWRC_ENV[] = "SPEWRC";
 
85
static const char DEFAULT_SPEWRC_FILENAME[] = ".spewrc";
 
86
static const char SYSTEM_SPEWRC_FILENAME[] = "spew.conf";
84
87
static const char PROG_VERSION[] = VERSION;
85
88
static const int MAX_TMP_STR_LEN = 1024;
86
89
static const unsigned int INDENT_SIZE = 4;
127
130
string gFile = "";
128
131
bool gUseTui = false;
129
132
string gLogfilePath = "";
 
133
bool gUseStdRcFiles = true;
130
134
Log *gLogger = (Log *)NULL;
131
135
capacity_t gJobId = 0;
132
136
SpewDisplay *gDisplay = (SpewDisplay *)NULL; 
135
139
TimeHack gTotalWriteTransferTime;
136
140
capacity_t gTotalBytesRead = 0;
137
141
capacity_t gTotalBytesWritten = 0;
 
142
capacity_t gTotalWriteOps = 0;
 
143
capacity_t gTotalReadOps = 0;
138
144
TimeHack gProgramStartTime;
139
145
unsigned int gFoundTransferErrors = 0;
140
146
 
141
 
 
142
147
//////////////////////////////////////////////////////////////////////////////
143
148
////////////////////  Function Prototypes  ///////////////////////////////////
144
149
//////////////////////////////////////////////////////////////////////////////
145
150
void error_msg(char *fmt, ...);
146
151
void note(char *fmt, ...);
147
152
void usage();
148
 
bool parse_options(int argc, const char **argv);
 
153
bool parse_options(int argc, const char **argv, string& cmdArgs);
149
154
bool validate_options();
150
 
void spew();
151
 
void snarf();
152
155
void end_program(int exitCode);
153
156
void end_program(int exitCode, char *fmt, ...);
154
157
void update_transfer_totals(const Job *job,
244
247
"                                    data. Available patterns are: none, \n"
245
248
"                                    zeros, random, and numbers. The default\n"
246
249
"                                    pattern is %s.\n"
 
250
"  RCFILE                            Read additional command-line options\n"
 
251
"                                    from RCFILE.  Other options on the\n"
 
252
"                                    command-line will override options in\n"
 
253
"                                    RCFILE.\n"
247
254
"  SEED                              Used to seed the random number generator\n"
248
255
"                                    Must be >= 1 and <= 2^32.\n"
249
256
"  TRANSFER_SIZE                     Total number of bytes to transfer (must\n"
277
284
//////////////////////////  usage()  /////////////////////////////////////////
278
285
void usage(poptContext &context)
279
286
{
280
 
   poptSetOtherOptionHelp(context, "[OPTION]... TRANSFER_SIZE[kKmMgG] FILE");
 
287
   poptSetOtherOptionHelp(context, "TRANSFER_SIZE[kKmMgG] FILE");
281
288
   poptPrintUsage(context, stdout, 0);
282
289
}
283
290
 
309
316
         size *= 1024LL * 1024LL * 1024LL * 102;
310
317
         break;
311
318
      default:
312
 
         error_msg("Invalid unit\n");
 
319
         error_msg("Invalid unit in argument \"%s\"\n", arg);
313
320
         exit(EXIT_ERROR_USAGE);
314
321
         break;
315
322
      }
316
323
   }
317
324
   else if (sscanf(arg, "%llu", &size) != 1)
318
325
   {
319
 
      error_msg("Could not parse size.\n");
 
326
      error_msg("Could not parse size for argument \"%s\".\n", arg);
320
327
      exit(EXIT_ERROR_USAGE);
321
328
   }
322
329
   return size;
358
365
         units = TERABYTES;
359
366
         break;
360
367
      default:
361
 
         error_msg("Invalid units - use kKmMgG.\n");
 
368
         error_msg("Invalid unit in argument \"%s\" - use kKmMgG.\n", arg);
362
369
         exit(EXIT_ERROR_USAGE);
363
370
         break;
364
371
      }
365
372
   }
366
373
   else
367
374
   {
368
 
      error_msg("Could not parse units.\n");
 
375
      error_msg("Could not parse units in argument \"%s\"\n", arg);
369
376
      exit(EXIT_ERROR_USAGE);
370
377
   }
371
378
   return units;
372
379
}
373
380
 
374
381
 
 
382
//////////////////////////  parse_rcfile()  ///////////////////////////////////
 
383
bool parse_rcfile(FILE *rcfile,
 
384
                  string& cmdArgs)
 
385
{
 
386
   char rcArgs[MAX_TMP_STR_LEN];
 
387
   int len;
 
388
   while (fgets(rcArgs, MAX_TMP_STR_LEN, rcfile) != (char *)NULL)
 
389
   {
 
390
      // Chop off string after comment character.
 
391
      char *commentStart = strchr(rcArgs, '#');
 
392
      if (commentStart)
 
393
         *commentStart = '\0';
 
394
      len = strlen(rcArgs);
 
395
      if (rcArgs[len - 1] == '\n')
 
396
         rcArgs[len - 1] = '\0';
 
397
      if (rcArgs[0] != '\0')
 
398
      {
 
399
         cmdArgs += rcArgs;
 
400
         cmdArgs += " ";
 
401
      }
 
402
   }
 
403
   return true;
 
404
}
 
405
 
 
406
 
 
407
//////////////////////////  read_rcfiles()  ///////////////////////////////////
 
408
bool read_rcfiles(int argc, const char **argv, string& cmdArgs)
 
409
{
 
410
   struct stat statbuf;
 
411
   string rcFilePath;
 
412
   vector<string> rcFilePaths;
 
413
 
 
414
 
 
415
   // Check command-line for --no-rcfiles option.
 
416
   for (int i = 0; i < argc; i++)
 
417
   {
 
418
      if (strncmp(argv[i], "--no-rcfiles", strlen("--no-rcfiles")) == 0)
 
419
      {
 
420
         gUseStdRcFiles = false;
 
421
         break;
 
422
      }
 
423
   }
 
424
 
 
425
   // Read standard config locations.
 
426
   if (gUseStdRcFiles)
 
427
   {
 
428
      // Read system-wide rcfile if it exists.
 
429
      rcFilePath = QUOTE(SYSCONFDIR);
 
430
      rcFilePath += "/";
 
431
      rcFilePath += SYSTEM_SPEWRC_FILENAME;
 
432
      if (stat(rcFilePath.c_str(), &statbuf) >= 0)
 
433
      {
 
434
         rcFilePaths.push_back(rcFilePath);
 
435
      }
 
436
      else
 
437
      {
 
438
         if (errno != ENOENT)
 
439
         {
 
440
            error_msg("Cannot access rc file \"%s\" -- %s.\n", 
 
441
                      rcFilePath.c_str(), strError(errno).c_str());
 
442
         }
 
443
      }
 
444
 
 
445
      rcFilePath = "";
 
446
      if (getenv(SPEWRC_ENV))
 
447
      {
 
448
         rcFilePath = getenv(SPEWRC_ENV);
 
449
      }
 
450
      else
 
451
      {
 
452
         char *home = getenv("HOME");
 
453
         if (home)
 
454
         {
 
455
            rcFilePath = home;
 
456
            rcFilePath += "/";
 
457
            rcFilePath += DEFAULT_SPEWRC_FILENAME;
 
458
         }
 
459
      }
 
460
      if (stat(rcFilePath.c_str(), &statbuf) >= 0)
 
461
      {
 
462
         rcFilePaths.push_back(rcFilePath);
 
463
      }
 
464
      else
 
465
      {
 
466
         if (errno != ENOENT)
 
467
         {
 
468
            error_msg("Cannot access rc file \"%s\" -- %s.\n", 
 
469
                      rcFilePath.c_str(), strError(errno).c_str());
 
470
         }
 
471
      }
 
472
   }
 
473
 
 
474
   // Check the command-line for --rcfile.
 
475
   for (int i = 1; i < argc; i++)
 
476
   {
 
477
      rcFilePath = "";
 
478
      if (strncmp(argv[i], "--rcfile", 8) == 0)
 
479
      {
 
480
         char *eqPos = strrchr(argv[i], '=');
 
481
         if (eqPos == (char *)NULL)
 
482
         {
 
483
            if (i + 1 < argc)
 
484
            {
 
485
               rcFilePath = argv[i+1];
 
486
            }
 
487
            else
 
488
            {
 
489
               error_msg("Missing RCFILE argument.\n");
 
490
               return false;
 
491
            }
 
492
         }
 
493
         else
 
494
         {
 
495
            rcFilePath = eqPos + 1;
 
496
         }
 
497
         if (stat(rcFilePath.c_str(), &statbuf) < 0)
 
498
         {
 
499
            error_msg("Cannot access RCFILE \"%s\" -- %s.\n", 
 
500
                      rcFilePath.c_str(), strError(errno).c_str());
 
501
            return false;
 
502
         }
 
503
         else
 
504
            rcFilePaths.push_back(rcFilePath);
 
505
         break;
 
506
      }
 
507
   }
 
508
 
 
509
   vector<string>::iterator pathIter;
 
510
   for (pathIter = rcFilePaths.begin();
 
511
        pathIter != rcFilePaths.end();
 
512
        pathIter++)
 
513
   {
 
514
      FILE *rcfile = fopen(pathIter->c_str(), "r");
 
515
      if (rcfile == (FILE *)NULL)
 
516
      {
 
517
         error_msg("Cannot open rc file \"%s\" -- %s.\n", 
 
518
                   pathIter->c_str(), strError(errno).c_str());
 
519
      }
 
520
      else
 
521
      {
 
522
         parse_rcfile(rcfile, cmdArgs);
 
523
         fclose(rcfile);
 
524
      }
 
525
   }
 
526
 
 
527
   return true;
 
528
}
 
529
 
375
530
 
376
531
//////////////////////////  parse_options()  /////////////////////////////////
377
 
bool parse_options(int argc, const char **argv)
 
532
bool parse_options(int argc, const char **argv, string& cmdArgs)
378
533
{
379
534
   char *minBufferSizeArgStr = (char *)NULL;
380
535
   char *maxBufferSizeArgStr = (char *)NULL;
382
537
   char *patternArgStr = (char *)NULL;
383
538
   char *unitsArgStr = (char *)NULL;
384
539
   char *logfilePathArgStr = (char *)NULL;
 
540
   char *dummyArgStr = (char *)NULL;
385
541
   int writeArg = 0;
386
542
   int readArg = 0;
387
543
   int readAfterWriteArg = 0;
399
555
   int directArg = 0;
400
556
   int randomArg = 0;
401
557
   int generateLoadArg = 0;
402
 
 
 
558
   int useStdRcFilesArg = 1;
403
559
 
404
560
   struct poptOption optionsTable[] =  {
405
561
      {"max-buffer-size", 'B', POPT_ARG_STRING, &maxBufferSizeArgStr, 0, "Each read(2)/write(2) call uses a maximum buffer of size BUFFER_SIZE.", "BUFFER_SIZE"},
412
568
      {"iterations", 'i', POPT_ARG_INT, &iterationsArg, 0, "Write/read data COUNT times. If count is 0, repeats forever.", "COUNT"},
413
569
      {"logfile", 'l', POPT_ARG_STRING, &logfilePathArgStr, 0, "Send log messages to LOGFILE.", "LOGFILE"},
414
570
      {"no-progress", 0, POPT_ARG_NONE, &noProgressArg, 0, "Don't show progess (default).", NULL},
 
571
      {"no-rcfiles", 0, POPT_ARG_NONE, NULL, 0, "Don't use standard rcfiles.", NULL},
 
572
      {"no-statistics", 'q', POPT_ARG_NONE, &noStatisticsArg, 0, "Don't output statistics.", NULL},
415
573
      {"no-tui", 0, POPT_ARG_NONE, &noTuiArg, 0, "Don't use TUI interface.", NULL},
416
574
      {"offset", 'o', POPT_ARG_STRING, &offsetArgStr, 0, "Seek to OFFSET before starting I/O.", "OFFSET"},
417
575
      {"progress", 'P', POPT_ARG_NONE, &progressArg, 0, "Show progess.", NULL},
418
576
      {"pattern", 'p', POPT_ARG_STRING, &patternArgStr, 0, "Use data pattern PATTERN when reading or writing data.", "PATTERN"},
419
 
      {"no-statistics", 'q', POPT_ARG_NONE, &noStatisticsArg, 0, "Don't output statistics.", NULL},
420
577
      {"random", 'r', POPT_ARG_NONE, &randomArg, 0, "Read/Write buffers to random offsets.", NULL},
421
578
      {"raw", 0, POPT_ARG_NONE, &readAfterWriteArg, 0, "An alias for --read-after-write.", NULL},
 
579
      {"rcfile", 0, POPT_ARG_STRING, &dummyArgStr, 0, "Read command-line options from RCFILE.", "RCFILE"},
422
580
      {"read", 0, POPT_ARG_NONE, &readArg, 0, "Read date from FILE.", NULL},
423
581
      {"read-after-write", 0, POPT_ARG_NONE, &readAfterWriteArg, 0, "Read back data after writing to FILE.", NULL},
424
582
      {"seed", 'S', POPT_ARG_LONG, &gSeed, 0, "Use SEED for random number seed.","SEED"},
431
589
      {"detailed-statistics", 'v', POPT_ARG_NONE, &detailedStatisticsArg, 0, "Output detailed statistics.", NULL},
432
590
      {"write", 0, POPT_ARG_NONE, &writeArg, 0, "Write data to FILE.", NULL},
433
591
      {"help", '?', POPT_ARG_NONE, &helpArg, 0, "Show this help and exit.", NULL},
434
 
      { NULL, 0, 0, NULL, 0 }
 
592
      POPT_TABLEEND
435
593
   };
436
594
 
437
 
   poptContext context = poptGetContext(gPrgName, argc, argv, optionsTable, 0);
 
595
   cmdArgs = "";
 
596
   if (!read_rcfiles(argc, argv, cmdArgs))
 
597
       return false;
 
598
   for (int i = 1; i < argc; i++)
 
599
   {
 
600
      cmdArgs += argv[i];
 
601
      cmdArgs += " ";
 
602
   }
 
603
   cmdArgs = " " + cmdArgs;
 
604
   cmdArgs = argv[0] + cmdArgs;
 
605
   int newArgc;
 
606
   const char **newArgv;
 
607
   poptParseArgvString((char *)cmdArgs.c_str(), &newArgc, &newArgv);
 
608
   poptContext context = poptGetContext(gPrgName,
 
609
                                        newArgc, 
 
610
                                        newArgv, 
 
611
                                        optionsTable, 
 
612
                                        POPT_CONTEXT_POSIXMEHARDER);
 
613
 
438
614
   int rc = poptGetNextOpt(context);
439
615
   if (rc < -1)
440
616
   {
441
 
      error_msg("%s\n", poptStrerror(rc));
 
617
      switch (rc)
 
618
      {
 
619
      case POPT_ERROR_BADOPT:
 
620
         error_msg("bad or unknown option \"%s\"\n.", 
 
621
                   poptBadOption(context, 0));
 
622
         break;
 
623
      default:
 
624
         error_msg("%s.\n", poptStrerror(rc));
 
625
         break;
 
626
      }
442
627
      usage(context);
443
628
      poptFreeContext(context);
444
629
      return false;
589
774
   if (gIterationsToDo < 0)
590
775
      gIterationsToDo = DEFAULT_ITERATIONS;
591
776
 
592
 
   if (poptPeekArg(context))
593
 
      gTransferSize = get_size(poptGetArg(context));
594
 
   else
 
777
   // Count the rest of the arguments.
 
778
   const char **argsLeft = poptGetArgs(context);
 
779
   int argsCount = 0;
 
780
   if (argsLeft)
 
781
   {
 
782
      while (argsLeft[argsCount] != NULL)
 
783
         argsCount++;
 
784
   }
 
785
   if (argsCount < 2)
595
786
   {
596
787
      error_msg("Need TRANSFER_SIZE and FILE.\n");
597
788
      usage(context);
599
790
      return false;
600
791
   }
601
792
 
602
 
   if (poptPeekArg(context))
603
 
      gFile = poptGetArg(context);
604
 
   else
605
 
   {
606
 
      error_msg("Need FILE.\n");
607
 
      usage(context);
608
 
      poptFreeContext(context);
609
 
      return false;
610
 
   }
 
793
   gTransferSize = get_size(poptGetArg(context));
 
794
   gFile = poptGetArg(context);
611
795
 
612
796
   if (gSeed == DEFAULT_SEED)
613
797
   {
683
867
   {
684
868
      if (gMinBufferSize % Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT != 0)
685
869
      {
686
 
         error_msg("MIN_BUFFER_SIZE must be a multiple of %llu bytes when using direct I/O.\n", Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT);
 
870
         error_msg("MIN_BUFFER_SIZE must be a multiple of %llu bytes when using direct I/O. Use -b|--min-buffer-size to set MIN_BUFFER_SIZE.\n", Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT);
687
871
         return false;
688
872
      }
689
873
      if (gMaxBufferSize % Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT != 0)
690
874
      {
691
 
         error_msg("MAX_BUFFER_SIZE must be a multiple of %llu bytes when using direct I/O.\n", Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT);
 
875
         error_msg("MAX_BUFFER_SIZE must be a multiple of %llu bytes when using direct I/O. Use -B|--max-buffer-size to set MAX_BUFFER_SIZE.\n", Transfer::DIRECTIO_BUFFER_SIZE_INCREMENT);
692
876
         return false;
693
877
      }
694
878
   }
843
1027
                                  jobTransferTime.getTime(),
844
1028
                                  gTotalBytesRead,
845
1029
                                  gTotalReadTransferTime.getTime(),
 
1030
                                  gTotalReadOps,
846
1031
                                  gTotalBytesWritten,
847
1032
                                  gTotalWriteTransferTime.getTime(), 
 
1033
                                  gTotalWriteOps,
848
1034
                                  now - gProgramStartTime);
849
1035
 
850
1036
   long double transferRate = convertCapacity((long double)job->getJobBytesTransferred(), gUnits)/jobTransferTime.getTime();
 
1037
   long double iops = (long double)job->getTotalNumberOfTransfers()/(long double)jobTransferTime.getTime();
851
1038
 
852
1039
   switch (ioDirection)
853
1040
   {
854
1041
   case READING:
855
 
      gLogger->logNote("Iter: %5d   Read Transfer rate: %11.2Lf %-5s    Transfer time: %s\n",
 
1042
      gLogger->logNote("Iter: %5d   RTR: %11.2Lf %-5s   TT: %s   IOPS: %11.2Lf\n",
856
1043
                       iteration,
857
1044
                       transferRate, 
858
1045
                       getTransferRateUnitsStr(gUnits), 
859
 
                       jobTransferTime.getElapsedTimeStr().c_str());
 
1046
                       jobTransferTime.getElapsedTimeStr().c_str(),
 
1047
                       iops);
860
1048
      break;
861
1049
   case WRITING:
862
 
      gLogger->logNote("Iter: %5d  Write Transfer rate: %11.2Lf %-5s    Transfer time: %s\n",
 
1050
      gLogger->logNote("Iter: %5d   WTR: %11.2Lf %-5s   TT: %s   IOPS: %11.2Lf\n",
863
1051
                       iteration,
864
1052
                       transferRate, 
865
1053
                       getTransferRateUnitsStr(gUnits), 
866
 
                       jobTransferTime.getElapsedTimeStr().c_str());
 
1054
                       jobTransferTime.getElapsedTimeStr().c_str(),
 
1055
                       iops);
867
1056
      break;
868
1057
   }  
869
1058
}
876
1065
   device = Log::OUTPUT_LOG_STDOUT;
877
1066
   if (gVerbosity == VERBOSITY_LONG)
878
1067
      device |= Log::OUTPUT_DISPLAY_STDOUT;
 
1068
 
 
1069
   TimeHack now(TimeHack::getCurrentTime());
 
1070
 
 
1071
   if (!gUseTui)
 
1072
      gLogger->note(device, "\n");
 
1073
   gLogger->note(device, "Total iterations:                %17u\n",
 
1074
                 iterations);
 
1075
   gLogger->note(device, "Total runtime:                   %17s\n",
 
1076
                 gProgramStartTime.getTimeDiffStr(now).c_str());
 
1077
 
 
1078
   if (gTotalBytesWritten > 0)
879
1079
   {
880
 
      TimeHack now(TimeHack::getCurrentTime());
881
 
 
882
 
      if (!gUseTui)
883
 
         gLogger->note(device, "\n");
884
 
      gLogger->note(device, "Total iterations:          %17u\n", iterations);
885
 
      gLogger->note(device, "Total runtime:             %17s\n",
886
 
                    gProgramStartTime.getTimeDiffStr(now).c_str());
887
 
 
888
 
      if (gTotalBytesWritten > 0)
889
 
      {
890
 
         long double writeTransferRate = convertCapacity((long double)gTotalBytesWritten, gUnits)/(long double)gTotalWriteTransferTime.getTime();
891
 
         gLogger->note(device, "Total write transfer time: %17s\n", 
892
 
                       gTotalWriteTransferTime.getElapsedTimeStr().c_str());
893
 
         gLogger->note(device, "Total write transfer rate: %11.2Lf %-5s\n",
894
 
                       writeTransferRate, getTransferRateUnitsStr(gUnits));
895
 
      }
896
 
      if (gTotalBytesRead > 0)
 
1080
      long double writeTransferRate = convertCapacity((long double)gTotalBytesWritten, gUnits)/(long double)gTotalWriteTransferTime.getTime();
 
1081
      long double writeIops = (long double)gTotalWriteOps/(long double)gTotalWriteTransferTime.getTime();
 
1082
      gLogger->note(device, "Total write transfer time (WTT): %17s\n", 
 
1083
                    gTotalWriteTransferTime.getElapsedTimeStr().c_str());
 
1084
      gLogger->note(device, "Total write transfer rate (WTR): %11.2Lf %-5s\n",
 
1085
                    writeTransferRate, getTransferRateUnitsStr(gUnits));
 
1086
      gLogger->note(device, "Total write IOPS:                %11.2Lf IOPS\n", writeIops);
 
1087
                    
 
1088
   }
 
1089
   if (gTotalBytesRead > 0)
897
1090
      
898
 
      {
899
 
         long double readTransferRate = convertCapacity((long double)gTotalBytesRead, gUnits)/(long double)gTotalReadTransferTime.getTime();
900
 
         gLogger->note(device, "Total read transfer time:  %17s\n", 
901
 
                       gTotalReadTransferTime.getElapsedTimeStr().c_str());
902
 
         gLogger->note(device, "Total read transfer rate:  %11.2Lf %-5s\n",
903
 
                       readTransferRate, getTransferRateUnitsStr(gUnits));
904
 
      }
 
1091
   {
 
1092
      long double readTransferRate = convertCapacity((long double)gTotalBytesRead, gUnits)/(long double)gTotalReadTransferTime.getTime();
 
1093
      long double readIops = (long double)gTotalReadOps/(long double)gTotalWriteTransferTime.getTime();
 
1094
      gLogger->note(device, "Total read transfer time (RTT):  %17s\n", 
 
1095
                    gTotalReadTransferTime.getElapsedTimeStr().c_str());
 
1096
      gLogger->note(device, "Total read transfer rate (RTR):  %11.2Lf %-5s\n",
 
1097
                    readTransferRate, getTransferRateUnitsStr(gUnits));
 
1098
      gLogger->note(device, "Total read IOPS:                 %11.2Lf IOPS\n", readIops);
905
1099
   }
906
1100
}
907
1101
 
1126
1320
      break;
1127
1321
   }
1128
1322
 
 
1323
   // Update IOPS.
 
1324
   switch (ioDirection)
 
1325
   {
 
1326
   case READING:
 
1327
      gTotalReadOps += job->getTotalNumberOfTransfers(); 
 
1328
      break;
 
1329
   case WRITING:
 
1330
      gTotalWriteOps += job->getTotalNumberOfTransfers(); 
 
1331
      break;
 
1332
   }
 
1333
 
1129
1334
   cumulative_statistics(job, iteration, ioDirection);
1130
1335
   gDisplay->endJob();
1131
1336
}
1225
1430
   // Process command-line options.
1226
1431
   gPrgName = argv[0];
1227
1432
   const char *prgBasename = basename(gPrgName);
 
1433
   string cmdArgs;
1228
1434
   
1229
1435
   for (int i = 1; PROG_NAME_LOOKUP[i] != (char *)NULL; i++)
1230
1436
   {
1235
1441
      }
1236
1442
   }
1237
1443
 
1238
 
   if (!parse_options(argc, (const char **)argv))
 
1444
   if (!parse_options(argc, (const char **)argv, cmdArgs))
1239
1445
   {
1240
1446
      exit(EXIT_ERROR_USAGE);
1241
1447
   }
1277
1483
   gDisplay->setCurrentUnits(gUnits);
1278
1484
   gProgramStartTime = TimeHack::getCurrentTime();
1279
1485
   gLogger->logStart();
1280
 
   gLogger->logCmdLine(argc, argv);
 
1486
   gLogger->logCmdLine(cmdArgs.c_str());
1281
1487
   gLogger->logNote("\n");
1282
1488
   gDisplay->startRun();
1283
1489