1176 lines
34 KiB
C
1176 lines
34 KiB
C
/*
|
|
* Disktest
|
|
* Copyright (c) International Business Machines Corp., 2001
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* Please send e-mail to yardleyb@us.ibm.com if you have
|
|
* questions or comments.
|
|
*
|
|
* Project Website: TBD
|
|
*
|
|
* $Id: parse.c,v 1.8 2009/02/26 12:02:23 subrata_modak Exp $
|
|
*
|
|
*/
|
|
#include <sys/types.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <signal.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "globals.h"
|
|
#include "threading.h"
|
|
#include "main.h"
|
|
#include "usage.h"
|
|
#include "sfunc.h"
|
|
#include "parse.h"
|
|
|
|
int fill_cld_args(int argc, char **argv, child_args_t * args)
|
|
{
|
|
extern char *optarg;
|
|
extern int optind;
|
|
extern unsigned long glb_flags;
|
|
|
|
signed char c;
|
|
char *leftovers;
|
|
|
|
while ((c =
|
|
getopt(argc, argv,
|
|
"?a:A:B:cC:dD:E:f:Fh:I:K:L:m:M:nN:o:p:P:qQrR:s:S:t:T:wvV:z"))
|
|
!= -1) {
|
|
switch (c) {
|
|
case ':':
|
|
pMsg(WARN, args, "Missing argument for perameter.\n");
|
|
usage();
|
|
return (-1);
|
|
case 'V':
|
|
#ifdef _DEBUG
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
exit(1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c argument is non numeric.\n", c);
|
|
exit(1);
|
|
}
|
|
gbl_dbg_lvl = atoi(optarg);
|
|
#else
|
|
pMsg(ERR, args,
|
|
"Debug code not compiled in, recompile with _DEBUG directive.\n",
|
|
c);
|
|
exit(1);
|
|
#endif
|
|
break;
|
|
case 'd':
|
|
glb_flags |= GLB_FLG_QUIET;
|
|
args->flags |= CLD_FLG_DUMP;
|
|
break;
|
|
case 'a':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
return (-1);
|
|
}
|
|
args->seed = (unsigned int)strtol(optarg, NULL, 0);
|
|
break;
|
|
case 'A':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
exit(1);
|
|
}
|
|
if (strchr(optarg, 'g')) {
|
|
glb_flags |= GLB_FLG_KILL;
|
|
}
|
|
if (strchr(optarg, 'c')) {
|
|
args->flags &= ~CLD_FLG_ALLDIE;
|
|
}
|
|
if (strchr(optarg, 'm')) {
|
|
args->flags |= CLD_FLG_ERR_MARK;
|
|
}
|
|
if (strchr(optarg, 'r')) {
|
|
args->flags &= ~CLD_FLG_ERR_REREAD;
|
|
}
|
|
if (strchr(optarg, 's')) {
|
|
args->flags &= ~CLD_FLG_LBA_SYNC;
|
|
}
|
|
if (strchr(optarg, 'S')) {
|
|
args->flags |= CLD_FLG_IO_SERIAL;
|
|
}
|
|
if (strchr(optarg, 'w')) {
|
|
args->flags |= CLD_FLG_WRITE_ONCE;
|
|
}
|
|
if (strchr(optarg, 'W')) {
|
|
args->flags |= CLD_FLG_UNIQ_WRT;
|
|
}
|
|
if (strchr(optarg, 't')) {
|
|
args->flags |= CLD_FLG_TMO_ERROR;
|
|
}
|
|
break;
|
|
case 'q':
|
|
glb_flags |= GLB_FLG_QUIET;
|
|
break;
|
|
case 'Q':
|
|
glb_flags |= GLB_FLG_SUPRESS;
|
|
break;
|
|
case 'v':
|
|
pMsg(INFO, args, "Version %s\n", VER_STR);
|
|
exit(0);
|
|
case 'p':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (args->flags & (CLD_FLG_LINEAR | CLD_FLG_RANDOM)) {
|
|
pMsg(WARN, args,
|
|
"Only one seek type, -p, can be specified.\n");
|
|
return (-1);
|
|
}
|
|
/* seek pattern type */
|
|
if (strchr(optarg, 'L'))
|
|
args->flags |= CLD_FLG_LINEAR;
|
|
else if (strchr(optarg, 'l'))
|
|
args->flags |=
|
|
(CLD_FLG_LINEAR | CLD_FLG_NTRLVD);
|
|
else if (strchr(optarg, 'R'))
|
|
args->flags |= CLD_FLG_RANDOM;
|
|
else if (strchr(optarg, 'r'))
|
|
args->flags |=
|
|
(CLD_FLG_RANDOM | CLD_FLG_NTRLVD);
|
|
else {
|
|
pMsg(WARN, args, "Unknown Seek pattern\n");
|
|
usage();
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, 'U') || strchr(optarg, 'u'))
|
|
if ((args->flags & (CLD_FLG_LINEAR)) &&
|
|
!(args->flags & CLD_FLG_LUND))
|
|
args->flags |= CLD_FLG_LUNU;
|
|
if (strchr(optarg, 'D') || strchr(optarg, 'd'))
|
|
if ((args->flags & (CLD_FLG_LINEAR)) &&
|
|
!(args->flags & CLD_FLG_LUNU))
|
|
args->flags |= CLD_FLG_LUND;
|
|
break;
|
|
case 'B':
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, ':') != NULL) { /* we are given a range of transfer sizes */
|
|
args->flags |= CLD_FLG_RTRSIZ;
|
|
args->ltrsiz = strtoul(optarg, &leftovers, 10);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* first value had a 'k' */
|
|
args->ltrsiz *= 2;
|
|
leftovers++;
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* first value had a 'm' */
|
|
args->ltrsiz *= (2 * 1024);
|
|
leftovers++;
|
|
} else {
|
|
if (args->ltrsiz > 256)
|
|
args->ltrsiz /= BLK_SIZE;
|
|
}
|
|
if (!isdigit(leftovers[1])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n",
|
|
c);
|
|
return (-1);
|
|
}
|
|
args->htrsiz =
|
|
atol((char *)strchr(leftovers, ':') + 1);
|
|
if ((strchr(leftovers, 'k')) != NULL) { /* second value had a 'k' */
|
|
args->htrsiz *= 2;
|
|
} else if ((strchr(leftovers, 'm')) != NULL) { /* second value had a 'm' */
|
|
args->htrsiz *= (2 * 1024);
|
|
} else {
|
|
if (args->htrsiz > 256)
|
|
args->htrsiz /= BLK_SIZE;
|
|
}
|
|
} else { /* only a single value given for transfer size */
|
|
args->ltrsiz = atoi(optarg);
|
|
if (strchr(optarg, 'k')) {
|
|
args->ltrsiz *= 2;
|
|
} else if (strchr(optarg, 'm')) {
|
|
args->ltrsiz *= (2 * 1024);
|
|
} else {
|
|
if (args->ltrsiz > 256)
|
|
args->ltrsiz /= BLK_SIZE;
|
|
}
|
|
args->htrsiz = args->ltrsiz;
|
|
}
|
|
#ifdef _DEBUG
|
|
PDBG5(DBUG, args, "Parsed Transfer size: %ld\n",
|
|
args->htrsiz);
|
|
#endif
|
|
break;
|
|
case 'c':
|
|
if (args->flags & CLD_FLG_PTYPS) {
|
|
pMsg(WARN, args,
|
|
"Please specify only one pattern type\n");
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_CPTYPE;
|
|
break;
|
|
case 'n':
|
|
if (args->flags & CLD_FLG_PTYPS) {
|
|
pMsg(WARN, args,
|
|
"Please specify only one pattern type\n");
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_LPTYPE;
|
|
break;
|
|
case 'f':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (args->flags & CLD_FLG_PTYPS) {
|
|
pMsg(WARN, args,
|
|
"Please specify only one pattern type\n");
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->pattern = my_strtofft(optarg);
|
|
args->flags |= CLD_FLG_FPTYPE;
|
|
break;
|
|
case 'F':
|
|
/* the filespec is a list of filespecs in a file */
|
|
args->flags |= CLD_FLG_FSLIST;
|
|
break;
|
|
case 'z':
|
|
if (args->flags & CLD_FLG_PTYPS) {
|
|
pMsg(WARN, args,
|
|
"Please specify only one pattern type\n");
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_RPTYPE;
|
|
break;
|
|
case 'h':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_HBEAT;
|
|
args->hbeat = atoi(optarg);
|
|
if (strchr(optarg, 'm')) { /* multiply by sec */
|
|
args->hbeat *= 60;
|
|
} else if (strchr(optarg, 'h')) { /* multiply sec*min */
|
|
args->hbeat *= (time_t) (60 * 60);
|
|
} else if (strchr(optarg, 'd')) { /* multiply by sec*min*hours */
|
|
args->hbeat *= (time_t) (60 * 60 * 24);
|
|
}
|
|
break;
|
|
case 'D':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->rperc = atoi(optarg);
|
|
args->wperc = atoi((char *)(strchr(optarg, ':') + 1));
|
|
args->flags |= CLD_FLG_DUTY;
|
|
break;
|
|
case 'r':
|
|
args->flags |= CLD_FLG_R;
|
|
break;
|
|
case 'w':
|
|
args->flags |= CLD_FLG_W;
|
|
break;
|
|
case 'o':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
args->offset = atol(optarg);
|
|
args->flags |= CLD_FLG_OFFSET;
|
|
break;
|
|
case 'R':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, ':') != NULL) { /* we are given a retry delay */
|
|
args->retries = strtol(optarg, &leftovers, 10);
|
|
args->retry_delay =
|
|
(time_t) atol((char *)strchr(leftovers, ':')
|
|
+ 1);
|
|
} else { /* only a retry count given */
|
|
args->retries = atoi(optarg);
|
|
}
|
|
break;
|
|
case 'M':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_ALT_MARK;
|
|
args->alt_mark = my_strtofft(optarg);
|
|
break;
|
|
case 'm':
|
|
args->flags |= CLD_FLG_MBLK;
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, 'l')) { /* returns NULL if char is not found */
|
|
args->flags |= CLD_FLG_MRK_LBA;
|
|
}
|
|
if (strchr(optarg, 'p')) {
|
|
args->flags |= CLD_FLG_MRK_PASS;
|
|
}
|
|
if (strchr(optarg, 't')) {
|
|
args->flags |= CLD_FLG_MRK_TIME;
|
|
}
|
|
if (strchr(optarg, 's')) {
|
|
args->flags |= CLD_FLG_MRK_SEED;
|
|
}
|
|
if (strchr(optarg, 'h')) {
|
|
args->flags |= CLD_FLG_MRK_HOST;
|
|
}
|
|
if (strchr(optarg, 'f')) {
|
|
args->flags |= CLD_FLG_MRK_TARGET;
|
|
}
|
|
if (strchr(optarg, 'a')) {
|
|
args->flags |= CLD_FLG_MRK_ALL;
|
|
}
|
|
if (!strchr(optarg, 'l') &&
|
|
!strchr(optarg, 'p') &&
|
|
!strchr(optarg, 't') &&
|
|
!strchr(optarg, 's') &&
|
|
!strchr(optarg, 'h') &&
|
|
!strchr(optarg, 'f') && !strchr(optarg, 'a')) {
|
|
pMsg(WARN, args,
|
|
"Unknown header mark option\n");
|
|
return (-1);
|
|
}
|
|
break;
|
|
case 'E':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments are non numeric.\n", c);
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_CMPR;
|
|
args->cmp_lng = strtol(optarg, NULL, 0);
|
|
if (strchr(optarg, 'k')) { /* multiply by 2^10 */
|
|
args->cmp_lng <<= 10;
|
|
} else if (strchr(optarg, 'K')) { /* multiply 10^3 */
|
|
args->cmp_lng *= 1000;
|
|
} else if (strchr(optarg, 'm')) { /* multiply by 2^20 */
|
|
args->cmp_lng <<= 20;
|
|
} else if (strchr(optarg, 'M')) { /* multiply by 10^6 */
|
|
args->cmp_lng *= 1000000;
|
|
}
|
|
break;
|
|
case 'N':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments are non numeric.\n", c);
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_VSIZ;
|
|
args->vsiz = my_strtofft(optarg);
|
|
if (strchr(optarg, 'k')) { /* multiply by 2^10 */
|
|
args->vsiz <<= 10;
|
|
} else if (strchr(optarg, 'K')) { /* multiply 10^3 */
|
|
args->vsiz *= 1000;
|
|
} else if (strchr(optarg, 'm')) { /* multiply by 2^20 */
|
|
args->vsiz <<= 20;
|
|
} else if (strchr(optarg, 'M')) { /* multiply by 10^6 */
|
|
args->vsiz *= 1000000;
|
|
} else if (strchr(optarg, 'g')) { /* multiply by 2^30 */
|
|
args->vsiz <<= 30;
|
|
} else if (strchr(optarg, 'G')) { /* multiply by 10^9 */
|
|
args->vsiz *= 1000000000;
|
|
}
|
|
break;
|
|
case 'I':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, 'R') || strchr(optarg, 'r')) {
|
|
if (!(args->flags & CLD_FLG_BLK) &&
|
|
!(args->flags & CLD_FLG_FILE)) {
|
|
args->flags |= CLD_FLG_RAW;
|
|
} else {
|
|
pMsg(WARN, args,
|
|
"Can only specify one IO type\n");
|
|
return (-1);
|
|
}
|
|
}
|
|
if (strchr(optarg, 'B') || strchr(optarg, 'b')) {
|
|
if (!(args->flags & CLD_FLG_RAW) &&
|
|
!(args->flags & CLD_FLG_FILE)) {
|
|
args->flags |= CLD_FLG_BLK;
|
|
} else {
|
|
pMsg(WARN, args,
|
|
"Can only specify one IO type\n");
|
|
return (-1);
|
|
}
|
|
}
|
|
if (strchr(optarg, 'F') || strchr(optarg, 'f')) {
|
|
if (!(args->flags & CLD_FLG_RAW) &&
|
|
!(args->flags & CLD_FLG_BLK)) {
|
|
args->flags |= CLD_FLG_FILE;
|
|
} else {
|
|
pMsg(WARN, args,
|
|
"Can only specify one IO type\n");
|
|
return (-1);
|
|
}
|
|
}
|
|
if (strchr(optarg, 'D') || strchr(optarg, 'd')) {
|
|
args->flags |= CLD_FLG_DIRECT;
|
|
}
|
|
if (strchr(optarg, 's')) {
|
|
args->sync_interval =
|
|
strtoul((char *)strchr(optarg, 's') + 1,
|
|
NULL, 10);
|
|
#ifdef _DEBUG
|
|
PDBG3(DBUG, args, "Parsed sync interval: %ld\n",
|
|
args->sync_interval);
|
|
#endif
|
|
if ((args->flags & CLD_FLG_DIRECT)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify sync with Direct IO\n");
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_WFSYNC;
|
|
}
|
|
break;
|
|
case 't':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
|
|
if (strchr(optarg, ':') != NULL) { /* we are given a option for delay & timeout */
|
|
args->delayTimeMin =
|
|
strtoul(optarg, &leftovers, 10);
|
|
/* check to see if we have one or more then one ':' */
|
|
if ((char *)strchr(optarg, ':') ==
|
|
(char *)strrchr(optarg, ':')) {
|
|
/* only one ':', assume no random delayTime, and ioTimeout */
|
|
args->delayTimeMax = args->delayTimeMin;
|
|
args->ioTimeout =
|
|
(time_t) atol((char *)
|
|
strchr(leftovers,
|
|
':') + 1);
|
|
} else {
|
|
/* more then one ':', assume random delayTime, and ioTimeout */
|
|
args->delayTimeMax =
|
|
strtoul(leftovers + 1, &leftovers,
|
|
10);
|
|
args->ioTimeout =
|
|
(time_t) atol((char *)
|
|
strchr(leftovers,
|
|
':') + 1);
|
|
}
|
|
if (strchr(leftovers, 'm')) { /* multiply by sec */
|
|
args->ioTimeout *= 60;
|
|
} else if (strchr(leftovers, 'h')) { /* multiply sec*min */
|
|
args->ioTimeout *= (time_t) (60 * 60);
|
|
} else if (strchr(leftovers, 'd')) { /* multiply by sec*min*hours */
|
|
args->ioTimeout *=
|
|
(time_t) (60 * 60 * 24);
|
|
}
|
|
} else {
|
|
args->delayTimeMin =
|
|
strtoul(optarg, NULL, 10);
|
|
args->delayTimeMax = args->delayTimeMin;
|
|
}
|
|
break;
|
|
case 'T':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
args->run_time = atoi(optarg);
|
|
args->flags |= CLD_FLG_TMD;
|
|
if (strchr(optarg, 'm')) { /* multiply by sec */
|
|
args->run_time *= 60;
|
|
} else if (strchr(optarg, 'h')) { /* multiply sec*min */
|
|
args->run_time *= (time_t) (60 * 60);
|
|
} else if (strchr(optarg, 'd')) { /* multiply by sec*min*hours */
|
|
args->run_time *= (time_t) (60 * 60 * 24);
|
|
}
|
|
break;
|
|
case 'L':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
args->seeks = atoi(optarg);
|
|
args->flags |= CLD_FLG_SKS;
|
|
if (strchr(optarg, 'k')) { /* multiply by 2^10 */
|
|
args->seeks <<= 10;
|
|
} else if (strchr(optarg, 'K')) { /* multiply 10^3 */
|
|
args->seeks *= 1000;
|
|
} else if (strchr(optarg, 'm')) { /* multiply by 2^20 */
|
|
args->seeks <<= 20;
|
|
} else if (strchr(optarg, 'M')) { /* multiply by 10^6 */
|
|
args->seeks *= 1000000;
|
|
} else if (strchr(optarg, 'g')) { /* multiply by 2^30 */
|
|
args->seeks <<= 30;
|
|
} else if (strchr(optarg, 'G')) { /* multiply by 10^9 */
|
|
args->seeks *= 1000000000;
|
|
}
|
|
break;
|
|
case 'C':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
usage();
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_CYC;
|
|
args->cycles = atol(optarg);
|
|
break;
|
|
case 'K':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (!isdigit(optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
usage();
|
|
return (-1);
|
|
}
|
|
if (atoi(optarg) > MAX_THREADS) {
|
|
pMsg(WARN, args,
|
|
"%u exceeds max of %u threads.\n",
|
|
atoi(optarg), MAX_THREADS);
|
|
return (-1);
|
|
}
|
|
args->t_kids = atoi(optarg);
|
|
break;
|
|
case 'P':
|
|
if (optarg == NULL) {
|
|
pMsg(WARN, args,
|
|
"-%c option requires an argument.\n", c);
|
|
return (-1);
|
|
}
|
|
if (strchr(optarg, 'X')) { /* returns NULL if char is not found */
|
|
args->flags |= CLD_FLG_XFERS;
|
|
}
|
|
if (strchr(optarg, 'T')) {
|
|
args->flags |= CLD_FLG_TPUTS;
|
|
}
|
|
if (strchr(optarg, 'P')) {
|
|
glb_flags |= GLB_FLG_PERFP;
|
|
}
|
|
if (strchr(optarg, 'R')) {
|
|
args->flags |= CLD_FLG_RUNT;
|
|
}
|
|
if (strchr(optarg, 'C')) {
|
|
args->flags |= CLD_FLG_PCYC;
|
|
}
|
|
if (strchr(optarg, 'A')) {
|
|
args->flags |= CLD_FLG_PRFTYPS;
|
|
}
|
|
if (!strchr(optarg, 'P') &&
|
|
!strchr(optarg, 'A') &&
|
|
!strchr(optarg, 'X') &&
|
|
!strchr(optarg, 'R') &&
|
|
!strchr(optarg, 'C') && !strchr(optarg, 'T')) {
|
|
pMsg(WARN, args,
|
|
"Unknown performance option\n");
|
|
return (-1);
|
|
}
|
|
break;
|
|
case 'S':
|
|
if (!isdigit((int)optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n", c);
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_BLK_RNG;
|
|
if (strchr(optarg, ':') != NULL) { /* we are given a range */
|
|
args->start_blk =
|
|
(OFF_T) strtoul(optarg, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->start_blk <<= 10;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->start_blk *= 1000;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->start_blk <<= 20;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->start_blk *= 1000000;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->start_blk <<= 30;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->start_blk *= 1000000000;
|
|
leftovers++; /* at the ':' */
|
|
}
|
|
leftovers++; /* should be at the next value */
|
|
if (!isdigit((int)leftovers[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c arguments is non numeric.\n",
|
|
c);
|
|
return (-1);
|
|
}
|
|
args->stop_blk =
|
|
(OFF_T) strtoul(leftovers, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->stop_blk <<= 10;
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->stop_blk *= 1000;
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->stop_blk <<= 20;
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->stop_blk *= 1000000;
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->stop_blk <<= 30;
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->stop_blk *= 1000000000;
|
|
}
|
|
} else { /* only a single value given */
|
|
args->start_blk =
|
|
(OFF_T) strtoul(optarg, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->start_blk <<= 10;
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->start_blk *= 1000;
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->start_blk <<= 20;
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->start_blk *= 1000000;
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->start_blk <<= 30;
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->start_blk *= 1000000000;
|
|
}
|
|
}
|
|
break;
|
|
case 's':
|
|
if (!isdigit((int)optarg[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c argument is non numeric.\n", c);
|
|
return (-1);
|
|
}
|
|
args->flags |= CLD_FLG_LBA_RNG;
|
|
if (strchr(optarg, ':') != NULL) { /* we are given a range */
|
|
args->start_lba =
|
|
(OFF_T) strtoul(optarg, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->start_lba <<= 10;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->start_lba *= 1000;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->start_lba <<= 20;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->start_lba *= 1000000;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->start_lba <<= 30;
|
|
leftovers++; /* at the ':' */
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->start_lba *= 1000000000;
|
|
leftovers++; /* at the ':' */
|
|
}
|
|
leftovers++; /* should be at the next value */
|
|
if (!isdigit((int)leftovers[0])) {
|
|
pMsg(WARN, args,
|
|
"-%c second argument is non numeric.\n",
|
|
c);
|
|
return (-1);
|
|
}
|
|
args->stop_lba =
|
|
(OFF_T) strtoul(leftovers, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->stop_lba <<= 10;
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->stop_lba *= 1000;
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->stop_lba <<= 20;
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->stop_lba *= 1000000;
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->stop_lba <<= 30;
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->stop_lba *= 1000000000;
|
|
}
|
|
} else { /* only a single value given */
|
|
args->start_lba =
|
|
(OFF_T) strtoul(optarg, &leftovers, 0);
|
|
if (leftovers == strchr(leftovers, 'k')) { /* multiply by 2^10 */
|
|
args->start_lba <<= 10;
|
|
} else if (leftovers == strchr(leftovers, 'K')) { /* multiply 10^3 */
|
|
args->start_lba *= 1000;
|
|
} else if (leftovers == strchr(leftovers, 'm')) { /* multiply by 2^20 */
|
|
args->start_lba <<= 20;
|
|
} else if (leftovers == strchr(leftovers, 'M')) { /* multiply by 10^6 */
|
|
args->start_lba *= 1000000;
|
|
} else if (leftovers == strchr(leftovers, 'g')) { /* multiply by 2^30 */
|
|
args->start_lba <<= 30;
|
|
} else if (leftovers == strchr(leftovers, 'G')) { /* multiply by 10^9 */
|
|
args->start_lba *= 1000000000;
|
|
}
|
|
}
|
|
break;
|
|
case '?':
|
|
default:
|
|
usage();
|
|
return (-1);
|
|
}
|
|
}
|
|
if (argv[optind] == NULL) {
|
|
pMsg(WARN, args, "Unspecified target.\n");
|
|
return (-1);
|
|
}
|
|
strncpy(args->device, argv[optind], (DEV_NAME_LEN - 1));
|
|
return 0;
|
|
}
|
|
|
|
int make_assumptions(child_args_t * args)
|
|
{
|
|
char TmpStr[80];
|
|
struct stat stat_buf;
|
|
int rv;
|
|
|
|
if (!(args->flags & CLD_FLG_IOTYPS)) {
|
|
/* use stat to get file properties, and use to set -I */
|
|
rv = stat(args->device, &stat_buf);
|
|
if (0 == rv) {
|
|
if (IS_FILE(stat_buf.st_mode)) {
|
|
strncat(args->argstr, "(-I f) ",
|
|
(MAX_ARG_LEN - 1) -
|
|
strlen(args->argstr));
|
|
args->flags |= CLD_FLG_FILE;
|
|
} else if (IS_BLK(stat_buf.st_mode)) {
|
|
strncat(args->argstr, "(-I b) ",
|
|
(MAX_ARG_LEN - 1) -
|
|
strlen(args->argstr));
|
|
args->flags |= CLD_FLG_BLK;
|
|
#ifndef WINDOWS
|
|
} else if (S_ISCHR(stat_buf.st_mode)) {
|
|
strncat(args->argstr, "(-I r) ",
|
|
(MAX_ARG_LEN - 1) -
|
|
strlen(args->argstr));
|
|
args->flags |= CLD_FLG_RAW;
|
|
#endif
|
|
}
|
|
} else {
|
|
pMsg(WARN, args,
|
|
"Can't get status on %s, defaulting to file, errno = %d\n",
|
|
args->device, GETLASTERROR());
|
|
strncat(args->argstr, "(-I f) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_FILE;
|
|
}
|
|
}
|
|
if ((args->flags & CLD_FLG_WFSYNC) && (0 == args->sync_interval)) {
|
|
pMsg(INFO, args,
|
|
"Sync interval set to zero, assuming interval of 1.\n");
|
|
args->sync_interval = 1;
|
|
}
|
|
|
|
if (args->ltrsiz <= 0) {
|
|
sprintf(TmpStr, "(-B %d) ", TRSIZ * BLK_SIZE);
|
|
strncat(args->argstr, TmpStr,
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->ltrsiz = TRSIZ;
|
|
args->htrsiz = TRSIZ;
|
|
}
|
|
if (args->flags & CLD_FLG_LBA_RNG) {
|
|
args->start_blk = args->start_lba / args->htrsiz;
|
|
if (!(args->stop_lba < 0))
|
|
args->stop_blk = args->stop_lba / args->htrsiz;
|
|
}
|
|
if (args->flags & CLD_FLG_BLK_RNG) {
|
|
args->start_lba = args->start_blk * args->htrsiz;
|
|
if (!(args->stop_blk < 0))
|
|
args->stop_lba =
|
|
(args->stop_blk * args->htrsiz) + (args->htrsiz -
|
|
1);
|
|
}
|
|
/* if vsiz is still not set, try and get it from the file */
|
|
if ((args->vsiz <= 0) && (args->flags & CLD_FLG_FILE)) {
|
|
if (0 != get_file_size(args->device)) { /* file size retrieved */
|
|
args->vsiz = get_file_size(args->device);
|
|
}
|
|
}
|
|
/* if vsiz is still not set, try and get it from the device */
|
|
if ((args->vsiz <= 0) && !(args->flags & CLD_FLG_FILE)) {
|
|
args->vsiz = get_vsiz(args->device);
|
|
}
|
|
/* if vsiz is still not set, set based on given range */
|
|
if ((args->vsiz <= 0)
|
|
&& (args->flags & (CLD_FLG_LBA_RNG | CLD_FLG_BLK_RNG))) {
|
|
if (!(args->stop_lba < 0))
|
|
args->vsiz = args->stop_lba + 1;
|
|
else
|
|
args->vsiz = args->start_lba + 1;
|
|
}
|
|
/* if vsiz is still not set, then set it to the default size */
|
|
if (args->vsiz <= 0) {
|
|
args->vsiz = VSIZ;
|
|
}
|
|
if (!(args->flags & CLD_FLG_VSIZ)) {
|
|
sprintf(TmpStr, N_ASSUME, args->vsiz);
|
|
strncat(args->argstr, TmpStr,
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
}
|
|
|
|
if (args->stop_lba == -1) {
|
|
args->stop_lba = args->vsiz - 1;
|
|
}
|
|
if (args->stop_blk == -1) {
|
|
args->stop_blk = (args->stop_lba / (OFF_T) args->htrsiz);
|
|
}
|
|
if (args->t_kids == 0) {
|
|
sprintf(TmpStr, "(-K %d) ", KIDS);
|
|
strncat(args->argstr, TmpStr,
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->t_kids = KIDS;
|
|
}
|
|
if ((args->flags & (CLD_FLG_W | CLD_FLG_R)) == 0) {
|
|
if (args->flags & CLD_FLG_DUTY) { /* no read/write but duty cycle specified */
|
|
if (args->rperc > 0) {
|
|
args->flags |= CLD_FLG_R;
|
|
strncat(args->argstr, "(-r) ",
|
|
(MAX_ARG_LEN - 1) -
|
|
strlen(args->argstr));
|
|
}
|
|
if (args->wperc > 0) {
|
|
args->flags |= CLD_FLG_W;
|
|
strncat(args->argstr, "(-w) ",
|
|
(MAX_ARG_LEN - 1) -
|
|
strlen(args->argstr));
|
|
}
|
|
} else {
|
|
strncat(args->argstr, "(-r) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_R;
|
|
}
|
|
}
|
|
if (!(args->flags & CLD_FLG_PTYPS)) {
|
|
strncat(args->argstr, "(-c) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_CPTYPE;
|
|
}
|
|
if (!(args->flags & CLD_FLG_SKTYPS)) {
|
|
strncat(args->argstr, "(-p R) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_RANDOM;
|
|
}
|
|
if (!(args->flags & CLD_FLG_SKS)) {
|
|
if (args->start_blk == args->stop_blk) { /* diskcache test, w/ no seek count set */
|
|
args->seeks = SEEKS;
|
|
} else if (args->flags & (CLD_FLG_BLK_RNG | CLD_FLG_LBA_RNG)) { /* range set, w/ no seek count */
|
|
args->seeks = args->stop_blk - args->start_blk + 1;
|
|
} else {
|
|
/* if vsiz is available, calculated seeks are in terms of the largest transfer size */
|
|
args->seeks =
|
|
(args->vsiz >
|
|
0) ? (args->vsiz / args->htrsiz) : SEEKS;
|
|
}
|
|
if ((args->flags & CLD_FLG_LINEAR) && (args->flags & CLD_FLG_R)
|
|
&& (args->flags & CLD_FLG_W)) {
|
|
args->seeks *= 2;
|
|
}
|
|
|
|
if (!(args->flags & CLD_FLG_TMD)) {
|
|
sprintf(TmpStr, L_ASSUME, args->seeks);
|
|
strncat(args->argstr, TmpStr,
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
}
|
|
}
|
|
if (!(args->flags & (CLD_FLG_SKS | CLD_FLG_TMD))
|
|
|| ((args->flags & CLD_FLG_CYC)
|
|
&& !(args->flags & (CLD_FLG_SKS | CLD_FLG_TMD)))) {
|
|
args->flags |= CLD_FLG_SKS;
|
|
}
|
|
if (args->flags & (CLD_FLG_LINEAR)) {
|
|
if (!(args->flags & (CLD_FLG_LUNU | CLD_FLG_LUND))) {
|
|
strncat(args->argstr, "(-p u) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_LUNU;
|
|
}
|
|
}
|
|
normalize_percs(args);
|
|
if (!(args->flags & CLD_FLG_DUTY) && (args->flags & CLD_FLG_RANDOM)
|
|
&& !(args->flags & CLD_FLG_NTRLVD)) {
|
|
sprintf(TmpStr, "(-D %d:%d) ", args->rperc, args->wperc);
|
|
strncat(args->argstr, TmpStr,
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
args->flags |= CLD_FLG_DUTY;
|
|
}
|
|
if ((args->delayTimeMin == 0) && (args->delayTimeMax == 0)
|
|
&& (args->ioTimeout == DEFAULT_IO_TIMEOUT)) {
|
|
strncat(args->argstr, "(-t 0:2m) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
}
|
|
if (!(args->flags & CLD_FLG_OFFSET)) {
|
|
strncat(args->argstr, "(-o 0) ",
|
|
(MAX_ARG_LEN - 1) - strlen(args->argstr));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* checks validity of data after parsing
|
|
* args and make assumtions. returns 0 on
|
|
* success and -1 on failure.
|
|
*/
|
|
int check_conclusions(child_args_t * args)
|
|
{
|
|
extern unsigned long glb_flags;
|
|
struct stat stat_buf;
|
|
int rv;
|
|
|
|
if ((args->flags & CLD_FLG_DUTY)
|
|
&& ((args->flags & CLD_FLG_LINEAR)
|
|
|| (args->flags & CLD_FLG_NTRLVD))) {
|
|
pMsg(WARN, args,
|
|
"Duty cycle testing is supported for random (-pR) tests only.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_BLK_RNG) && (args->flags & CLD_FLG_RTRSIZ)) {
|
|
pMsg(WARN, args,
|
|
"Can't have unfixed block sizes and specify seek range in terms of blocks.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->vsiz < 0) || (args->ltrsiz < 1) || (args->htrsiz < 1)) {
|
|
pMsg(WARN, args,
|
|
"Bounds exceeded for transfer size and/or volume size.\n");
|
|
pMsg(WARN, args, MAXTRSIZ, (args->htrsiz * BLK_SIZE),
|
|
args->vsiz);
|
|
return (-1);
|
|
}
|
|
if (args->htrsiz < args->ltrsiz) {
|
|
pMsg(ERR, args,
|
|
"Min transfer size, %lu, greater then Max transfer size, %lu.\n",
|
|
args->ltrsiz, args->htrsiz);
|
|
return (-1);
|
|
}
|
|
if (args->vsiz < (args->stop_lba - args->start_lba + 1)) {
|
|
pMsg(ERR, args, "Volume stop block/lba exceeds volume size.\n");
|
|
return (-1);
|
|
}
|
|
if (args->vsiz < args->htrsiz) {
|
|
pMsg(WARN, args, VSIZETS, args->vsiz, args->htrsiz);
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_TMD) == 0 && (args->seeks <= 0)) {
|
|
pMsg(WARN, args, TSEEK, args->seeks);
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_SKS) && (args->t_kids > args->seeks)) {
|
|
pMsg(WARN, args,
|
|
"Can't have more children then max number of seeks, use -K/-L to adjust.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->start_blk > args->vsiz)
|
|
&& !(args->flags & (CLD_FLG_BLK_RNG | CLD_FLG_LBA_RNG))) {
|
|
pMsg(WARN, args, STBGTTLBA, args->start_blk,
|
|
(args->vsiz / args->htrsiz));
|
|
return (-1);
|
|
}
|
|
if ((args->stop_blk > args->vsiz)
|
|
&& !(args->flags & (CLD_FLG_BLK_RNG | CLD_FLG_LBA_RNG))) {
|
|
pMsg(WARN, args, SBGTTLBA, args->stop_blk,
|
|
(args->vsiz / args->htrsiz));
|
|
return (-1);
|
|
}
|
|
if ((args->start_lba > args->vsiz)
|
|
&& !(args->flags & (CLD_FLG_BLK_RNG | CLD_FLG_LBA_RNG))) {
|
|
pMsg(WARN, args, STLBAGTLBA, args->start_lba, args->vsiz);
|
|
return (-1);
|
|
}
|
|
if ((args->stop_lba > args->vsiz)
|
|
&& !(args->flags & (CLD_FLG_BLK_RNG | CLD_FLG_LBA_RNG))) {
|
|
pMsg(WARN, args, SLBAGTLBA, args->stop_lba, args->vsiz);
|
|
return (-1);
|
|
}
|
|
if (args->start_blk > args->stop_blk) {
|
|
pMsg(WARN, args, SBRSB, args->stop_blk, args->start_blk);
|
|
return (-1);
|
|
}
|
|
if (args->start_lba > args->stop_lba) {
|
|
pMsg(ERR, args, SLBARSLBA, args->stop_lba, args->start_lba);
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_LBA_RNG) && (args->flags & CLD_FLG_BLK_RNG)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify range in both block and LBA, use -s or -S.\n");
|
|
return (-1);
|
|
}
|
|
|
|
/* use stat to get file properties, and test then agains specified -I */
|
|
rv = stat(args->device, &stat_buf);
|
|
if (0 == rv) { /* no error on call to stat, compare against -I option */
|
|
/* files are usually file type */
|
|
if ((args->flags & CLD_FLG_FILE) && !IS_FILE(stat_buf.st_mode)) {
|
|
pMsg(ERR, args,
|
|
"Can't open non-file filespec with file device type, -If.\n");
|
|
return (-1);
|
|
}
|
|
/* block devices, are usually block type */
|
|
if ((args->flags & CLD_FLG_BLK) && !IS_BLK(stat_buf.st_mode)) {
|
|
pMsg(ERR, args,
|
|
"Can't open non-block filespec with block device type, -Ib.\n");
|
|
return (-1);
|
|
}
|
|
#ifndef WINDOWS
|
|
/* raw devices, are usually character type */
|
|
if ((args->flags & CLD_FLG_RAW) && !S_ISCHR(stat_buf.st_mode)) {
|
|
pMsg(ERR, args,
|
|
"Can't open non-raw filespec with raw device type, -Ir.\n");
|
|
return (-1);
|
|
}
|
|
#else
|
|
if (args->flags & CLD_FLG_RAW) {
|
|
pMsg(ERR, args,
|
|
"RAW IO type not supported in Windows, use direct IO instead.\n");
|
|
return (-1);
|
|
}
|
|
#endif
|
|
#ifdef _DEBUG
|
|
} else {
|
|
PDBG1(DBUG, args,
|
|
"Can't get status on %s, assuming a new file, errno = %d\n",
|
|
args->device, GETLASTERROR());
|
|
#endif
|
|
}
|
|
|
|
if ((args->hbeat > 0) && (args->flags & CLD_FLG_TMD)
|
|
&& (args->hbeat > args->run_time)) {
|
|
pMsg(ERR, args,
|
|
"Heartbeat should be at least equal to runtime, use -h/-T to adjust.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->hbeat > 0) && !(args->flags & CLD_FLG_PRFTYPS)) {
|
|
pMsg(ERR, args,
|
|
"At least one performance option, -P, must be specified when using -h.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_W) && !(args->flags & CLD_FLG_R)
|
|
&& (args->flags & CLD_FLG_CMPR)) {
|
|
pMsg(ERR, args, "Write only, ignoring option -E.\n");
|
|
}
|
|
if ((args->flags & CLD_FLG_TMD) && (args->flags & CLD_FLG_SKS)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify both -L and -T they are mutually exclusive.\n");
|
|
return (-1);
|
|
}
|
|
if (((args->flags & CLD_FLG_R) && !(args->flags & CLD_FLG_W))
|
|
&& (args->flags & CLD_FLG_ERR_MARK)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify mark on error, -Am, in read only mode.\n");
|
|
return (-1);
|
|
}
|
|
if (!(args->flags & CLD_FLG_ALLDIE) && (args->flags & CLD_FLG_ERR_MARK)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify mark on error, -Am, when continue on error is set.\n");
|
|
return (-1);
|
|
}
|
|
if ((glb_flags & GLB_FLG_KILL) && !(args->flags & CLD_FLG_ALLDIE)) {
|
|
pMsg(ERR, args,
|
|
"Can't specify global kill, -Ag, when continue on error is set, -Ac.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_LINEAR) && !(args->flags & CLD_FLG_NTRLVD)
|
|
&& (args->flags & CLD_FLG_TMD)) {
|
|
pMsg(ERR, args, "Linear read / write test can not be timed.\n");
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_CMPR)
|
|
&& (args->cmp_lng > (args->ltrsiz * BLK_SIZE))) {
|
|
pMsg(ERR, args,
|
|
"Compare length, %lu, is greater then transfer size, %lu\n",
|
|
args->cmp_lng, args->ltrsiz * BLK_SIZE);
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_OFFSET) && (args->offset > args->stop_lba)) {
|
|
pMsg(ERR, args, LBAOFFGSLBA, args->offset, args->stop_lba);
|
|
return (-1);
|
|
}
|
|
if ((args->flags & CLD_FLG_OFFSET)
|
|
&& ((args->offset + args->ltrsiz - 1) > args->stop_lba)) {
|
|
pMsg(ERR, args, LBAOTSGSLBA, args->offset, args->ltrsiz,
|
|
args->stop_lba);
|
|
return (-1);
|
|
}
|
|
return 0;
|
|
}
|