2012-01-09 00:51:04 +04:00
|
|
|
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
|
|
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
|
|
*/
|
2011-06-17 23:20:43 +04:00
|
|
|
/******************************************************************************\
|
|
|
|
* *
|
|
|
|
* Copyright (c) 2003, The Regents of the University of California *
|
|
|
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
|
|
|
* *
|
|
|
|
********************************************************************************
|
|
|
|
*
|
2011-10-28 01:12:26 +04:00
|
|
|
* Parse commandline functions.
|
2011-06-17 23:20:43 +04:00
|
|
|
*
|
|
|
|
\******************************************************************************/
|
|
|
|
|
2011-11-12 04:40:45 +04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2011-11-12 04:40:45 +04:00
|
|
|
#include <ctype.h>
|
2011-06-17 23:20:43 +04:00
|
|
|
#include <string.h>
|
|
|
|
|
2018-07-07 10:41:33 +03:00
|
|
|
|
2018-07-07 12:29:27 +03:00
|
|
|
#include <getopt/optlist.h>
|
|
|
|
#include "utilities.h"
|
2011-11-12 04:40:45 +04:00
|
|
|
#include "ior.h"
|
|
|
|
#include "aiori.h"
|
|
|
|
#include "parse_options.h"
|
|
|
|
|
2017-09-21 18:12:31 +03:00
|
|
|
#define ISPOWEROFTWO(x) ((x != 0) && !(x & (x - 1)))
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
IOR_param_t initialTestParams;
|
|
|
|
|
2012-01-09 06:41:30 +04:00
|
|
|
/*
|
|
|
|
* Takes a string of the form 64, 8m, 128k, 4g, etc. and converts to bytes.
|
|
|
|
*/
|
|
|
|
static IOR_offset_t StringToBytes(char *size_str)
|
|
|
|
{
|
|
|
|
IOR_offset_t size = 0;
|
|
|
|
char range;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = sscanf(size_str, " %lld %c ", &size, &range);
|
|
|
|
if (rc == 2) {
|
|
|
|
switch ((int)range) {
|
|
|
|
case 'k':
|
|
|
|
case 'K':
|
|
|
|
size <<= 10;
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
case 'M':
|
|
|
|
size <<= 20;
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
case 'G':
|
|
|
|
size <<= 30;
|
|
|
|
break;
|
2018-07-07 12:29:27 +03:00
|
|
|
case 't':
|
|
|
|
case 'T':
|
|
|
|
size <<= 40;
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
case 'P':
|
|
|
|
size <<= 50;
|
|
|
|
break;
|
2012-01-09 06:41:30 +04:00
|
|
|
}
|
|
|
|
} else if (rc == 0) {
|
|
|
|
size = -1;
|
|
|
|
}
|
|
|
|
return (size);
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t NodeMemoryStringToBytes(char *size_str)
|
|
|
|
{
|
|
|
|
int percent;
|
|
|
|
int rc;
|
|
|
|
long page_size;
|
|
|
|
long num_pages;
|
|
|
|
long long mem;
|
|
|
|
|
|
|
|
rc = sscanf(size_str, " %d %% ", &percent);
|
|
|
|
if (rc == 0)
|
|
|
|
return (size_t)StringToBytes(size_str);
|
|
|
|
if (percent > 100 || percent < 0)
|
|
|
|
ERR("percentage must be between 0 and 100");
|
|
|
|
|
|
|
|
page_size = sysconf(_SC_PAGESIZE);
|
2014-07-31 03:17:21 +04:00
|
|
|
#ifdef _SC_PHYS_PAGES
|
2012-01-09 06:41:30 +04:00
|
|
|
num_pages = sysconf(_SC_PHYS_PAGES);
|
|
|
|
if (num_pages == -1)
|
|
|
|
ERR("sysconf(_SC_PHYS_PAGES) is not supported");
|
2014-07-31 03:17:21 +04:00
|
|
|
#else
|
|
|
|
ERR("sysconf(_SC_PHYS_PAGES) is not supported");
|
|
|
|
#endif
|
2012-01-09 06:41:30 +04:00
|
|
|
mem = page_size * num_pages;
|
|
|
|
|
|
|
|
return mem / 100 * percent;
|
|
|
|
}
|
|
|
|
|
2011-12-13 09:00:18 +04:00
|
|
|
static void RecalculateExpectedFileSize(IOR_param_t *params)
|
|
|
|
{
|
|
|
|
params->expectedAggFileSize =
|
|
|
|
params->blockSize * params->segmentCount * params->numTasks;
|
|
|
|
}
|
|
|
|
|
2011-06-17 23:20:43 +04:00
|
|
|
/*
|
|
|
|
* Check and correct all settings of each test in queue for correctness.
|
|
|
|
*/
|
2011-12-13 09:00:18 +04:00
|
|
|
static void CheckRunSettings(IOR_test_t *tests)
|
2011-11-12 02:22:17 +04:00
|
|
|
{
|
2014-08-26 01:51:28 +04:00
|
|
|
IOR_test_t *ptr;
|
|
|
|
IOR_param_t *params;
|
|
|
|
|
|
|
|
for (ptr = tests; ptr != NULL; ptr = ptr->next) {
|
|
|
|
params = &ptr->params;
|
2011-12-13 09:00:18 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
/* If no write/read/check action requested, set both write and read */
|
2011-12-13 09:00:18 +04:00
|
|
|
if (params->writeFile == FALSE
|
|
|
|
&& params->readFile == FALSE
|
|
|
|
&& params->checkWrite == FALSE
|
|
|
|
&& params->checkRead == FALSE) {
|
|
|
|
params->readFile = TRUE;
|
|
|
|
params->writeFile = TRUE;
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2014-08-26 01:51:28 +04:00
|
|
|
|
|
|
|
/* If only read or write is requested, then fix the default
|
|
|
|
* openFlags to not be open RDWR. It matters in the case
|
|
|
|
* of HDFS, which doesn't support opening RDWR.
|
2015-05-19 18:36:28 +03:00
|
|
|
* (We assume int-valued params are exclusively 0 or 1.)
|
2014-08-26 01:51:28 +04:00
|
|
|
*/
|
|
|
|
if ((params->openFlags & IOR_RDWR)
|
2018-07-07 12:29:27 +03:00
|
|
|
&& ((params->readFile | params->checkRead)
|
|
|
|
^ (params->writeFile | params->checkWrite))
|
|
|
|
&& (params->openFlags & IOR_RDWR)) {
|
|
|
|
|
2014-08-26 01:51:28 +04:00
|
|
|
params->openFlags &= ~(IOR_RDWR);
|
2018-07-07 12:29:27 +03:00
|
|
|
if (params->readFile | params->checkRead) {
|
2014-08-26 01:51:28 +04:00
|
|
|
params->openFlags |= IOR_RDONLY;
|
2017-04-28 23:01:30 +03:00
|
|
|
params->openFlags &= ~(IOR_CREAT|IOR_EXCL);
|
|
|
|
}
|
2014-08-26 01:51:28 +04:00
|
|
|
else
|
|
|
|
params->openFlags |= IOR_WRONLY;
|
|
|
|
}
|
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
/* If numTasks set to 0, use all tasks */
|
2011-12-13 09:00:18 +04:00
|
|
|
if (params->numTasks == 0) {
|
2018-07-07 12:29:27 +03:00
|
|
|
MPI_CHECK(MPI_Comm_size(mpi_comm_world,
|
2014-08-26 01:51:28 +04:00
|
|
|
¶ms->numTasks),
|
2011-11-12 02:22:17 +04:00
|
|
|
"MPI_Comm_size() error");
|
2014-08-26 01:51:28 +04:00
|
|
|
RecalculateExpectedFileSize(params);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Set flags from commandline string/value pairs.
|
|
|
|
*/
|
2011-12-13 09:00:18 +04:00
|
|
|
void DecodeDirective(char *line, IOR_param_t *params)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
char option[MAX_STR];
|
|
|
|
char value[MAX_STR];
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
rc = sscanf(line, " %[^=# \t\r\n] = %[^# \t\r\n] ", option, value);
|
|
|
|
if (rc != 2 && rank == 0) {
|
2018-07-07 12:29:27 +03:00
|
|
|
fprintf(out_logfile, "Syntax error in configuration options: %s\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
line);
|
|
|
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
|
|
|
}
|
|
|
|
if (strcasecmp(option, "api") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
strcpy(params->api, value);
|
2018-07-08 15:07:32 +03:00
|
|
|
} else if (strcasecmp(option, "summaryFile") == 0) {
|
|
|
|
out_logfile = fopen(value, "w");
|
|
|
|
if (out_logfile == NULL){
|
|
|
|
FAIL("Cannot open output file for writes!");
|
|
|
|
}
|
2018-07-08 15:38:05 +03:00
|
|
|
printf("Writing output to %s\n", value);
|
2018-07-08 15:07:32 +03:00
|
|
|
} else if (strcasecmp(option, "summaryFormat") == 0) {
|
|
|
|
if(strcasecmp(value, "default")){
|
|
|
|
outputFormat = OUTPUT_DEFAULT;
|
|
|
|
}else if(strcasecmp(value, "JSON")){
|
|
|
|
outputFormat = OUTPUT_JSON;
|
|
|
|
}else if(strcasecmp(value, "CSV")){
|
|
|
|
outputFormat = OUTPUT_CSV;
|
|
|
|
}else{
|
|
|
|
FAIL("Unknown summaryFormat");
|
|
|
|
}
|
2012-01-14 02:05:13 +04:00
|
|
|
} else if (strcasecmp(option, "refnum") == 0) {
|
|
|
|
params->referenceNumber = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "debug") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
strcpy(params->debug, value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "platform") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
strcpy(params->platform, value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "testfile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
strcpy(params->testFileName, value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "hintsfilename") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
strcpy(params->hintsFileName, value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "deadlineforstonewalling") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->deadlineForStonewalling = atoi(value);
|
2017-10-20 19:02:24 +03:00
|
|
|
} else if (strcasecmp(option, "stoneWallingWearOut") == 0) {
|
|
|
|
params->stoneWallingWearOut = atoi(value);
|
2017-10-21 12:59:09 +03:00
|
|
|
} else if (strcasecmp(option, "stoneWallingWearOutIterations") == 0) {
|
2018-07-07 12:29:27 +03:00
|
|
|
params->stoneWallingWearOutIterations = atoll(value);
|
2018-07-07 16:01:11 +03:00
|
|
|
} else if (strcasecmp(option, "stoneWallingStatusFile") == 0) {
|
|
|
|
strcpy(params->stoneWallingStatusFile, value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "maxtimeduration") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->maxTimeDuration = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "outlierthreshold") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->outlierThreshold = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "nodes") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->nodes = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "repetitions") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->repetitions = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "intertestdelay") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->interTestDelay = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "readfile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->readFile = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "writefile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->writeFile = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "fileperproc") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->filePerProc = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "taskpernodeoffset") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->taskPerNodeOffset = atoi(value);
|
2012-01-09 01:21:20 +04:00
|
|
|
} else if (strcasecmp(option, "reordertasksconstant") == 0) {
|
|
|
|
params->reorderTasks = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "reordertasksrandom") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->reorderTasksRandom = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "reordertasksrandomSeed") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->reorderTasksRandomSeed = atoi(value);
|
2012-01-09 01:21:20 +04:00
|
|
|
} else if (strcasecmp(option, "reordertasks") == 0) {
|
|
|
|
/* Backwards compatibility for the "reorderTasks" option.
|
|
|
|
MUST follow the other longer reordertasks checks. */
|
|
|
|
params->reorderTasks = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "checkwrite") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->checkWrite = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "checkread") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->checkRead = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "keepfile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->keepFile = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "keepfilewitherror") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->keepFileWithError = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "multiFile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->multiFile = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "quitonerror") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->quitOnError = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "segmentcount") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->segmentCount = StringToBytes(value);
|
|
|
|
RecalculateExpectedFileSize(params);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "blocksize") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->blockSize = StringToBytes(value);
|
|
|
|
RecalculateExpectedFileSize(params);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "transfersize") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->transferSize = StringToBytes(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "setalignment") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->setAlignment = StringToBytes(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "singlexferattempt") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->singleXferAttempt = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "individualdatasets") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->individualDataSets = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "intraTestBarriers") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->intraTestBarriers = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "nofill") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->noFill = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "verbose") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->verbose = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "settimestampsignature") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->setTimeStampSignature = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "collective") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->collective = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "preallocate") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->preallocate = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "storefileoffset") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->storeFileOffset = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "usefileview") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->useFileView = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "usesharedfilepointer") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->useSharedFilePointer = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "useo_direct") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->useO_DIRECT = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "usestrideddatatype") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->useStridedDatatype = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "showhints") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->showHints = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "showhelp") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->showHelp = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "uniqueDir") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->uniqueDir = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "useexistingtestfile") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->useExistingTestFile = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "fsyncperwrite") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->fsyncPerWrite = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "fsync") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->fsync = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "randomoffset") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->randomOffset = atoi(value);
|
2012-01-07 05:29:45 +04:00
|
|
|
} else if (strcasecmp(option, "memoryPerTask") == 0) {
|
|
|
|
params->memoryPerTask = StringToBytes(value);
|
2012-01-09 06:41:30 +04:00
|
|
|
params->memoryPerNode = 0;
|
|
|
|
} else if (strcasecmp(option, "memoryPerNode") == 0) {
|
|
|
|
params->memoryPerNode = NodeMemoryStringToBytes(value);
|
|
|
|
params->memoryPerTask = 0;
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "lustrestripecount") == 0) {
|
2011-11-10 02:30:21 +04:00
|
|
|
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
2011-11-12 02:22:17 +04:00
|
|
|
ERR("ior was not compiled with Lustre support");
|
2011-11-10 02:30:21 +04:00
|
|
|
#endif
|
2011-12-13 09:00:18 +04:00
|
|
|
params->lustre_stripe_count = atoi(value);
|
|
|
|
params->lustre_set_striping = 1;
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "lustrestripesize") == 0) {
|
2011-11-10 02:30:21 +04:00
|
|
|
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
2011-11-12 02:22:17 +04:00
|
|
|
ERR("ior was not compiled with Lustre support");
|
2011-11-10 02:30:21 +04:00
|
|
|
#endif
|
2011-12-13 09:00:18 +04:00
|
|
|
params->lustre_stripe_size = StringToBytes(value);
|
|
|
|
params->lustre_set_striping = 1;
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "lustrestartost") == 0) {
|
2011-11-10 02:30:21 +04:00
|
|
|
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
2011-11-12 02:22:17 +04:00
|
|
|
ERR("ior was not compiled with Lustre support");
|
2011-11-10 02:30:21 +04:00
|
|
|
#endif
|
2011-12-13 09:00:18 +04:00
|
|
|
params->lustre_start_ost = atoi(value);
|
|
|
|
params->lustre_set_striping = 1;
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "lustreignorelocks") == 0) {
|
2011-11-10 02:30:21 +04:00
|
|
|
#ifndef HAVE_LUSTRE_LUSTRE_USER_H
|
2011-11-12 02:22:17 +04:00
|
|
|
ERR("ior was not compiled with Lustre support");
|
2011-11-10 02:30:21 +04:00
|
|
|
#endif
|
2011-12-13 09:00:18 +04:00
|
|
|
params->lustre_ignore_locks = atoi(value);
|
2013-09-26 17:48:50 +04:00
|
|
|
} else if (strcasecmp(option, "gpfshintaccess") == 0) {
|
|
|
|
#ifndef HAVE_GPFS_FCNTL_H
|
|
|
|
ERR("ior was not compiled with GPFS hint support");
|
|
|
|
#endif
|
|
|
|
params->gpfs_hint_access = atoi(value);
|
|
|
|
} else if (strcasecmp(option, "gpfsreleasetoken") == 0) {
|
|
|
|
#ifndef HAVE_GPFS_FCNTL_H
|
|
|
|
ERR("ior was not compiled with GPFS hint support");
|
|
|
|
#endif
|
|
|
|
params->gpfs_release_token = atoi(value);
|
2017-09-21 18:12:31 +03:00
|
|
|
} else if (strcasecmp(option, "beegfsNumTargets") == 0) {
|
|
|
|
#ifndef HAVE_BEEGFS_BEEGFS_H
|
|
|
|
ERR("ior was not compiled with BeeGFS support");
|
|
|
|
#endif
|
|
|
|
params->beegfs_numTargets = atoi(value);
|
|
|
|
if (params->beegfs_numTargets < 1)
|
|
|
|
ERR("beegfsNumTargets must be >= 1");
|
|
|
|
} else if (strcasecmp(option, "beegfsChunkSize") == 0) {
|
|
|
|
#ifndef HAVE_BEEGFS_BEEGFS_H
|
2018-07-07 10:41:33 +03:00
|
|
|
ERR("ior was not compiled with BeeGFS support");
|
2017-09-21 18:12:31 +03:00
|
|
|
#endif
|
|
|
|
params->beegfs_chunkSize = StringToBytes(value);
|
|
|
|
if (!ISPOWEROFTWO(params->beegfs_chunkSize) || params->beegfs_chunkSize < (1<<16))
|
|
|
|
ERR("beegfsChunkSize must be a power of two and >64k");
|
2011-11-12 02:22:17 +04:00
|
|
|
} else if (strcasecmp(option, "numtasks") == 0) {
|
2011-12-13 09:00:18 +04:00
|
|
|
params->numTasks = atoi(value);
|
|
|
|
RecalculateExpectedFileSize(params);
|
2012-01-14 01:27:55 +04:00
|
|
|
} else if (strcasecmp(option, "summaryalways") == 0) {
|
|
|
|
params->summary_every_test = atoi(value);
|
2011-11-12 02:22:17 +04:00
|
|
|
} else {
|
|
|
|
if (rank == 0)
|
2018-07-07 12:29:27 +03:00
|
|
|
fprintf(out_logfile, "Unrecognized parameter \"%s\"\n",
|
2011-11-12 02:22:17 +04:00
|
|
|
option);
|
|
|
|
MPI_CHECK(MPI_Abort(MPI_COMM_WORLD, -1), "MPI_Abort() error");
|
|
|
|
}
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse a single line, which may contain multiple comma-seperated directives
|
|
|
|
*/
|
2011-11-12 02:22:17 +04:00
|
|
|
void ParseLine(char *line, IOR_param_t * test)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
char *start, *end;
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
start = line;
|
|
|
|
do {
|
|
|
|
end = strchr(start, ',');
|
|
|
|
if (end != NULL)
|
|
|
|
*end = '\0';
|
|
|
|
DecodeDirective(start, test);
|
|
|
|
start = end + 1;
|
|
|
|
} while (end != NULL);
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Determines if the string "haystack" contains only the string "needle", and
|
|
|
|
* possibly whitespace before and after needle. Function is case insensitive.
|
|
|
|
*/
|
2011-11-12 02:22:17 +04:00
|
|
|
int contains_only(char *haystack, char *needle)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
char *ptr, *end;
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
end = haystack + strlen(haystack);
|
|
|
|
/* skip over leading shitspace */
|
|
|
|
for (ptr = haystack; ptr < end; ptr++) {
|
|
|
|
if (!isspace(*ptr))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* check for "needle" */
|
|
|
|
if (strncasecmp(ptr, needle, strlen(needle)) != 0)
|
|
|
|
return 0;
|
|
|
|
/* make sure the rest of the line is only whitspace as well */
|
|
|
|
for (ptr += strlen(needle); ptr < end; ptr++) {
|
|
|
|
if (!isspace(*ptr))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Read the configuration script, allocating and filling in the structure of
|
|
|
|
* global parameters.
|
|
|
|
*/
|
2011-12-13 09:00:18 +04:00
|
|
|
IOR_test_t *ReadConfigScript(char *scriptName)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2011-11-12 02:22:17 +04:00
|
|
|
int test_num = 0;
|
|
|
|
int runflag = 0;
|
|
|
|
char linebuf[MAX_STR];
|
|
|
|
char empty[MAX_STR];
|
|
|
|
FILE *file;
|
2011-12-13 09:00:18 +04:00
|
|
|
IOR_test_t *head = NULL;
|
|
|
|
IOR_test_t *tail = NULL;
|
2011-11-12 02:22:17 +04:00
|
|
|
|
|
|
|
/* Initialize the first test */
|
2011-12-13 09:00:18 +04:00
|
|
|
head = CreateTest(&initialTestParams, test_num++);
|
2011-11-12 02:22:17 +04:00
|
|
|
tail = head;
|
|
|
|
|
|
|
|
/* open the script */
|
|
|
|
file = fopen(scriptName, "r");
|
|
|
|
if (file == NULL)
|
|
|
|
ERR("fopen() failed");
|
|
|
|
|
|
|
|
/* search for the "IOR START" line */
|
|
|
|
while (fgets(linebuf, MAX_STR, file) != NULL) {
|
|
|
|
if (contains_only(linebuf, "ior start")) {
|
|
|
|
break;
|
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
2011-11-12 02:22:17 +04:00
|
|
|
|
|
|
|
/* Iterate over a block of IOR commands */
|
|
|
|
while (fgets(linebuf, MAX_STR, file) != NULL) {
|
|
|
|
/* skip empty lines */
|
|
|
|
if (sscanf(linebuf, "%s", empty) == -1)
|
|
|
|
continue;
|
|
|
|
/* skip lines containing only comments */
|
|
|
|
if (sscanf(linebuf, " #%s", empty) == 1)
|
|
|
|
continue;
|
|
|
|
if (contains_only(linebuf, "ior stop")) {
|
2014-08-26 01:51:28 +04:00
|
|
|
AllocResults(tail);
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
|
|
|
} else if (contains_only(linebuf, "run")) {
|
2012-01-14 01:40:03 +04:00
|
|
|
if (runflag) {
|
|
|
|
/* previous line was a "run" as well
|
|
|
|
create duplicate test */
|
|
|
|
tail->next = CreateTest(&tail->params, test_num++);
|
|
|
|
tail = tail->next;
|
|
|
|
}
|
2014-08-26 01:51:28 +04:00
|
|
|
AllocResults(tail);
|
2011-11-12 02:22:17 +04:00
|
|
|
runflag = 1;
|
2011-12-13 09:00:18 +04:00
|
|
|
} else if (runflag) {
|
2011-11-12 02:22:17 +04:00
|
|
|
/* If this directive was preceded by a "run" line, then
|
|
|
|
create and initialize a new test structure */
|
2014-08-26 01:51:28 +04:00
|
|
|
runflag = 0;
|
|
|
|
tail->next = CreateTest(&tail->params, test_num++);
|
|
|
|
tail = tail->next;
|
2011-12-13 09:00:18 +04:00
|
|
|
ParseLine(linebuf, &tail->params);
|
2014-08-26 01:51:28 +04:00
|
|
|
} else {
|
2011-12-13 09:00:18 +04:00
|
|
|
ParseLine(linebuf, &tail->params);
|
2011-11-12 02:22:17 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
/* close the script */
|
|
|
|
if (fclose(file) != 0)
|
|
|
|
ERR("fclose() of script file failed");
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-12-13 09:00:18 +04:00
|
|
|
return head;
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse Commandline.
|
|
|
|
*/
|
2011-12-13 09:00:18 +04:00
|
|
|
IOR_test_t *ParseCommandLine(int argc, char **argv)
|
2011-06-17 23:20:43 +04:00
|
|
|
{
|
2018-07-07 12:29:27 +03:00
|
|
|
char * const opts =
|
2015-05-21 21:05:56 +03:00
|
|
|
"a:A:b:BcCd:D:eEf:FgG:hHi:Ij:J:kKl:mM:nN:o:O:pPqQ:rRs:St:T:uU:vVwWxX:YzZ";
|
2018-07-07 10:41:33 +03:00
|
|
|
int i;
|
2018-07-07 12:29:27 +03:00
|
|
|
IOR_test_t *tests = NULL;
|
|
|
|
char * optarg;
|
2011-11-12 02:22:17 +04:00
|
|
|
|
|
|
|
init_IOR_Param_t(&initialTestParams);
|
|
|
|
GetPlatformName(initialTestParams.platform);
|
|
|
|
initialTestParams.writeFile = initialTestParams.readFile = FALSE;
|
|
|
|
initialTestParams.checkWrite = initialTestParams.checkRead = FALSE;
|
|
|
|
|
2018-07-07 10:41:33 +03:00
|
|
|
option_t *optList, *thisOpt;
|
|
|
|
optList = GetOptList(argc, argv, opts);
|
|
|
|
|
|
|
|
while (optList != NULL) {
|
|
|
|
thisOpt = optList;
|
|
|
|
optarg = thisOpt->argument;
|
|
|
|
optList = optList->next;
|
|
|
|
switch (thisOpt->option) {
|
2011-11-12 02:22:17 +04:00
|
|
|
case 'a':
|
|
|
|
strcpy(initialTestParams.api, optarg);
|
|
|
|
break;
|
2015-05-19 18:36:28 +03:00
|
|
|
case 'A':
|
|
|
|
initialTestParams.referenceNumber = atoi(optarg);
|
|
|
|
break;
|
2011-11-12 02:22:17 +04:00
|
|
|
case 'b':
|
|
|
|
initialTestParams.blockSize = StringToBytes(optarg);
|
2012-01-14 01:28:14 +04:00
|
|
|
RecalculateExpectedFileSize(&initialTestParams);
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
|
|
|
case 'B':
|
|
|
|
initialTestParams.useO_DIRECT = TRUE;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
initialTestParams.collective = TRUE;
|
|
|
|
break;
|
|
|
|
case 'C':
|
|
|
|
initialTestParams.reorderTasks = TRUE;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
initialTestParams.interTestDelay = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
initialTestParams.deadlineForStonewalling =
|
|
|
|
atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
initialTestParams.fsync = TRUE;
|
|
|
|
break;
|
|
|
|
case 'E':
|
|
|
|
initialTestParams.useExistingTestFile = TRUE;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
tests = ReadConfigScript(optarg);
|
|
|
|
break;
|
|
|
|
case 'F':
|
|
|
|
initialTestParams.filePerProc = TRUE;
|
|
|
|
break;
|
|
|
|
case 'g':
|
|
|
|
initialTestParams.intraTestBarriers = TRUE;
|
|
|
|
break;
|
|
|
|
case 'G':
|
2015-05-21 21:05:56 +03:00
|
|
|
/* This option toggles between Incompressible Seed and Time stamp sig based on -l,
|
|
|
|
* so we'll toss the value in both for now, and sort it out in initialization
|
|
|
|
* after all the arguments are in and we know which it keep.
|
|
|
|
*/
|
2011-11-12 02:22:17 +04:00
|
|
|
initialTestParams.setTimeStampSignature = atoi(optarg);
|
2015-05-21 21:05:56 +03:00
|
|
|
initialTestParams.incompressibleSeed = atoi(optarg);
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
initialTestParams.showHelp = TRUE;
|
|
|
|
break;
|
|
|
|
case 'H':
|
|
|
|
initialTestParams.showHints = TRUE;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
initialTestParams.repetitions = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'I':
|
|
|
|
initialTestParams.individualDataSets = TRUE;
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
initialTestParams.outlierThreshold = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'J':
|
|
|
|
initialTestParams.setAlignment = StringToBytes(optarg);
|
|
|
|
break;
|
|
|
|
case 'k':
|
|
|
|
initialTestParams.keepFile = TRUE;
|
|
|
|
break;
|
|
|
|
case 'K':
|
|
|
|
initialTestParams.keepFileWithError = TRUE;
|
|
|
|
break;
|
|
|
|
case 'l':
|
2015-05-21 21:05:56 +03:00
|
|
|
switch(*optarg) {
|
|
|
|
case 'i': /* Incompressible */
|
|
|
|
initialTestParams.dataPacketType = incompressible;
|
|
|
|
break;
|
|
|
|
case 't': /* timestamp */
|
2017-10-20 19:02:24 +03:00
|
|
|
initialTestParams.dataPacketType = timestamp;
|
2015-05-21 21:05:56 +03:00
|
|
|
break;
|
|
|
|
case 'o': /* offset packet */
|
|
|
|
initialTestParams.storeFileOffset = TRUE;
|
|
|
|
initialTestParams.dataPacketType = offset;
|
|
|
|
break;
|
2017-10-20 19:02:24 +03:00
|
|
|
default:
|
2018-07-07 12:29:27 +03:00
|
|
|
fprintf(out_logfile,
|
2015-05-21 21:05:56 +03:00
|
|
|
"Unknown arguement for -l %s generic assumed\n", optarg);
|
|
|
|
break;
|
|
|
|
}
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
2015-05-19 18:36:28 +03:00
|
|
|
case 'm':
|
|
|
|
initialTestParams.multiFile = TRUE;
|
|
|
|
break;
|
2014-08-26 01:51:28 +04:00
|
|
|
case 'M':
|
2012-01-09 06:41:30 +04:00
|
|
|
initialTestParams.memoryPerNode =
|
|
|
|
NodeMemoryStringToBytes(optarg);
|
2012-01-07 05:29:45 +04:00
|
|
|
break;
|
2011-11-12 02:22:17 +04:00
|
|
|
case 'n':
|
|
|
|
initialTestParams.noFill = TRUE;
|
|
|
|
break;
|
|
|
|
case 'N':
|
|
|
|
initialTestParams.numTasks = atoi(optarg);
|
2012-01-14 01:28:14 +04:00
|
|
|
RecalculateExpectedFileSize(&initialTestParams);
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
|
|
|
case 'o':
|
|
|
|
strcpy(initialTestParams.testFileName, optarg);
|
|
|
|
break;
|
|
|
|
case 'O':
|
|
|
|
ParseLine(optarg, &initialTestParams);
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
initialTestParams.preallocate = TRUE;
|
|
|
|
break;
|
|
|
|
case 'P':
|
|
|
|
initialTestParams.useSharedFilePointer = TRUE;
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
initialTestParams.quitOnError = TRUE;
|
|
|
|
break;
|
2015-05-19 18:36:28 +03:00
|
|
|
case 'Q':
|
|
|
|
initialTestParams.taskPerNodeOffset = atoi(optarg);
|
|
|
|
break;
|
2011-11-12 02:22:17 +04:00
|
|
|
case 'r':
|
|
|
|
initialTestParams.readFile = TRUE;
|
|
|
|
break;
|
|
|
|
case 'R':
|
|
|
|
initialTestParams.checkRead = TRUE;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
initialTestParams.segmentCount = atoi(optarg);
|
2012-01-14 01:28:14 +04:00
|
|
|
RecalculateExpectedFileSize(&initialTestParams);
|
2011-11-12 02:22:17 +04:00
|
|
|
break;
|
|
|
|
case 'S':
|
|
|
|
initialTestParams.useStridedDatatype = TRUE;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
initialTestParams.transferSize = StringToBytes(optarg);
|
|
|
|
break;
|
|
|
|
case 'T':
|
|
|
|
initialTestParams.maxTimeDuration = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'u':
|
|
|
|
initialTestParams.uniqueDir = TRUE;
|
|
|
|
break;
|
|
|
|
case 'U':
|
|
|
|
strcpy(initialTestParams.hintsFileName, optarg);
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
initialTestParams.verbose++;
|
|
|
|
break;
|
|
|
|
case 'V':
|
|
|
|
initialTestParams.useFileView = TRUE;
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
initialTestParams.writeFile = TRUE;
|
|
|
|
break;
|
|
|
|
case 'W':
|
|
|
|
initialTestParams.checkWrite = TRUE;
|
|
|
|
break;
|
|
|
|
case 'x':
|
|
|
|
initialTestParams.singleXferAttempt = TRUE;
|
|
|
|
break;
|
2015-05-19 18:36:28 +03:00
|
|
|
case 'X':
|
|
|
|
initialTestParams.reorderTasksRandomSeed = atoi(optarg);
|
|
|
|
break;
|
|
|
|
case 'Y':
|
|
|
|
initialTestParams.fsyncPerWrite = TRUE;
|
|
|
|
break;
|
2011-11-12 02:22:17 +04:00
|
|
|
case 'z':
|
|
|
|
initialTestParams.randomOffset = TRUE;
|
|
|
|
break;
|
2015-05-19 18:36:28 +03:00
|
|
|
case 'Z':
|
|
|
|
initialTestParams.reorderTasksRandom = TRUE;
|
|
|
|
break;
|
2011-11-12 02:22:17 +04:00
|
|
|
default:
|
2018-07-07 12:29:27 +03:00
|
|
|
fprintf(out_logfile,
|
2011-11-12 02:22:17 +04:00
|
|
|
"ParseCommandLine: unknown option `-%c'.\n",
|
|
|
|
optopt);
|
|
|
|
}
|
2011-06-17 23:20:43 +04:00
|
|
|
}
|
|
|
|
|
2018-07-07 12:29:27 +03:00
|
|
|
tests = CreateTest(&initialTestParams, 0);
|
|
|
|
AllocResults(tests);
|
2011-06-17 23:20:43 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
CheckRunSettings(tests);
|
2011-11-10 04:13:44 +04:00
|
|
|
|
2011-11-12 02:22:17 +04:00
|
|
|
return (tests);
|
2011-11-12 03:11:28 +04:00
|
|
|
}
|