blob: 765cfdae5ad9be6f576967cc8b60e823a1b20080 [file] [log] [blame]
plars865695b2001-08-27 22:15:12 +00001/*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
subrata_modak4bb656a2009-02-26 12:02:09 +00003 *
plars865695b2001-08-27 22:15:12 +00004 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
subrata_modak4bb656a2009-02-26 12:02:09 +00007 *
plars865695b2001-08-27 22:15:12 +00008 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
subrata_modak4bb656a2009-02-26 12:02:09 +000011 *
plars865695b2001-08-27 22:15:12 +000012 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
subrata_modak4bb656a2009-02-26 12:02:09 +000018 *
plars865695b2001-08-27 22:15:12 +000019 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
subrata_modak4bb656a2009-02-26 12:02:09 +000022 *
plars865695b2001-08-27 22:15:12 +000023 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
subrata_modak4bb656a2009-02-26 12:02:09 +000025 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
plars865695b2001-08-27 22:15:12 +000030 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 */
32/*
33 * iogen - a tool for generating file/sds io for a doio process
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <unistd.h>
39#include <signal.h>
40#include <fcntl.h>
41#include <errno.h>
42#include <string.h>
43#include <signal.h>
44#include <time.h>
45#include <sys/param.h>
46#include <sys/types.h>
subrata_modak90d1e3c2008-08-21 13:07:02 +000047#include <sys/time.h>
plars865695b2001-08-27 22:15:12 +000048#include <sys/stat.h>
49#include <sys/sysmacros.h>
50#ifdef CRAY
51#include <sys/file.h>
52#include <sys/iosw.h>
53#include <sys/listio.h>
54#endif
55#ifdef sgi
56#include <sys/statvfs.h>
57#include <sys/fs/xfs_itable.h>
58#endif
59
60#ifdef CRAY
61#include "libkern.h"
62#endif
63#include "doio.h"
Marios Makris1475f672012-05-10 16:04:48 +030064#include "bytes_by_prefix.h"
plars865695b2001-08-27 22:15:12 +000065#include "string_to_tokens.h"
66#include "open_flags.h"
67#include "random_range.h"
68
69#ifndef PATH_MAX
Wanlong Gao354ebb42012-12-07 10:10:04 +080070#define PATH_MAX 512 /* ??? */
plars865695b2001-08-27 22:15:12 +000071#endif
72
73#ifndef BSIZE
74#ifdef linux
75#define BSIZE DEV_BSIZE
76#else
77#define BSIZE 512
78#endif
79#endif
80
81#define RAW_IO(_flags_) ((_flags_) & (O_RAW | O_SSD))
82
mridgef7298c72005-12-05 19:14:37 +000083#ifndef __linux__
Wanlong Gao354ebb42012-12-07 10:10:04 +080084extern char *sys_errlist[];
plars865695b2001-08-27 22:15:12 +000085#endif
nstraz5e9c69e2002-09-04 14:59:49 +000086#define SYSERR strerror(errno)
plars865695b2001-08-27 22:15:12 +000087
88/*
89 * Structure for retaining test file information
90 */
91
92struct file_info {
Wanlong Gao354ebb42012-12-07 10:10:04 +080093 char f_path[MAX_FNAME_LENGTH + 1]; /* file name (full path) */
94 int f_length; /* length in bytes */
95 int f_iou; /* file iounit */
96 int f_riou; /* file raw iounit (for O_RAW/O_SSD) */
97 int f_dalign; /* direct I/O alignment */
98 int f_nextoff; /* offset of end of last io operation */
99 int f_type; /* file type S_IFREG, etc... */
100 int f_lastoffset; /* offset of last io operation */
101 int f_lastlength; /* length of last io operation */
plars865695b2001-08-27 22:15:12 +0000102};
103
104/*
105 * Simple structure for associating strings with values - useful for converting
106 * cmdline args to internal values, as well as printing internal values in
107 * a human readable form.
108 */
109
110struct strmap {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800111 char *m_string;
112 int m_value;
113 int m_flags;
plars865695b2001-08-27 22:15:12 +0000114};
115
Wanlong Gao354ebb42012-12-07 10:10:04 +0800116void startup_info(FILE * stream, int seed);
117int init_output(void);
118int form_iorequest(struct io_req *req);
119int get_file_info(struct file_info *rec);
120int create_file(char *path, int nbytes);
121int str_to_value(struct strmap *map, char *str);
122struct strmap *str_lookup(struct strmap *map, char *str);
123char *value_to_string(struct strmap *map, int val);
124int parse_cmdline(int argc, char **argv, char *opts);
125int help(FILE * stream);
126int usage(FILE * stream);
Alex Elder6b572162011-04-01 17:01:27 -0500127
plars865695b2001-08-27 22:15:12 +0000128/*
129 * Declare cmdline option flags/variables initialized in parse_cmdline()
130 */
131
132#define OPTS "a:dhf:i:L:m:op:qr:s:t:T:O:N:"
133
Wanlong Gao354ebb42012-12-07 10:10:04 +0800134int a_opt = 0; /* async io comp. types supplied */
135int o_opt = 0; /* form overlapping requests */
136int f_opt = 0; /* test flags */
137int i_opt = 0; /* iterations - 0 implies infinite */
138int L_opt = 0; /* listio min-max nstrides & nents */
139int m_opt = 0; /* offset mode */
140int O_opt = 0; /* file creation Open flags */
141int p_opt = 0; /* output pipe - default is stdout */
142int r_opt = 0; /* specify raw io multiple instead of */
plars865695b2001-08-27 22:15:12 +0000143 /* getting it from the mounted on device. */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800144 /* Only applies to regular files. */
145int s_opt = 0; /* syscalls */
146int t_opt = 0; /* min transfer size (bytes) */
147int T_opt = 0; /* max transfer size (bytes) */
148int q_opt = 0; /* quiet operation on startup */
149char TagName[40]; /* name of this iogen (see Monster) */
150struct strmap *Offset_Mode; /* M_SEQUENTIAL, M_RANDOM, etc. */
151int Iterations; /* # requests to generate (0 --> infinite) */
152int Time_Mode = 0; /* non-zero if Iterations is in seconds */
plars865695b2001-08-27 22:15:12 +0000153 /* (ie. -i arg was suffixed with 's') */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800154char *Outpipe; /* Pipe to write output to if p_opt */
155int Mintrans; /* min io transfer size */
156int Maxtrans; /* max io transfer size */
157int Rawmult; /* raw/ssd io multiple (from -r) */
158int Minstrides; /* min # of listio strides per request */
159int Maxstrides; /* max # of listio strides per request */
160int Oflags; /* open(2) flags for creating files */
161int Ocbits; /* open(2) cbits for creating files */
162int Ocblks; /* open(2) cblks for creating files */
163int Orealtime = 0; /* flag set for -O REALTIME */
164int Oextsize = 0; /* real-time extent size */
165int Oreserve = 1; /* flag for -O [no]reserve */
166int Oallocate = 0; /* flag for -O allocate */
167int Owrite = 1; /* flag for -O nowrite */
plars865695b2001-08-27 22:15:12 +0000168
Wanlong Gao354ebb42012-12-07 10:10:04 +0800169int Nfiles = 0; /* # files on cmdline */
170struct file_info *File_List; /* info about each file */
171int Nflags = 0; /* # flags on cmdline */
172struct strmap *Flag_List[128]; /* flags selected from cmdline */
173int Nsyscalls = 0; /* # syscalls on cmdline */
174struct strmap *Syscall_List[128]; /* syscalls selected on cmdline */
175int Fileio = 0; /* flag indicating that a file */
176 /* io syscall has been chosen. */
177int Naio_Strat_Types = 0; /* # async io completion types */
178struct strmap *Aio_Strat_List[128]; /* Async io completion types */
plars865695b2001-08-27 22:15:12 +0000179
plars865695b2001-08-27 22:15:12 +0000180/*
181 * Map async io completion modes (-a args) names to values. Macros are
182 * defined in doio.h.
183 */
184
Wanlong Gao354ebb42012-12-07 10:10:04 +0800185struct strmap Aio_Strat_Map[] = {
plars865695b2001-08-27 22:15:12 +0000186#ifndef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +0800187 {"poll", A_POLL},
188 {"signal", A_SIGNAL},
plars865695b2001-08-27 22:15:12 +0000189#else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800190 {"none", 0},
plars865695b2001-08-27 22:15:12 +0000191#endif /* !linux */
192#ifdef CRAY
193#if _UMK || RELEASE_LEVEL >= 8000
Wanlong Gao354ebb42012-12-07 10:10:04 +0800194 {"recall", A_RECALL},
plars865695b2001-08-27 22:15:12 +0000195#endif
196
197#ifdef RECALL_SIZEOF
Wanlong Gao354ebb42012-12-07 10:10:04 +0800198 {"recalla", A_RECALLA},
plars865695b2001-08-27 22:15:12 +0000199#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800200 {"recalls", A_RECALLS},
plars865695b2001-08-27 22:15:12 +0000201#endif /* CRAY */
202
203#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +0800204 {"suspend", A_SUSPEND},
205 {"callback", A_CALLBACK},
plars865695b2001-08-27 22:15:12 +0000206#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800207 {NULL, -1}
plars865695b2001-08-27 22:15:12 +0000208};
209
210/*
211 * Offset_Mode #defines
212 */
213
214#define M_RANDOM 1
215#define M_SEQUENTIAL 2
216#define M_REVERSE 3
217
218/*
219 * Map offset mode (-m args) names to values
220 */
221
Wanlong Gao354ebb42012-12-07 10:10:04 +0800222struct strmap Omode_Map[] = {
223 {"random", M_RANDOM},
224 {"sequential", M_SEQUENTIAL},
225 {"reverse", M_REVERSE},
226 {NULL, -1}
plars865695b2001-08-27 22:15:12 +0000227};
228
229/*
230 * Map syscall names (-s args) to values - macros are defined in doio.h.
231 */
232#define SY_ASYNC 00001
233#define SY_WRITE 00002
234#define SY_SDS 00010
235#define SY_LISTIO 00020
236#define SY_NENT 00100 /* multi entry vs multi stride >>> */
237
Wanlong Gao354ebb42012-12-07 10:10:04 +0800238struct strmap Syscall_Map[] = {
239 {"read", READ, 0},
240 {"write", WRITE, SY_WRITE},
plars865695b2001-08-27 22:15:12 +0000241#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800242 {"reada", READA, SY_ASYNC},
243 {"writea", WRITEA, SY_WRITE | SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000244#ifndef _CRAYMPP
Wanlong Gao354ebb42012-12-07 10:10:04 +0800245 {"ssread", SSREAD, SY_SDS},
246 {"sswrite", SSWRITE, SY_WRITE | SY_SDS},
plars865695b2001-08-27 22:15:12 +0000247#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800248 {"listio", LISTIO, SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000249
250 /* listio as 4 system calls */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800251 {"lread", LREAD, 0},
252 {"lreada", LREADA, SY_ASYNC},
253 {"lwrite", LWRITE, SY_WRITE},
254 {"lwritea", LWRITEA, SY_WRITE | SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000255
256 /* listio with nstrides > 1 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800257 {"lsread", LSREAD, 0},
258 {"lsreada", LSREADA, SY_ASYNC},
259 {"lswrite", LSWRITE, SY_WRITE},
260 {"lswritea", LSWRITEA, SY_WRITE | SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000261
262 /* listio with nents > 1 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800263 {"leread", LEREAD, 0 | SY_NENT},
264 {"lereada", LEREADA, SY_ASYNC | SY_NENT},
265 {"lewrite", LEWRITE, SY_WRITE | SY_NENT},
266 {"lewritea", LEWRITEA, SY_WRITE | SY_ASYNC | SY_NENT},
plars865695b2001-08-27 22:15:12 +0000267
268 /* listio with nents > 1 & nstrides > 1 */
269
270 /* all listio system calls under one name */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800271 {"listio+", LREAD, 0},
272 {"listio+", LREADA, SY_ASYNC},
273 {"listio+", LWRITE, SY_WRITE},
274 {"listio+", LWRITEA, SY_WRITE | SY_ASYNC},
275 {"listio+", LSREAD, 0},
276 {"listio+", LSREADA, SY_ASYNC},
277 {"listio+", LSWRITE, SY_WRITE},
278 {"listio+", LSWRITEA, SY_WRITE | SY_ASYNC},
279 {"listio+", LEREAD, 0 | SY_NENT},
280 {"listio+", LEREADA, SY_ASYNC | SY_NENT},
281 {"listio+", LEWRITE, SY_WRITE | SY_NENT},
282 {"listio+", LEWRITEA, SY_WRITE | SY_ASYNC | SY_NENT},
plars865695b2001-08-27 22:15:12 +0000283#endif
284
285#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +0800286 {"pread", PREAD},
287 {"pwrite", PWRITE, SY_WRITE},
288 {"aread", AREAD, SY_ASYNC},
289 {"awrite", AWRITE, SY_WRITE | SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000290#if 0
291 /* not written yet */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800292 {"llread", LLREAD, 0},
293 {"llaread", LLAREAD, SY_ASYNC},
294 {"llwrite", LLWRITE, 0},
295 {"llawrite", LLAWRITE, SY_ASYNC},
plars865695b2001-08-27 22:15:12 +0000296#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800297 {"resvsp", RESVSP, SY_WRITE},
298 {"unresvsp", UNRESVSP, SY_WRITE},
299 {"reserve", RESVSP, SY_WRITE},
300 {"unreserve", UNRESVSP, SY_WRITE},
301 {"ffsync", DFFSYNC, SY_WRITE},
plars865695b2001-08-27 22:15:12 +0000302#endif /* SGI */
303
304#ifndef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800305 {"readv", READV},
306 {"writev", WRITEV, SY_WRITE},
307 {"mmread", MMAPR},
308 {"mmwrite", MMAPW, SY_WRITE},
309 {"fsync2", FSYNC2, SY_WRITE},
310 {"fdatasync", FDATASYNC, SY_WRITE},
plars865695b2001-08-27 22:15:12 +0000311#endif
312
Wanlong Gao354ebb42012-12-07 10:10:04 +0800313 {NULL, -1}
plars865695b2001-08-27 22:15:12 +0000314};
315
316/*
317 * Map open flags (-f args) to values
318 */
319#define FLG_RAW 00001
320
Wanlong Gao354ebb42012-12-07 10:10:04 +0800321struct strmap Flag_Map[] = {
322 {"buffered", 0, 0},
323 {"sync", O_SYNC, 0},
plars865695b2001-08-27 22:15:12 +0000324#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800325 {"raw", O_RAW, FLG_RAW},
326 {"raw+wf", O_RAW | O_WELLFORMED, FLG_RAW},
327 {"raw+wf+ldraw", O_RAW | O_WELLFORMED | O_LDRAW, FLG_RAW},
328 {"raw+wf+ldraw+sync", O_RAW | O_WELLFORMED | O_LDRAW | O_SYNC, FLG_RAW},
plars865695b2001-08-27 22:15:12 +0000329#ifdef O_SSD
Wanlong Gao354ebb42012-12-07 10:10:04 +0800330 {"ssd", O_SSD, FLG_RAW},
plars865695b2001-08-27 22:15:12 +0000331#endif
332#ifdef O_LDRAW
Wanlong Gao354ebb42012-12-07 10:10:04 +0800333 {"ldraw", O_LDRAW, 0},
plars865695b2001-08-27 22:15:12 +0000334#endif
335#ifdef O_PARALLEL
Wanlong Gao354ebb42012-12-07 10:10:04 +0800336 {"parallel", O_PARALLEL | O_RAW | O_WELLFORMED,
337 FLG_RAW},
338 {"parallel+sync", O_PARALLEL | O_RAW | O_WELLFORMED | O_SYNC,
339 FLG_RAW},
340 {"parallel+ldraw", O_PARALLEL | O_RAW | O_WELLFORMED | O_LDRAW,
341 FLG_RAW},
342 {"parallel+ldraw+sync",
343 O_PARALLEL | O_RAW | O_WELLFORMED | O_LDRAW | O_SYNC,
344 FLG_RAW},
plars865695b2001-08-27 22:15:12 +0000345#endif
346#endif /* CRAY */
347
348#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +0800349 {"direct", O_DIRECT, FLG_RAW},
350 {"dsync", O_DSYNC}, /* affects writes */
351 {"rsync", O_RSYNC}, /* affects reads */
352 {"rsync+dsync", O_RSYNC | O_DSYNC},
plars865695b2001-08-27 22:15:12 +0000353#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +0800354 {NULL, -1}
plars865695b2001-08-27 22:15:12 +0000355};
356
357/*
358 * Map file types to strings
359 */
360
Wanlong Gao354ebb42012-12-07 10:10:04 +0800361struct strmap Ftype_Map[] = {
362 {"regular", S_IFREG},
363 {"blk-spec", S_IFBLK},
364 {"chr-spec", S_IFCHR},
365 {NULL, 0}
plars865695b2001-08-27 22:15:12 +0000366};
367
368/*
369 * Misc declarations
370 */
371
Wanlong Gao354ebb42012-12-07 10:10:04 +0800372int Sds_Avail;
plars865695b2001-08-27 22:15:12 +0000373
Wanlong Gao354ebb42012-12-07 10:10:04 +0800374char Byte_Patterns[26] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
375 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
376 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
377 'Y', 'Z'
378};
plars865695b2001-08-27 22:15:12 +0000379
Wanlong Gao354ebb42012-12-07 10:10:04 +0800380int main(int argc, char **argv)
plars865695b2001-08-27 22:15:12 +0000381{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800382 int rseed, outfd, infinite;
383 time_t start_time;
384 struct io_req req;
Garrett Cooper2c282152010-12-16 00:55:50 -0800385
Wanlong Gao354ebb42012-12-07 10:10:04 +0800386 umask(0);
plars865695b2001-08-27 22:15:12 +0000387
388#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800389 Sds_Avail = sysconf(_SC_CRAY_SDS);
plars865695b2001-08-27 22:15:12 +0000390#else
Wanlong Gao354ebb42012-12-07 10:10:04 +0800391 Sds_Avail = 0;
plars865695b2001-08-27 22:15:12 +0000392#endif
393
Wanlong Gao354ebb42012-12-07 10:10:04 +0800394 TagName[0] = '\0';
395 parse_cmdline(argc, argv, OPTS);
plars865695b2001-08-27 22:15:12 +0000396
Wanlong Gao354ebb42012-12-07 10:10:04 +0800397 /*
398 * Initialize output descriptor.
399 */
400 if (!p_opt) {
401 outfd = 1;
402 } else {
403 outfd = init_output();
404 }
plars865695b2001-08-27 22:15:12 +0000405
Wanlong Gao354ebb42012-12-07 10:10:04 +0800406 rseed = getpid();
407 random_range_seed(rseed); /* initialize random number generator */
plars865695b2001-08-27 22:15:12 +0000408
Wanlong Gao354ebb42012-12-07 10:10:04 +0800409 /*
410 * Print out startup information, unless we're running in quiet mode
411 */
412 if (!q_opt)
413 startup_info(stderr, rseed);
subrata_modak90d1e3c2008-08-21 13:07:02 +0000414 {
Wanlong Gao354ebb42012-12-07 10:10:04 +0800415 struct timeval ts;
416 gettimeofday(&ts, NULL);
subrata_modak90d1e3c2008-08-21 13:07:02 +0000417 start_time = ts.tv_sec;
418 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800419 /*
420 * While iterations (or forever if Iterations == 0) - compute an
421 * io request, and write the structure to the output descriptor
422 */
plars865695b2001-08-27 22:15:12 +0000423
Wanlong Gao354ebb42012-12-07 10:10:04 +0800424 infinite = !Iterations;
subrata_modak90d1e3c2008-08-21 13:07:02 +0000425 struct timeval ts;
Wanlong Gao354ebb42012-12-07 10:10:04 +0800426 gettimeofday(&ts, NULL);
427 while (infinite ||
428 (!Time_Mode && Iterations--) ||
429 (Time_Mode && (ts.tv_sec - start_time <= Iterations))) {
430 gettimeofday(&ts, NULL);
431 memset(&req, 0, sizeof(struct io_req));
432 if (form_iorequest(&req) == -1) {
433 fprintf(stderr, "iogen%s: form_iorequest() failed\n",
434 TagName);
435 continue;
436 }
437
438 req.r_magic = DOIO_MAGIC;
439 if (write(outfd, (char *)&req, sizeof(req)) == -1)
440 perror("Warning: Could not write");
plars865695b2001-08-27 22:15:12 +0000441 }
442
Wanlong Gao354ebb42012-12-07 10:10:04 +0800443 exit(0);
plars865695b2001-08-27 22:15:12 +0000444
Wanlong Gao354ebb42012-12-07 10:10:04 +0800445} /* main */
plars865695b2001-08-27 22:15:12 +0000446
Wanlong Gao354ebb42012-12-07 10:10:04 +0800447void startup_info(FILE * stream, int seed)
plars865695b2001-08-27 22:15:12 +0000448{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800449 char *value_to_string(), *type;
450 int i;
plars865695b2001-08-27 22:15:12 +0000451
452 fprintf(stream, "\n");
Wanlong Gao354ebb42012-12-07 10:10:04 +0800453 fprintf(stream, "iogen%s starting up with the following:\n", TagName);
plars865695b2001-08-27 22:15:12 +0000454 fprintf(stream, "\n");
plars865695b2001-08-27 22:15:12 +0000455
Wanlong Gao354ebb42012-12-07 10:10:04 +0800456 fprintf(stream, "Out-pipe: %s\n",
457 p_opt ? Outpipe : "stdout");
458
459 if (Iterations) {
460 fprintf(stream, "Iterations: %d", Iterations);
461 if (Time_Mode)
462 fprintf(stream, " seconds");
463
464 fprintf(stream, "\n");
465 } else {
466 fprintf(stream, "Iterations: Infinite\n");
plars865695b2001-08-27 22:15:12 +0000467 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800468
469 fprintf(stream, "Seed: %d\n", seed);
470
471 fprintf(stream, "Offset-Mode: %s\n", Offset_Mode->m_string);
472
473 fprintf(stream, "Overlap Flag: %s\n", o_opt ? "on" : "off");
474
475 fprintf(stream,
476 "Mintrans: %-11d (%d blocks)\n",
477 Mintrans, (Mintrans + BSIZE - 1) / BSIZE);
478
479 fprintf(stream,
480 "Maxtrans: %-11d (%d blocks)\n",
481 Maxtrans, (Maxtrans + BSIZE - 1) / BSIZE);
482
483 if (!r_opt)
484 fprintf(stream,
485 "O_RAW/O_SSD Multiple: (Determined by device)\n");
486 else
487 fprintf(stream,
488 "O_RAW/O_SSD Multiple: %-11d (%d blocks)\n",
489 Rawmult, (Rawmult + BSIZE - 1) / BSIZE);
490
491 fprintf(stream, "Syscalls: ");
492 for (i = 0; i < Nsyscalls; i++)
493 fprintf(stream, "%s ", Syscall_List[i]->m_string);
494 fprintf(stream, "\n");
495
496 fprintf(stream, "Aio completion types: ");
497 for (i = 0; i < Naio_Strat_Types; i++)
498 fprintf(stream, "%s ", Aio_Strat_List[i]->m_string);
499 fprintf(stream, "\n");
500
501 if (Fileio) {
502 fprintf(stream, "Flags: ");
503 for (i = 0; i < Nflags; i++)
504 fprintf(stream, "%s ", Flag_List[i]->m_string);
505
506 fprintf(stream, "\n");
507 fprintf(stream, "\n");
508 fprintf(stream, "Test Files: \n");
509 fprintf(stream, "\n");
510 fprintf(stream,
511 "Path Length iou raw iou file\n");
512 fprintf(stream,
513 " (bytes) (bytes) (bytes) type\n");
514 fprintf(stream,
515 "-----------------------------------------------------------------------------\n");
516
517 for (i = 0; i < Nfiles; i++) {
518 type = value_to_string(Ftype_Map, File_List[i].f_type);
519 fprintf(stream, "%-40s %12d %7d %7d %s\n",
520 File_List[i].f_path, File_List[i].f_length,
521 File_List[i].f_iou, File_List[i].f_riou, type);
522 }
523 }
plars865695b2001-08-27 22:15:12 +0000524}
525
526/*
527 * Initialize output descriptor. If going to stdout, its easy,
528 * otherwise, attempt to create a FIFO on path Outpipe. Exit with an
529 * error code if this cannot be done.
530 */
Wanlong Gao354ebb42012-12-07 10:10:04 +0800531int init_output(void)
plars865695b2001-08-27 22:15:12 +0000532{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800533 int outfd;
534 struct stat sbuf;
plars865695b2001-08-27 22:15:12 +0000535
Wanlong Gao354ebb42012-12-07 10:10:04 +0800536 if (stat(Outpipe, &sbuf) == -1) {
537 if (errno == ENOENT) {
538 if (mkfifo(Outpipe, 0666) == -1) {
539 fprintf(stderr,
540 "iogen%s: Could not mkfifo %s: %s\n",
541 TagName, Outpipe, SYSERR);
542 exit(2);
543 }
544 } else {
545 fprintf(stderr,
546 "iogen%s: Could not stat outpipe %s: %s\n",
547 TagName, Outpipe, SYSERR);
548 exit(2);
549 }
550 } else {
551 if (!S_ISFIFO(sbuf.st_mode)) {
552 fprintf(stderr,
553 "iogen%s: Output file %s exists, but is not a FIFO\n",
554 TagName, Outpipe);
555 exit(2);
556 }
557 }
558
559 if ((outfd = open(Outpipe, O_RDWR)) == -1) {
560 fprintf(stderr,
561 "iogen%s: Couldn't open outpipe %s with flags O_RDWR: %s\n",
plars865695b2001-08-27 22:15:12 +0000562 TagName, Outpipe, SYSERR);
563 exit(2);
plars865695b2001-08-27 22:15:12 +0000564 }
plars865695b2001-08-27 22:15:12 +0000565
Wanlong Gao354ebb42012-12-07 10:10:04 +0800566 return (outfd);
plars865695b2001-08-27 22:15:12 +0000567}
568
plars865695b2001-08-27 22:15:12 +0000569/*
570 * Main io generation function. form_iorequest() selects a system call to
571 * do based on cmdline arguments, and proceeds to select parameters for that
572 * system call.
573 *
574 * Returns 0 if req is filled in with a complete doio request, otherwise
575 * returns -1.
576 */
577
Wanlong Gao354ebb42012-12-07 10:10:04 +0800578int form_iorequest(struct io_req *req)
plars865695b2001-08-27 22:15:12 +0000579{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800580 int mult, offset = 0, length = 0, slength;
581 int minlength, maxlength, laststart, lastend;
582 int minoffset, maxoffset;
583 int maxstride, nstrides;
584 char pattern, *errp;
585 struct strmap *flags, *sc, *aio_strat;
586 struct file_info *fptr;
plars865695b2001-08-27 22:15:12 +0000587#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800588 int opcode, cmd;
plars865695b2001-08-27 22:15:12 +0000589#endif
590
Wanlong Gao354ebb42012-12-07 10:10:04 +0800591 /*
592 * Choose system call, flags, and file
593 */
plars865695b2001-08-27 22:15:12 +0000594
Wanlong Gao354ebb42012-12-07 10:10:04 +0800595 sc = Syscall_List[random_range(0, Nsyscalls - 1, 1, NULL)];
596 req->r_type = sc->m_value;
plars865695b2001-08-27 22:15:12 +0000597
598#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800599 if (sc->m_value == LISTIO) {
600 opcode = random_range(0, 1, 1, NULL) ? LO_READ : LO_WRITE;
601 cmd = random_range(0, 1, 1, NULL) ? LC_START : LC_WAIT;
602 }
plars865695b2001-08-27 22:15:12 +0000603#endif
604
Wanlong Gao354ebb42012-12-07 10:10:04 +0800605 if (sc->m_flags & SY_WRITE)
606 pattern =
607 Byte_Patterns[random_range
608 (0, sizeof(Byte_Patterns) - 1, 1, NULL)];
609 else
610 pattern = 0;
plars865695b2001-08-27 22:15:12 +0000611
612#if CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800613 /*
614 * If sds io, simply choose a length (possibly pattern) and return
plars865695b2001-08-27 22:15:12 +0000615 */
plars865695b2001-08-27 22:15:12 +0000616
Wanlong Gao354ebb42012-12-07 10:10:04 +0800617 if (sc->m_flags & SY_SDS) {
618 req->r_data.ssread.r_nbytes =
619 random_range(Mintrans, Maxtrans, BSIZE, NULL);
620 if (sc->m_flags & SY_WRITE)
621 req->r_data.sswrite.r_pattern = pattern;
plars865695b2001-08-27 22:15:12 +0000622
Wanlong Gao354ebb42012-12-07 10:10:04 +0800623 return 0;
plars865695b2001-08-27 22:15:12 +0000624 }
625#endif
plars865695b2001-08-27 22:15:12 +0000626
Wanlong Gao354ebb42012-12-07 10:10:04 +0800627 /*
628 * otherwise, we're doing file io. Choose starting offset, length,
629 * open flags, and possibly a pattern (for write/writea).
630 */
631
632 fptr = &File_List[random_range(0, Nfiles - 1, 1, NULL)];
633 flags = Flag_List[random_range(0, Nflags - 1, 1, NULL)];
634
635 /*
636 * Choose offset/length multiple. IO going to a device, or regular
637 * IO that is O_RAW or O_SSD must be aligned on the file r_iou. Otherwise
638 * it must be aligned on the regular iou (normally 1).
639 */
640
641 if (fptr->f_type == S_IFREG && (flags->m_flags & FLG_RAW))
642 mult = fptr->f_riou;
643 else
644 mult = fptr->f_iou;
645
646 /*
647 * Choose offset and length. Both must be a multiple of mult
648 */
649
650 /*
651 * Choose length first - it must be a multiple of mult
652 */
653
654 laststart = fptr->f_lastoffset;
655 lastend = fptr->f_lastoffset + fptr->f_lastlength - 1;
656
657 minlength = (Mintrans > mult) ? Mintrans : mult;
658
659 switch (Offset_Mode->m_value) {
660 case M_SEQUENTIAL:
661 if (o_opt && lastend > laststart)
662 offset = random_range(laststart, lastend, 1, NULL);
663 else
664 offset = lastend + 1;
665 if (offset && (offset % mult))
666 offset += mult - (offset % mult);
667
668 if (minlength > fptr->f_length - offset)
669 offset = 0;
670
671 maxlength = fptr->f_length - offset;
672 if (maxlength > Maxtrans)
673 maxlength = Maxtrans;
674
675 length = random_range(minlength, maxlength, mult, &errp);
676 if (errp != NULL) {
677 fprintf(stderr,
678 "iogen%s: random_range(%d, %d, %d) failed\n",
679 TagName, minlength, maxlength, mult);
680 return -1;
681 }
682
683 break;
684
685 case M_REVERSE:
686 maxlength = laststart;
687
688 if (maxlength > Maxtrans)
689 maxlength = Maxtrans;
690
691 if (minlength > maxlength) {
692 laststart = fptr->f_length;
693 lastend = fptr->f_length;
694 maxlength = Maxtrans;
695 }
696
697 length = random_range(minlength, maxlength, mult, &errp);
698 if (errp != NULL) {
699 fprintf(stderr,
700 "iogen%s: random_range(%d, %d, %d) failed\n",
701 TagName, minlength, maxlength, mult);
702 return -1;
703 }
704
705 offset = laststart - length;
706
707 if (o_opt && lastend > laststart)
708 offset += random_range(1, lastend - laststart, 1, NULL);
709
710 if (offset && (offset % mult))
711 offset -= offset % mult;
712
713 break;
714
715 case M_RANDOM:
716 length = random_range(Mintrans, Maxtrans, mult, NULL);
717
718 if (o_opt && lastend > laststart) {
719 minoffset = laststart - length + 1;
720 if (minoffset < 0) {
721 minoffset = 0;
722 }
723
724 if (lastend + length > fptr->f_length) {
725 maxoffset = fptr->f_length - length;
726 } else {
727 maxoffset = lastend;
728 }
729 } else {
730 minoffset = 0;
731 maxoffset = fptr->f_length - length;
732 }
733
734 if (minoffset < 0)
735 minoffset = 0;
736
737 offset = random_range(minoffset, maxoffset, mult, &errp);
738 if (errp != NULL) {
739 fprintf(stderr,
740 "iogen%s: random_range(%d, %d, %d) failed\n",
741 TagName, minoffset, maxoffset, mult);
742 return -1;
743 }
744 }
745
746 fptr->f_lastoffset = offset;
747 fptr->f_lastlength = length;
748
749 /*
750 * Choose an async io completion strategy if necessary
751 */
752 if (sc->m_flags & SY_ASYNC)
753 aio_strat = Aio_Strat_List[random_range(0, Naio_Strat_Types - 1,
754 1, NULL)];
755 else
756 aio_strat = NULL;
757
758 /*
759 * fill in specific syscall record data
760 */
761 switch (sc->m_value) {
762 case READ:
763 case READA:
764 strcpy(req->r_data.read.r_file, fptr->f_path);
765 req->r_data.read.r_oflags = O_RDONLY | flags->m_value;
766 req->r_data.read.r_offset = offset;
767 req->r_data.read.r_nbytes = length;
768 req->r_data.read.r_uflags =
769 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
770 req->r_data.read.r_aio_strat =
771 (aio_strat == NULL) ? 0 : aio_strat->m_value;
772 req->r_data.read.r_nstrides = 1;
773 req->r_data.read.r_nent = 1;
774 break;
775
776 case WRITE:
777 case WRITEA:
778 strcpy(req->r_data.write.r_file, fptr->f_path);
779 req->r_data.write.r_oflags = O_WRONLY | flags->m_value;
780 req->r_data.write.r_offset = offset;
781 req->r_data.write.r_nbytes = length;
782 req->r_data.write.r_pattern = pattern;
783 req->r_data.write.r_uflags =
784 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
785 req->r_data.write.r_aio_strat =
786 (aio_strat == NULL) ? 0 : aio_strat->m_value;
787 req->r_data.write.r_nstrides = 1;
788 req->r_data.write.r_nent = 1;
789 break;
790
791 case READV:
792 case AREAD:
793 case PREAD:
794 case WRITEV:
795 case AWRITE:
796 case PWRITE:
797
798 case LREAD:
799 case LREADA:
800 case LWRITE:
801 case LWRITEA:
802
803 case RESVSP:
804 case UNRESVSP:
805 case DFFSYNC:
806 case FSYNC2:
807 case FDATASYNC:
808
809 strcpy(req->r_data.io.r_file, fptr->f_path);
810 req->r_data.io.r_oflags =
811 ((sc->m_flags & SY_WRITE) ? O_WRONLY : O_RDONLY) | flags->
812 m_value;
813 req->r_data.io.r_offset = offset;
814 req->r_data.io.r_nbytes = length;
815 req->r_data.io.r_pattern = pattern;
816 req->r_data.io.r_uflags =
817 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
818 req->r_data.io.r_aio_strat =
819 (aio_strat == NULL) ? 0 : aio_strat->m_value;
820 req->r_data.io.r_nstrides = 1;
821 req->r_data.io.r_nent = 1;
822 break;
823
824 case MMAPR:
825 case MMAPW:
826 strcpy(req->r_data.io.r_file, fptr->f_path);
827 /* a subtle "feature" of mmap: a write-map requires
828 the file open read/write */
829 req->r_data.io.r_oflags =
830 ((sc->m_flags & SY_WRITE) ? O_RDWR : O_RDONLY) | flags->
831 m_value;
832 req->r_data.io.r_offset = offset;
833 req->r_data.io.r_nbytes = length;
834 req->r_data.io.r_pattern = pattern;
835 req->r_data.io.r_uflags =
836 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
837 req->r_data.io.r_aio_strat =
838 (aio_strat == NULL) ? 0 : aio_strat->m_value;
839 req->r_data.io.r_nstrides = 1;
840 req->r_data.io.r_nent = 1;
841 break;
842
843 case LSREAD:
844 case LSREADA:
845 case LEREAD:
846 case LEREADA:
847 case LSWRITE:
848 case LSWRITEA:
849 case LEWRITE:
850 case LEWRITEA:
851 /* multi-strided */
852 strcpy(req->r_data.io.r_file, fptr->f_path);
853 req->r_data.io.r_oflags =
854 ((sc->m_flags & SY_WRITE) ? O_WRONLY : O_RDONLY) | flags->
855 m_value;
856 req->r_data.io.r_offset = offset;
857 req->r_data.io.r_uflags =
858 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
859 req->r_data.io.r_aio_strat =
860 (aio_strat == NULL) ? 0 : aio_strat->m_value;
861 req->r_data.io.r_pattern = pattern;
862
863 /* multi-strided request...
864 * random number of strides (1...MaxStrides)
865 * length of stride must be > minlength
866 * length of stride must be % mult
867 *
868 * maxstrides = min(length / mult, overall.max#strides)
869 * nstrides = random #
870 * while (length / nstrides < minlength)
871 * nstrides = new random #
872 */
873 maxstride = length / mult;
874 if (maxstride > Maxstrides)
875 maxstride = Maxstrides;
876
877 if (!Minstrides)
878 Minstrides = 1;
879 nstrides = random_range(Minstrides, maxstride, 1, &errp);
880 if (errp != NULL) {
881 fprintf(stderr,
882 "iogen%s: random_range(%d, %d, %d) failed\n",
883 TagName, Minstrides, maxstride, 1);
884 return -1;
885 }
886
887 slength = length / nstrides;
888 if (slength % mult != 0) {
889 if (mult > slength) {
890 slength = mult;
891 } else {
892 slength -= slength % mult;
893 }
894 nstrides = length / slength;
895 if (nstrides > Maxstrides)
896 nstrides = Maxstrides;
897 }
898
899 req->r_data.io.r_nbytes = slength;
900 if (sc->m_flags & SY_NENT) {
901 req->r_data.io.r_nstrides = 1;
902 req->r_data.io.r_nent = nstrides;
903 } else {
904 req->r_data.io.r_nstrides = nstrides;
905 req->r_data.io.r_nent = 1;
906 }
907 break;
908
909 case LISTIO:
910#ifdef CRAY
911 strcpy(req->r_data.listio.r_file, fptr->f_path);
912 req->r_data.listio.r_offset = offset;
913 req->r_data.listio.r_cmd = cmd;
914 req->r_data.listio.r_aio_strat =
915 (aio_strat == NULL) ? 0 : aio_strat->m_value;
916 req->r_data.listio.r_filestride = 0;
917 req->r_data.listio.r_memstride = 0;
918 req->r_data.listio.r_opcode = opcode;
919 req->r_data.listio.r_nstrides = 1;
920 req->r_data.listio.r_nbytes = length;
921 req->r_data.listio.r_uflags =
922 (flags->m_flags & FLG_RAW) ? F_WORD_ALIGNED : 0;
923
924 if (opcode == LO_WRITE) {
925 req->r_data.listio.r_pattern = pattern;
926 req->r_data.listio.r_oflags = O_WRONLY | flags->m_value;
927 } else {
928 req->r_data.listio.r_oflags = O_RDONLY | flags->m_value;
929 }
930#endif
931 break;
932 }
933
934 return 0;
plars865695b2001-08-27 22:15:12 +0000935}
936
937/*
938 * Get information about a file that iogen uses to choose io length and
939 * offset. Information gathered is file length, iounit, and raw iounit.
940 * For regurlar files, iounit is 1, and raw iounit is the iounit of the
941 * device on which the file resides. For block/character special files
942 * the iounit and raw iounit are both the iounit of the device.
943 *
944 * Note: buffered and osync io must be iounit aligned
945 * raw and ossd io must be raw iounit aligned
946 */
947
Wanlong Gao354ebb42012-12-07 10:10:04 +0800948int get_file_info(struct file_info *rec)
plars865695b2001-08-27 22:15:12 +0000949{
Wanlong Gao354ebb42012-12-07 10:10:04 +0800950 struct stat sbuf;
plars865695b2001-08-27 22:15:12 +0000951#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +0800952 struct lk_device_info dinfo;
plars865695b2001-08-27 22:15:12 +0000953#endif
954#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +0800955 int fd;
956 struct dioattr finfo;
plars865695b2001-08-27 22:15:12 +0000957#endif
958
plars865695b2001-08-27 22:15:12 +0000959 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +0800960 * Figure out if the files is regular, block or character special. Any
961 * other type is an error.
plars865695b2001-08-27 22:15:12 +0000962 */
963
Wanlong Gao354ebb42012-12-07 10:10:04 +0800964 if (stat(rec->f_path, &sbuf) == -1) {
965 fprintf(stderr,
966 "iogen%s: get_file_info(): Could not stat() %s: %s\n",
967 TagName, rec->f_path, SYSERR);
968 return -1;
plars865695b2001-08-27 22:15:12 +0000969 }
Wanlong Gao354ebb42012-12-07 10:10:04 +0800970#if _CRAY2
971 if ((!S_ISREG(sbuf.st_mode)) || strncmp(rec->f_path, "/dev/", 5) == 0) {
972 fprintf(stderr,
973 "iogen%s: device level io not supported on cray2\n",
974 TagName);
975 return -1;
976 }
977#endif
plars865695b2001-08-27 22:15:12 +0000978
Wanlong Gao354ebb42012-12-07 10:10:04 +0800979 rec->f_type = sbuf.st_mode & S_IFMT;
980
981 /*
982 * If regular, iou is 1, and we must figure out the device on
983 * which the file resides. riou is the iou (logical sector size) of
984 * this device.
985 */
986
987 if (S_ISREG(sbuf.st_mode)) {
988 rec->f_iou = 1;
989 rec->f_length = sbuf.st_size;
990
991 /*
992 * If -r used, take Rawmult as the raw/ssd io multiple. Otherwise
993 * attempt to determine it by looking at the device the file
994 * resides on.
995 */
996
997 if (r_opt) {
998 rec->f_riou = Rawmult;
999 return 0;
1000 }
plars865695b2001-08-27 22:15:12 +00001001#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08001002 if (lk_rawdev(rec->f_path, dinfo.path, sizeof(dinfo.path), 0) ==
1003 -1)
1004 return -1;
plars865695b2001-08-27 22:15:12 +00001005
Wanlong Gao354ebb42012-12-07 10:10:04 +08001006 if (lk_devinfo(&dinfo, 0) == -1) {
1007 /* can't get raw I/O unit -- use stat to fudge it */
1008 rec->f_riou = sbuf.st_blksize;
1009 } else {
1010 rec->f_riou = ctob(dinfo.iou);
1011 }
plars865695b2001-08-27 22:15:12 +00001012#endif
1013#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001014 rec->f_riou = BSIZE;
plars865695b2001-08-27 22:15:12 +00001015#endif
1016#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08001017 if ((fd = open(rec->f_path, O_RDWR | O_DIRECT, 0)) != -1) {
1018 if (fcntl(fd, F_DIOINFO, &finfo) != -1) {
1019 rec->f_riou = finfo.d_miniosz;
1020 } else {
1021 fprintf(stderr,
1022 "iogen%s: Error %s (%d) getting direct I/O info of file %s\n",
1023 TagName, strerror(errno), errno,
1024 rec->f_path);
1025 }
1026 close(fd);
1027 } else {
1028 rec->f_riou = BBSIZE;
1029 }
1030#endif /* SGI */
plars865695b2001-08-27 22:15:12 +00001031
Wanlong Gao354ebb42012-12-07 10:10:04 +08001032 } else {
plars865695b2001-08-27 22:15:12 +00001033
1034#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08001035 /*
1036 * Otherwise, file is a device. Use lk_devinfo() to get its logical
1037 * sector size. This is the iou and riou
1038 */
plars865695b2001-08-27 22:15:12 +00001039
Wanlong Gao354ebb42012-12-07 10:10:04 +08001040 strcpy(dinfo.path, rec->f_path);
plars865695b2001-08-27 22:15:12 +00001041
Wanlong Gao354ebb42012-12-07 10:10:04 +08001042 if (lk_devinfo(&dinfo, 0) == -1) {
1043 fprintf(stderr, "iogen%s: %s: %s\n", TagName,
1044 Lk_err_func, Lk_err_mesg);
1045 return -1;
1046 }
plars865695b2001-08-27 22:15:12 +00001047
Wanlong Gao354ebb42012-12-07 10:10:04 +08001048 rec->f_iou = ctob(dinfo.iou);
1049 rec->f_riou = ctob(dinfo.iou);
1050 rec->f_length = ctob(dinfo.length);
plars865695b2001-08-27 22:15:12 +00001051#else
1052#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08001053 rec->f_riou = BBSIZE;
1054 rec->f_length = BBSIZE;
plars865695b2001-08-27 22:15:12 +00001055#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001056 rec->f_riou = BSIZE;
1057 rec->f_length = BSIZE;
plars865695b2001-08-27 22:15:12 +00001058#endif /* sgi */
1059#endif /* CRAY */
Wanlong Gao354ebb42012-12-07 10:10:04 +08001060 }
plars865695b2001-08-27 22:15:12 +00001061
Wanlong Gao354ebb42012-12-07 10:10:04 +08001062 return 0;
plars865695b2001-08-27 22:15:12 +00001063}
1064
1065/*
1066 * Create file path as nbytes long. If path exists, the file will either be
1067 * extended or truncated to be nbytes long. Returns final size of file,
1068 * or -1 if there was a failure.
1069 */
1070
Wanlong Gao354ebb42012-12-07 10:10:04 +08001071int create_file(char *path, int nbytes)
plars865695b2001-08-27 22:15:12 +00001072{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001073 int fd, rval;
1074 char c;
1075 struct stat sbuf;
plars865695b2001-08-27 22:15:12 +00001076#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08001077 int nb;
1078 struct flock f;
1079 struct fsxattr xattr;
1080 struct dioattr finfo;
1081 char *b, *buf;
plars865695b2001-08-27 22:15:12 +00001082#endif
1083
Wanlong Gao354ebb42012-12-07 10:10:04 +08001084 errno = 0;
1085 rval = stat(path, &sbuf);
plars865695b2001-08-27 22:15:12 +00001086
Wanlong Gao354ebb42012-12-07 10:10:04 +08001087 if (rval == -1) {
1088 if (errno == ENOENT) {
1089 sbuf.st_size = 0;
plars865695b2001-08-27 22:15:12 +00001090 } else {
Wanlong Gao354ebb42012-12-07 10:10:04 +08001091 fprintf(stderr,
1092 "iogen%s: Could not stat file %s: %s (%d)\n",
1093 TagName, path, SYSERR, errno);
1094 return -1;
plars865695b2001-08-27 22:15:12 +00001095 }
Wanlong Gao354ebb42012-12-07 10:10:04 +08001096 } else {
1097 if (!S_ISREG(sbuf.st_mode)) {
1098 fprintf(stderr,
1099 "iogen%s: file %s exists, but is not a regular file - cannot modify length\n",
1100 TagName, path);
1101 return -1;
1102 }
plars865695b2001-08-27 22:15:12 +00001103 }
plars865695b2001-08-27 22:15:12 +00001104
Wanlong Gao354ebb42012-12-07 10:10:04 +08001105 if (sbuf.st_size == nbytes)
1106 return nbytes;
plars865695b2001-08-27 22:15:12 +00001107
Wanlong Gao354ebb42012-12-07 10:10:04 +08001108 Oflags |= O_CREAT | O_WRONLY;
1109
1110 if ((fd = open(path, Oflags, 0666)) == -1) {
1111 fprintf(stderr,
1112 "iogen%s: Could not create/open file %s: %s (%d)\n",
1113 TagName, path, SYSERR, errno);
1114 return -1;
1115 }
1116
1117 /*
1118 * Truncate file if it is longer than nbytes, otherwise attempt to
1119 * pre-allocate file blocks.
1120 */
1121
1122 if (sbuf.st_size > nbytes) {
1123 if (ftruncate(fd, nbytes) == -1) {
1124 fprintf(stderr,
1125 "iogen%s: Could not ftruncate() %s to %d bytes: %s (%d)\n",
1126 TagName, path, nbytes, SYSERR, errno);
1127 close(fd);
1128 return -1;
1129 }
1130 } else {
1131
1132#ifdef sgi
1133 /*
1134 * The file must be designated as Real-Time before any data
1135 * is allocated to it.
1136 *
1137 */
1138 if (Orealtime != 0) {
1139 memset(&xattr, 0x00, sizeof(xattr));
1140 xattr.fsx_xflags = XFS_XFLAG_REALTIME;
1141 /*fprintf(stderr, "set: fsx_xflags = 0x%x\n", xattr.fsx_xflags); */
1142 if (fcntl(fd, F_FSSETXATTR, &xattr) == -1) {
1143 fprintf(stderr,
1144 "iogen%s: Error %s (%d) setting XFS XATTR->Realtime on file %s\n",
1145 TagName, SYSERR, errno, path);
1146 close(fd);
1147 return -1;
1148 }
1149#ifdef DEBUG
1150 if (fcntl(fd, F_FSGETXATTR, &xattr) == -1) {
1151 fprintf(stderr,
1152 "iogen%s: Error getting realtime flag %s (%d)\n",
1153 TagName, SYSERR, errno);
1154 close(fd);
1155 return -1;
1156 } else {
1157 fprintf(stderr, "get: fsx_xflags = 0x%x\n",
1158 xattr.fsx_xflags);
1159 }
1160#endif
1161 }
1162
1163 /*
1164 * Reserve space with F_RESVSP
1165 *
1166 * Failure is ignored since F_RESVSP only works on XFS and the
1167 * filesystem could be on EFS or NFS
1168 */
1169 if (Oreserve) {
1170 f.l_whence = SEEK_SET;
1171 f.l_start = 0;
1172 f.l_len = nbytes;
1173
1174 /*fprintf(stderr,
1175 "create_file: fcntl(%d, F_RESVSP, { %d, %lld, %lld })\n",
1176 fd, f.l_whence, (long long)f.l_start, (long long)f.l_len); */
1177
1178 /* non-zeroing reservation */
1179 if (fcntl(fd, F_RESVSP, &f) == -1) {
1180 fprintf(stderr,
1181 "iogen%s: Could not fcntl(F_RESVSP) %d bytes in file %s: %s (%d)\n",
1182 TagName, nbytes, path, SYSERR, errno);
1183 close(fd);
1184 return -1;
1185 }
1186 }
1187
1188 if (Oallocate) {
1189 /* F_ALLOCSP allocates from the start of the file to l_start */
1190 f.l_whence = SEEK_SET;
1191 f.l_start = nbytes;
1192 f.l_len = 0;
1193 /*fprintf(stderr,
1194 "create_file: fcntl(%d, F_ALLOCSP, { %d, %lld, %lld })\n",
1195 fd, f.l_whence, (long long)f.l_start,
1196 (long long)f.l_len); */
1197
1198 /* zeroing reservation */
1199 if (fcntl(fd, F_ALLOCSP, &f) == -1) {
1200 fprintf(stderr,
1201 "iogen%s: Could not fcntl(F_ALLOCSP) %d bytes in file %s: %s (%d)\n",
1202 TagName, nbytes, path, SYSERR, errno);
1203 close(fd);
1204 return -1;
1205 }
1206 }
1207#endif /* sgi */
1208
1209 /*
1210 * Write a byte at the end of file so that stat() sets the right
1211 * file size.
1212 */
1213
1214#ifdef sgi
1215 if (Owrite == 2) {
1216 close(fd);
1217 if ((fd =
1218 open(path, O_CREAT | O_RDWR | O_DIRECT,
1219 0)) != -1) {
1220 if (fcntl(fd, F_DIOINFO, &finfo) == -1) {
1221 fprintf(stderr,
1222 "iogen%s: Error %s (%d) getting direct I/O info for file %s\n",
1223 TagName, SYSERR, errno, path);
1224 return -1;
1225 } else {
1226 /*fprintf(stderr, "%s: miniosz=%d\n",
1227 path, finfo.d_miniosz); */
1228 }
1229 } else {
1230 fprintf(stderr,
1231 "iogen%s: Error %s (%d) opening file %s with flags O_CREAT|O_RDWR|O_DIRECT\n",
1232 TagName, SYSERR, errno, path);
1233 return -1;
1234 }
1235
1236 /*
1237 * nb is nbytes adjusted down by an even d_miniosz block
1238 *
1239 * Note: the first adjustment can cause iogen to print a warning
1240 * about not being able to create a file of <nbytes> length,
1241 * since the file will be shorter.
1242 */
1243 nb = nbytes - finfo.d_miniosz;
1244 nb = nb - nb % finfo.d_miniosz;
1245
1246 /*fprintf(stderr,
1247 "create_file_ow2: lseek(%d, %d {%d %d}, SEEK_SET)\n",
1248 fd, nb, nbytes, finfo.d_miniosz); */
1249
1250 if (lseek(fd, nb, SEEK_SET) == -1) {
1251 fprintf(stderr,
1252 "iogen%s: Could not lseek() to EOF of file %s: %s (%d)\n\tactual offset %d file size goal %d miniosz %lld\n",
1253 TagName, path, SYSERR, errno,
1254 nb, nbytes, (long long)finfo.d_miniosz);
1255 close(fd);
1256 return -1;
1257 }
1258
Cyril Hrubisd218f342014-09-23 13:14:56 +02001259 b = buf = malloc(finfo.d_miniosz + finfo.d_mem);
Wanlong Gao354ebb42012-12-07 10:10:04 +08001260
1261 if (((long)buf % finfo.d_mem != 0)) {
1262 buf += finfo.d_mem - ((long)buf % finfo.d_mem);
1263 }
1264
1265 memset(buf, 0, finfo.d_miniosz);
1266
1267 if ((rval =
1268 write(fd, buf,
1269 finfo.d_miniosz)) != finfo.d_miniosz) {
1270 fprintf(stderr,
1271 "iogen%s: Could not write %d byte length file %s: %s (%d)\n",
1272 TagName, nb, path, SYSERR, errno);
1273 fprintf(stderr, "\twrite(%d, 0x%lx, %d) = %d\n",
1274 fd, (long)buf, finfo.d_miniosz, rval);
1275 fprintf(stderr,
1276 "\toffset %d file size goal %d, miniosz=%d\n",
1277 nb, nbytes, finfo.d_miniosz);
1278 close(fd);
1279 return -1;
1280 }
1281 free(b);
1282 } else
1283#endif /* sgi */
1284 if (Owrite) {
1285 /*fprintf(stderr,
1286 "create_file_Owrite: lseek(%d, %d {%d}, SEEK_SET)\n",
1287 fd, nbytes-1, nbytes); */
1288
1289 if (lseek(fd, nbytes - 1, SEEK_SET) == -1) {
1290 fprintf(stderr,
1291 "iogen%s: Could not lseek() to EOF in file %s: %s (%d)\n\toffset goal %d\n",
1292 TagName, path, SYSERR, errno,
1293 nbytes - 1);
1294 close(fd);
1295 return -1;
1296 }
1297
1298 if ((rval = write(fd, &c, 1)) != 1) {
1299 fprintf(stderr,
1300 "iogen%s: Could not create a %d byte length file %s: %s (%d)\n",
1301 TagName, nbytes, path, SYSERR, errno);
1302 fprintf(stderr,
1303 "\twrite(%d, 0x%lx, %d) = %d\n",
1304 fd, (long)&c, 1, rval);
1305 fprintf(stderr,
1306 "\toffset %d file size goal %d\n",
1307 nbytes - 1, nbytes);
1308 close(fd);
1309 return -1;
1310 }
1311 }
1312 }
1313
1314 fstat(fd, &sbuf);
1315 close(fd);
1316
1317 return sbuf.st_size;
plars865695b2001-08-27 22:15:12 +00001318}
1319
1320/*
1321 * Function to convert a string to its corresponding value in a strmap array.
1322 * If the string is not found in the array, the value corresponding to the
1323 * NULL string (the last element in the array) is returned.
1324 */
1325
Wanlong Gao354ebb42012-12-07 10:10:04 +08001326int str_to_value(struct strmap *map, char *str)
plars865695b2001-08-27 22:15:12 +00001327{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001328 struct strmap *mp;
plars865695b2001-08-27 22:15:12 +00001329
Wanlong Gao354ebb42012-12-07 10:10:04 +08001330 for (mp = map; mp->m_string != NULL; mp++)
1331 if (strcmp(mp->m_string, str) == 0)
1332 break;
plars865695b2001-08-27 22:15:12 +00001333
Wanlong Gao354ebb42012-12-07 10:10:04 +08001334 return mp->m_value;
plars865695b2001-08-27 22:15:12 +00001335}
Garrett Cooper2c282152010-12-16 00:55:50 -08001336
plars865695b2001-08-27 22:15:12 +00001337/*
1338 * Function to convert a string to its corresponding entry in a strmap array.
1339 * If the string is not found in the array, a NULL is returned.
1340 */
1341
Wanlong Gao354ebb42012-12-07 10:10:04 +08001342struct strmap *str_lookup(struct strmap *map, char *str)
plars865695b2001-08-27 22:15:12 +00001343{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001344 struct strmap *mp;
plars865695b2001-08-27 22:15:12 +00001345
Wanlong Gao354ebb42012-12-07 10:10:04 +08001346 for (mp = map; mp->m_string != NULL; mp++)
1347 if (strcmp(mp->m_string, str) == 0)
1348 break;
plars865695b2001-08-27 22:15:12 +00001349
Wanlong Gao354ebb42012-12-07 10:10:04 +08001350 return ((mp->m_string == NULL) ? NULL : mp);
plars865695b2001-08-27 22:15:12 +00001351}
plars865695b2001-08-27 22:15:12 +00001352
1353/*
1354 * Function to convert a value to its corresponding string in a strmap array.
1355 * If the value is not found in the array, NULL is returned.
1356 */
1357
Wanlong Gao354ebb42012-12-07 10:10:04 +08001358char *value_to_string(struct strmap *map, int val)
plars865695b2001-08-27 22:15:12 +00001359{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001360 struct strmap *mp;
plars865695b2001-08-27 22:15:12 +00001361
Wanlong Gao354ebb42012-12-07 10:10:04 +08001362 for (mp = map; mp->m_string != NULL; mp++)
1363 if (mp->m_value == val)
1364 break;
plars865695b2001-08-27 22:15:12 +00001365
Wanlong Gao354ebb42012-12-07 10:10:04 +08001366 return mp->m_string;
plars865695b2001-08-27 22:15:12 +00001367}
1368
1369/*
1370 * Interpret cmdline options/arguments. Exit with 1 if something on the
1371 * cmdline isn't kosher.
1372 */
1373
Wanlong Gao354ebb42012-12-07 10:10:04 +08001374int parse_cmdline(int argc, char **argv, char *opts)
plars865695b2001-08-27 22:15:12 +00001375{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001376 int o, len, nb, format_error;
1377 struct strmap *flgs, *sc;
1378 char *file, *cp, ch;
1379 extern int opterr;
1380 extern int optind;
1381 extern char *optarg;
1382 struct strmap *mp;
1383 struct file_info *fptr;
1384 int nopenargs;
1385 char *openargs[5]; /* Flags, cbits, cblks */
1386 char *errmsg;
1387 int str_to_int();
1388 opterr = 0;
plars865695b2001-08-27 22:15:12 +00001389#ifndef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001390 char *ranges;
1391 struct strmap *type;
plars865695b2001-08-27 22:15:12 +00001392#endif
1393
Wanlong Gao354ebb42012-12-07 10:10:04 +08001394 while ((o = getopt(argc, argv, opts)) != EOF) {
1395 switch ((char)o) {
plars865695b2001-08-27 22:15:12 +00001396
Wanlong Gao354ebb42012-12-07 10:10:04 +08001397 case 'a':
plars865695b2001-08-27 22:15:12 +00001398#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001399 fprintf(stderr,
1400 "iogen%s: Unrecognized option -a on this platform\n",
1401 TagName);
1402 exit(2);
plars865695b2001-08-27 22:15:12 +00001403#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001404 cp = strtok(optarg, ",");
1405 while (cp != NULL) {
1406 if ((type =
1407 str_lookup(Aio_Strat_Map, cp)) == NULL) {
1408 fprintf(stderr,
1409 "iogen%s: Unrecognized aio completion strategy: %s\n",
1410 TagName, cp);
1411 exit(2);
1412 }
plars865695b2001-08-27 22:15:12 +00001413
Wanlong Gao354ebb42012-12-07 10:10:04 +08001414 Aio_Strat_List[Naio_Strat_Types++] = type;
1415 cp = strtok(NULL, ",");
1416 }
1417 a_opt++;
plars865695b2001-08-27 22:15:12 +00001418#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +08001419 break;
plars865695b2001-08-27 22:15:12 +00001420
Wanlong Gao354ebb42012-12-07 10:10:04 +08001421 case 'f':
1422 cp = strtok(optarg, ",");
1423 while (cp != NULL) {
1424 if ((flgs = str_lookup(Flag_Map, cp)) == NULL) {
1425 fprintf(stderr,
1426 "iogen%s: Unrecognized flags: %s\n",
1427 TagName, cp);
1428 exit(2);
1429 }
plars865695b2001-08-27 22:15:12 +00001430
Wanlong Gao354ebb42012-12-07 10:10:04 +08001431 cp = strtok(NULL, ",");
plars865695b2001-08-27 22:15:12 +00001432
1433#ifdef O_SSD
Wanlong Gao354ebb42012-12-07 10:10:04 +08001434 if (flgs->m_value & O_SSD && !Sds_Avail) {
1435 fprintf(stderr,
1436 "iogen%s: Warning - no sds available, ignoring ssd flag\n",
1437 TagName);
1438 continue;
1439 }
plars865695b2001-08-27 22:15:12 +00001440#endif
1441
Wanlong Gao354ebb42012-12-07 10:10:04 +08001442 Flag_List[Nflags++] = flgs;
1443 }
1444 f_opt++;
1445 break;
plars865695b2001-08-27 22:15:12 +00001446
Wanlong Gao354ebb42012-12-07 10:10:04 +08001447 case 'h':
1448 help(stdout);
1449 exit(0);
1450 break;
plars865695b2001-08-27 22:15:12 +00001451
Wanlong Gao354ebb42012-12-07 10:10:04 +08001452 case 'i':
1453 format_error = 0;
plars865695b2001-08-27 22:15:12 +00001454
Wanlong Gao354ebb42012-12-07 10:10:04 +08001455 switch (sscanf(optarg, "%i%c", &Iterations, &ch)) {
1456 case 1:
1457 Time_Mode = 0;
1458 break;
plars865695b2001-08-27 22:15:12 +00001459
Wanlong Gao354ebb42012-12-07 10:10:04 +08001460 case 2:
1461 if (ch == 's')
1462 Time_Mode = 1;
1463 else
1464 format_error = 1;
1465 break;
plars865695b2001-08-27 22:15:12 +00001466
Wanlong Gao354ebb42012-12-07 10:10:04 +08001467 default:
1468 format_error = 1;
1469 }
plars865695b2001-08-27 22:15:12 +00001470
Wanlong Gao354ebb42012-12-07 10:10:04 +08001471 if (Iterations < 0)
1472 format_error = 1;
plars865695b2001-08-27 22:15:12 +00001473
Wanlong Gao354ebb42012-12-07 10:10:04 +08001474 if (format_error) {
1475 fprintf(stderr,
1476 "iogen%s: Illegal -i arg (%s): Must be of the format: number[s]\n",
1477 TagName, optarg);
1478 fprintf(stderr,
1479 " where 'number' is >= 0\n");
1480 exit(1);
1481 }
plars865695b2001-08-27 22:15:12 +00001482
Wanlong Gao354ebb42012-12-07 10:10:04 +08001483 i_opt++;
1484 break;
plars865695b2001-08-27 22:15:12 +00001485
Wanlong Gao354ebb42012-12-07 10:10:04 +08001486 case 'L':
plars865695b2001-08-27 22:15:12 +00001487#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001488 fprintf(stderr,
1489 "iogen%s: Unrecognized option -L on this platform\n",
1490 TagName);
1491 exit(2);
plars865695b2001-08-27 22:15:12 +00001492#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001493 if (parse_ranges(optarg, 1, 255, 1, NULL, &ranges,
1494 &errmsg) == -1) {
1495 fprintf(stderr,
1496 "iogen%s: error parsing listio range '%s': %s\n",
1497 TagName, optarg, errmsg);
1498 exit(1);
1499 }
plars865695b2001-08-27 22:15:12 +00001500
Wanlong Gao354ebb42012-12-07 10:10:04 +08001501 Minstrides = range_min(ranges, 0);
1502 Maxstrides = range_max(ranges, 0);
plars865695b2001-08-27 22:15:12 +00001503
Wanlong Gao354ebb42012-12-07 10:10:04 +08001504 free(ranges);
1505 L_opt++;
plars865695b2001-08-27 22:15:12 +00001506#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +08001507 break;
plars865695b2001-08-27 22:15:12 +00001508
Wanlong Gao354ebb42012-12-07 10:10:04 +08001509 case 'm':
1510 if ((Offset_Mode =
1511 str_lookup(Omode_Map, optarg)) == NULL) {
1512 fprintf(stderr,
1513 "iogen%s: Illegal -m arg (%s)\n",
1514 TagName, optarg);
1515 exit(1);
1516 }
plars865695b2001-08-27 22:15:12 +00001517
Wanlong Gao354ebb42012-12-07 10:10:04 +08001518 m_opt++;
1519 break;
plars865695b2001-08-27 22:15:12 +00001520
Wanlong Gao354ebb42012-12-07 10:10:04 +08001521 case 'N':
1522 sprintf(TagName, "(%.39s)", optarg);
1523 break;
plars865695b2001-08-27 22:15:12 +00001524
Wanlong Gao354ebb42012-12-07 10:10:04 +08001525 case 'o':
1526 o_opt++;
1527 break;
plars865695b2001-08-27 22:15:12 +00001528
Wanlong Gao354ebb42012-12-07 10:10:04 +08001529 case 'O':
plars865695b2001-08-27 22:15:12 +00001530
Wanlong Gao354ebb42012-12-07 10:10:04 +08001531 nopenargs = string_to_tokens(optarg, openargs, 4, ":/");
plars865695b2001-08-27 22:15:12 +00001532
1533#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08001534 if (nopenargs)
1535 sscanf(openargs[1], "%i", &Ocbits);
1536 if (nopenargs > 1)
1537 sscanf(openargs[2], "%i", &Ocblks);
plars865695b2001-08-27 22:15:12 +00001538
Wanlong Gao354ebb42012-12-07 10:10:04 +08001539 Oflags = parse_open_flags(openargs[0], &errmsg);
1540 if (Oflags == -1) {
1541 fprintf(stderr, "iogen%s: -O %s error: %s\n",
1542 TagName, optarg, errmsg);
1543 exit(1);
1544 }
plars865695b2001-08-27 22:15:12 +00001545#endif
1546#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001547 Oflags = parse_open_flags(openargs[0], &errmsg);
1548 if (Oflags == -1) {
1549 fprintf(stderr, "iogen%s: -O %s error: %s\n",
1550 TagName, optarg, errmsg);
1551 exit(1);
1552 }
plars865695b2001-08-27 22:15:12 +00001553#endif
1554#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08001555 if (!strcmp(openargs[0], "realtime")) {
1556 /*
1557 * -O realtime:extsize
1558 */
1559 Orealtime = 1;
1560 if (nopenargs > 1)
1561 sscanf(openargs[1], "%i", &Oextsize);
1562 else
1563 Oextsize = 0;
1564 } else if (!strcmp(openargs[0], "allocate") ||
1565 !strcmp(openargs[0], "allocsp")) {
1566 /*
1567 * -O allocate
1568 */
1569 Oreserve = 0;
1570 Oallocate = 1;
1571 } else if (!strcmp(openargs[0], "reserve")) {
1572 /*
1573 * -O [no]reserve
1574 */
1575 Oallocate = 0;
1576 Oreserve = 1;
1577 } else if (!strcmp(openargs[0], "noreserve")) {
1578 /* Oreserve=1 by default; this clears that default */
1579 Oreserve = 0;
1580 } else if (!strcmp(openargs[0], "nowrite")) {
1581 /* Owrite=1 by default; this clears that default */
1582 Owrite = 0;
1583 } else if (!strcmp(openargs[0], "direct")) {
1584 /* this means "use direct i/o to preallocate file" */
1585 Owrite = 2;
1586 } else {
1587 fprintf(stderr,
1588 "iogen%s: Error: -O %s error: unrecognized option\n",
1589 TagName, openargs[0]);
1590 exit(1);
1591 }
plars865695b2001-08-27 22:15:12 +00001592#endif
1593
Wanlong Gao354ebb42012-12-07 10:10:04 +08001594 O_opt++;
1595 break;
plars865695b2001-08-27 22:15:12 +00001596
Wanlong Gao354ebb42012-12-07 10:10:04 +08001597 case 'p':
1598 Outpipe = optarg;
1599 p_opt++;
1600 break;
plars865695b2001-08-27 22:15:12 +00001601
Wanlong Gao354ebb42012-12-07 10:10:04 +08001602 case 'r':
1603 if ((Rawmult = bytes_by_prefix(optarg)) == -1 ||
1604 Rawmult < 11 || Rawmult % BSIZE) {
1605 fprintf(stderr,
1606 "iogen%s: Illegal -r arg (%s). Must be > 0 and multipe of BSIZE (%d)\n",
1607 TagName, optarg, BSIZE);
1608 exit(1);
1609 }
plars865695b2001-08-27 22:15:12 +00001610
Wanlong Gao354ebb42012-12-07 10:10:04 +08001611 r_opt++;
1612 break;
plars865695b2001-08-27 22:15:12 +00001613
Wanlong Gao354ebb42012-12-07 10:10:04 +08001614 case 's':
1615 cp = strtok(optarg, ",");
1616 while (cp != NULL) {
1617 if ((sc = str_lookup(Syscall_Map, cp)) == NULL) {
1618 fprintf(stderr,
1619 "iogen%s: Unrecognized syscall: %s\n",
1620 TagName, cp);
1621 exit(2);
1622 }
1623
1624 do {
1625 /* >>> sc->m_flags & FLG_SDS */
1626 if (sc->m_value != SSREAD
1627 && sc->m_value != SSWRITE)
1628 Fileio++;
1629
1630 Syscall_List[Nsyscalls++] = sc;
1631 } while ((sc = str_lookup(++sc, cp)) != NULL);
1632
1633 cp = strtok(NULL, ",");
1634 }
1635 s_opt++;
1636 break;
1637
1638 case 't':
1639 if ((Mintrans = bytes_by_prefix(optarg)) == -1) {
1640 fprintf(stderr,
1641 "iogen%s: Illegal -t arg (%s): Must have the form num[bkm]\n",
1642 TagName, optarg);
1643 exit(1);
1644 }
1645 t_opt++;
1646 break;
1647
1648 case 'T':
1649 if ((Maxtrans = bytes_by_prefix(optarg)) == -1) {
1650 fprintf(stderr,
1651 "iogen%s: Illegal -T arg (%s): Must have the form num[bkm]\n",
1652 TagName, optarg);
1653 exit(1);
1654 }
1655 T_opt++;
1656 break;
1657
1658 case 'q':
1659 q_opt++;
1660 break;
1661
1662 case '?':
1663 usage(stderr);
1664 exit(1);
plars865695b2001-08-27 22:15:12 +00001665 }
plars865695b2001-08-27 22:15:12 +00001666 }
1667
1668 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +08001669 * Supply defaults
plars865695b2001-08-27 22:15:12 +00001670 */
subrata_modakbdbaec52009-02-26 12:14:51 +00001671
Wanlong Gao354ebb42012-12-07 10:10:04 +08001672 if (!L_opt) {
1673 Minstrides = 1;
1674 Maxstrides = 255;
plars865695b2001-08-27 22:15:12 +00001675 }
1676
Wanlong Gao354ebb42012-12-07 10:10:04 +08001677 if (!m_opt)
1678 Offset_Mode = str_lookup(Omode_Map, "sequential");
plars865695b2001-08-27 22:15:12 +00001679
Wanlong Gao354ebb42012-12-07 10:10:04 +08001680 if (!i_opt)
1681 Iterations = 0;
plars865695b2001-08-27 22:15:12 +00001682
Wanlong Gao354ebb42012-12-07 10:10:04 +08001683 if (!t_opt)
1684 Mintrans = 1;
plars865695b2001-08-27 22:15:12 +00001685
Wanlong Gao354ebb42012-12-07 10:10:04 +08001686 if (!T_opt)
1687 Maxtrans = 256 * BSIZE;
plars865695b2001-08-27 22:15:12 +00001688
Wanlong Gao354ebb42012-12-07 10:10:04 +08001689 if (!O_opt)
1690 Oflags = Ocbits = Ocblks = 0;
1691
1692 /*
1693 * Supply default async io completion strategy types.
1694 */
1695
1696 if (!a_opt) {
1697 for (mp = Aio_Strat_Map; mp->m_string != NULL; mp++) {
1698 Aio_Strat_List[Naio_Strat_Types++] = mp;
plars865695b2001-08-27 22:15:12 +00001699 }
Wanlong Gao354ebb42012-12-07 10:10:04 +08001700 }
plars865695b2001-08-27 22:15:12 +00001701
Wanlong Gao354ebb42012-12-07 10:10:04 +08001702 /*
1703 * Supply default syscalls. Default is read,write,reada,writea,listio.
1704 */
plars865695b2001-08-27 22:15:12 +00001705
Wanlong Gao354ebb42012-12-07 10:10:04 +08001706 if (!s_opt) {
1707 Nsyscalls = 0;
1708 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "read");
1709 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "write");
1710#ifdef CRAY
1711 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "reada");
1712 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "writea");
1713 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "lread");
1714 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "lreada");
1715 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "lwrite");
1716 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "lwritea");
1717#endif
plars865695b2001-08-27 22:15:12 +00001718
Wanlong Gao354ebb42012-12-07 10:10:04 +08001719#ifdef sgi
1720 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "pread");
1721 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "pwrite");
1722 /*Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "aread"); */
1723 /*Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "awrite"); */
1724#endif
1725
1726#ifndef CRAY
1727 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "readv");
1728 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "writev");
1729 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "mmread");
1730 Syscall_List[Nsyscalls++] = str_lookup(Syscall_Map, "mmwrite");
1731#endif
1732
1733 Fileio = 1;
1734 }
1735
1736 if (Fileio && (argc - optind < 1)) {
1737 fprintf(stderr, "iogen%s: No files specified on the cmdline\n",
1738 TagName);
1739 exit(1);
1740 }
1741
1742 /*
1743 * Supply default file io flags - defaut is 'buffered,raw,sync,ldraw'.
1744 */
1745
1746 if (!f_opt && Fileio) {
1747 Nflags = 0;
1748 Flag_List[Nflags++] = str_lookup(Flag_Map, "buffered");
1749 Flag_List[Nflags++] = str_lookup(Flag_Map, "sync");
1750#ifdef CRAY
1751 Flag_List[Nflags++] = str_lookup(Flag_Map, "raw+wf");
1752 Flag_List[Nflags++] = str_lookup(Flag_Map, "ldraw");
1753#endif
1754
1755#ifdef sgi
1756 /* Warning: cannot mix direct i/o with others! */
1757 Flag_List[Nflags++] = str_lookup(Flag_Map, "dsync");
1758 Flag_List[Nflags++] = str_lookup(Flag_Map, "rsync");
1759 /* Flag_List[Nflags++] = str_lookup(Flag_Map, "rsync+sync"); */
1760 /* Flag_List[Nflags++] = str_lookup(Flag_Map, "rsync+dsync"); */
1761#endif
1762 }
1763
1764 if (Fileio) {
1765 if (optind >= argc) {
1766 fprintf(stderr,
1767 "iogen%s: No files listed on the cmdline\n",
1768 TagName);
1769 exit(1);
plars865695b2001-08-27 22:15:12 +00001770 }
plars865695b2001-08-27 22:15:12 +00001771
1772 /*
Wanlong Gao354ebb42012-12-07 10:10:04 +08001773 * Initialize File_List[] - only necessary if doing file io. First
1774 * space for the File_List array, then fill it in.
plars865695b2001-08-27 22:15:12 +00001775 */
1776
Cyril Hrubisd218f342014-09-23 13:14:56 +02001777 File_List = malloc((argc - optind) * sizeof(struct file_info));
Wanlong Gao354ebb42012-12-07 10:10:04 +08001778
1779 if (File_List == NULL) {
1780 fprintf(stderr,
1781 "iogen%s: Could not malloc space for %d file_info structures\n",
1782 TagName, argc - optind);
1783 exit(2);
plars865695b2001-08-27 22:15:12 +00001784 }
1785
Wanlong Gao354ebb42012-12-07 10:10:04 +08001786 memset(File_List, 0,
1787 (argc - optind) * sizeof(struct file_info));
plars865695b2001-08-27 22:15:12 +00001788
Wanlong Gao354ebb42012-12-07 10:10:04 +08001789 Nfiles = 0;
1790 while (optind < argc) {
1791 len = -1;
plars865695b2001-08-27 22:15:12 +00001792
Wanlong Gao354ebb42012-12-07 10:10:04 +08001793 /*
1794 * Pick off leading len: if it's there and create/extend/trunc
1795 * the file to the desired length. Otherwise, just make sure
1796 * the file is accessable.
1797 */
Garrett Cooper2c282152010-12-16 00:55:50 -08001798
Wanlong Gao354ebb42012-12-07 10:10:04 +08001799 if ((cp = strchr(argv[optind], ':')) != NULL) {
1800 *cp = '\0';
1801 if ((len = bytes_by_prefix(argv[optind])) == -1) {
1802 fprintf(stderr,
1803 "iogen%s: illegal file length (%s) for file %s\n",
1804 TagName, argv[optind], cp + 1);
1805 exit(2);
1806 }
1807 *cp = ':';
1808 file = cp + 1;
Garrett Cooper2c282152010-12-16 00:55:50 -08001809
Wanlong Gao354ebb42012-12-07 10:10:04 +08001810 if (strlen(file) > MAX_FNAME_LENGTH) {
1811 fprintf(stderr,
1812 "iogen%s: Max fname length is %d chars - ignoring file %s\n",
1813 TagName, MAX_FNAME_LENGTH,
1814 file);
1815 optind++;
1816 continue;
1817 }
Garrett Cooper2c282152010-12-16 00:55:50 -08001818
Wanlong Gao354ebb42012-12-07 10:10:04 +08001819 nb = create_file(file, len);
1820
1821 if (nb < len) {
1822 fprintf(stderr,
1823 "iogen%s warning: Couldn't create file %s of %d bytes\n",
1824 TagName, file, len);
1825
1826 if (nb <= 0) {
1827 optind++;
1828 continue;
1829 }
1830 }
1831 } else {
1832 file = argv[optind];
1833 if (access(file, R_OK | W_OK) == -1) {
1834 fprintf(stderr,
1835 "iogen%s: file %s cannot be accessed for reading and/or writing: %s (%d)\n",
1836 TagName, file, SYSERR, errno);
1837 exit(2);
1838 }
1839 }
1840
1841 /*
1842 * get per-file information
1843 */
1844
1845 fptr = &File_List[Nfiles];
1846
1847 if (file[0] == '/') {
1848 strcpy(fptr->f_path, file);
1849 } else {
1850 if (getcwd
1851 (fptr->f_path,
1852 sizeof(fptr->f_path) - 1) == NULL)
1853 perror
1854 ("Could not get current working directory");
1855 strcat(fptr->f_path, "/");
1856 strcat(fptr->f_path, file);
1857 }
1858
1859 if (get_file_info(fptr) == -1) {
1860 fprintf(stderr,
1861 "iogen%s warning: Error getting file info for %s\n",
1862 TagName, file);
1863 } else {
1864
1865 /*
1866 * If the file length is smaller than our min transfer size,
1867 * ignore it.
1868 */
1869
1870 if (fptr->f_length < Mintrans) {
1871 fprintf(stderr,
1872 "iogen%s warning: Ignoring file %s\n",
1873 TagName, fptr->f_path);
1874 fprintf(stderr,
1875 " length (%d) is < min transfer size (%d)\n",
1876 fptr->f_length, Mintrans);
1877 optind++;
1878 continue;
1879 }
1880
1881 /*
1882 * If the file length is smaller than our max transfer size,
1883 * ignore it.
1884 */
1885
1886 if (fptr->f_length < Maxtrans) {
1887 fprintf(stderr,
1888 "iogen%s warning: Ignoring file %s\n",
1889 TagName, fptr->f_path);
1890 fprintf(stderr,
1891 " length (%d) is < max transfer size (%d)\n",
1892 fptr->f_length, Maxtrans);
1893 optind++;
1894 continue;
1895 }
1896
1897 if (fptr->f_length > 0) {
1898 switch (Offset_Mode->m_value) {
1899 case M_SEQUENTIAL:
1900 fptr->f_lastoffset = 0;
1901 fptr->f_lastlength = 0;
1902 break;
1903
1904 case M_REVERSE:
1905 fptr->f_lastoffset =
1906 fptr->f_length;
1907 fptr->f_lastlength = 0;
1908 break;
1909
1910 case M_RANDOM:
1911 fptr->f_lastoffset =
1912 fptr->f_length / 2;
1913 fptr->f_lastlength = 0;
1914 break;
1915 }
1916
1917 Nfiles++;
1918 }
1919 }
1920
1921 optind++;
plars865695b2001-08-27 22:15:12 +00001922 }
plars865695b2001-08-27 22:15:12 +00001923
Wanlong Gao354ebb42012-12-07 10:10:04 +08001924 if (Nfiles == 0) {
1925 fprintf(stderr,
1926 "iogen%s: Could not create, or gather info for any test files\n",
1927 TagName);
1928 exit(2);
1929 }
plars865695b2001-08-27 22:15:12 +00001930 }
1931
Wanlong Gao354ebb42012-12-07 10:10:04 +08001932 return 0;
plars865695b2001-08-27 22:15:12 +00001933}
1934
Wanlong Gao354ebb42012-12-07 10:10:04 +08001935int help(FILE * stream)
plars865695b2001-08-27 22:15:12 +00001936{
Wanlong Gao354ebb42012-12-07 10:10:04 +08001937 usage(stream);
1938 fprintf(stream, "\n");
plars865695b2001-08-27 22:15:12 +00001939#ifndef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001940 fprintf(stream,
1941 "\t-a aio_type,... Async io completion types to choose. Supported types\n");
plars865695b2001-08-27 22:15:12 +00001942#ifdef CRAY
1943#if _UMK || RELEASE_LEVEL >= 8000
Wanlong Gao354ebb42012-12-07 10:10:04 +08001944 fprintf(stream,
1945 "\t are: poll, signal, recall, recalla, and recalls.\n");
plars865695b2001-08-27 22:15:12 +00001946#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001947 fprintf(stream,
1948 "\t are: poll, signal, recalla, and recalls.\n");
plars865695b2001-08-27 22:15:12 +00001949#endif
1950#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001951 fprintf(stream,
1952 "\t are: poll, signal, suspend, and callback.\n");
plars865695b2001-08-27 22:15:12 +00001953#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +08001954 fprintf(stream, "\t Default is all of the above.\n");
plars865695b2001-08-27 22:15:12 +00001955#else /* !linux */
Wanlong Gao354ebb42012-12-07 10:10:04 +08001956 fprintf(stream, "\t-a (Not used on Linux).\n");
plars865695b2001-08-27 22:15:12 +00001957#endif /* !linux */
Wanlong Gao354ebb42012-12-07 10:10:04 +08001958 fprintf(stream,
1959 "\t-f flag,... Flags to use for file IO. Supported flags are\n");
plars865695b2001-08-27 22:15:12 +00001960#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08001961 fprintf(stream,
1962 "\t raw, ssd, buffered, ldraw, sync,\n");
1963 fprintf(stream,
1964 "\t raw+wf, raw+wf+ldraw, raw+wf+ldraw+sync,\n");
1965 fprintf(stream,
1966 "\t and parallel (unicos/mk on MPP only).\n");
1967 fprintf(stream,
1968 "\t Default is 'raw,ldraw,sync,buffered'.\n");
plars865695b2001-08-27 22:15:12 +00001969#else
1970#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08001971 fprintf(stream,
1972 "\t buffered, direct, sync, dsync, rsync,\n");
1973 fprintf(stream, "\t rsync+dsync.\n");
1974 fprintf(stream,
1975 "\t Default is 'buffered,sync,dsync,rsync'.\n");
plars865695b2001-08-27 22:15:12 +00001976#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001977 fprintf(stream, "\t buffered, sync.\n");
1978 fprintf(stream, "\t Default is 'buffered,sync'.\n");
plars865695b2001-08-27 22:15:12 +00001979#endif /* sgi */
1980#endif /* CRAY */
Wanlong Gao354ebb42012-12-07 10:10:04 +08001981 fprintf(stream, "\t-h This help.\n");
1982 fprintf(stream,
1983 "\t-i iterations[s] # of requests to generate. 0 means causes iogen\n");
1984 fprintf(stream,
1985 "\t to run until it's killed. If iterations is suffixed\n");
1986 fprintf(stream,
1987 "\t with 's', then iterations is the number of seconds\n");
1988 fprintf(stream,
1989 "\t that iogen should run for. Default is '0'.\n");
plars865695b2001-08-27 22:15:12 +00001990#ifndef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08001991 fprintf(stream,
1992 "\t-L min:max listio nstrides / nrequests range\n");
plars865695b2001-08-27 22:15:12 +00001993#else
Wanlong Gao354ebb42012-12-07 10:10:04 +08001994 fprintf(stream, "\t-L (Not used on Linux).\n");
plars865695b2001-08-27 22:15:12 +00001995#endif /* !linux */
Wanlong Gao354ebb42012-12-07 10:10:04 +08001996 fprintf(stream,
1997 "\t-m offset-mode The mode by which iogen chooses the offset for\n");
1998 fprintf(stream,
1999 "\t consectutive transfers within a given file.\n");
2000 fprintf(stream,
2001 "\t Allowed values are 'random', 'sequential',\n");
2002 fprintf(stream, "\t and 'reverse'.\n");
2003 fprintf(stream, "\t sequential is the default.\n");
2004 fprintf(stream, "\t-N tagname Tag name, for Monster.\n");
2005 fprintf(stream,
2006 "\t-o Form overlapping consecutive requests.\n");
2007 fprintf(stream, "\t-O Open flags for creating files\n");
plars865695b2001-08-27 22:15:12 +00002008#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08002009 fprintf(stream,
2010 "\t {O_PLACE,O_BIG,etc}[:CBITS[:CBLKS]]\n");
plars865695b2001-08-27 22:15:12 +00002011#endif
2012#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08002013 fprintf(stream,
2014 "\t realtime:extsize - put file on real-time volume\n");
2015 fprintf(stream,
2016 "\t allocate - allocate space with F_ALLOCSP\n");
2017 fprintf(stream,
2018 "\t reserve - reserve space with F_RESVSP (default)\n");
2019 fprintf(stream,
2020 "\t noreserve - do not reserve with F_RESVSP\n");
2021 fprintf(stream,
2022 "\t direct - use O_DIRECT I/O to write to the file\n");
plars865695b2001-08-27 22:15:12 +00002023#endif
2024#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08002025 fprintf(stream, "\t {O_SYNC,etc}\n");
plars865695b2001-08-27 22:15:12 +00002026#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +08002027 fprintf(stream,
2028 "\t-p Output pipe. Default is stdout.\n");
2029 fprintf(stream,
2030 "\t-q Quiet mode. Normally iogen spits out info\n");
2031 fprintf(stream,
2032 "\t about test files, options, etc. before starting.\n");
2033 fprintf(stream,
2034 "\t-s syscall,... Syscalls to do. Supported syscalls are\n");
plars865695b2001-08-27 22:15:12 +00002035#ifdef sgi
Wanlong Gao354ebb42012-12-07 10:10:04 +08002036 fprintf(stream,
2037 "\t read, write, pread, pwrite, readv, writev\n");
2038 fprintf(stream,
2039 "\t aread, awrite, resvsp, unresvsp, ffsync,\n");
2040 fprintf(stream,
2041 "\t mmread, mmwrite, fsync2, fdatasync,\n");
2042 fprintf(stream,
2043 "\t Default is 'read,write,pread,pwrite,readv,writev,mmread,mmwrite'.\n");
plars865695b2001-08-27 22:15:12 +00002044#endif
2045#ifdef CRAY
Wanlong Gao354ebb42012-12-07 10:10:04 +08002046 fprintf(stream,
2047 "\t read, write, reada, writea, listio,\n");
2048 fprintf(stream,
2049 "\t ssread (PVP only), and sswrite (PVP only).\n");
2050 fprintf(stream,
2051 "\t Default is 'read,write,reada,writea,listio'.\n");
plars865695b2001-08-27 22:15:12 +00002052#endif
2053#ifdef linux
Wanlong Gao354ebb42012-12-07 10:10:04 +08002054 fprintf(stream, "\t read, write, readv, writev,\n");
2055 fprintf(stream,
2056 "\t mmread, mmwrite, fsync2, fdatasync,\n");
2057 fprintf(stream,
2058 "\t Default is 'read,write,readv,writev,mmread,mmwrite'.\n");
plars865695b2001-08-27 22:15:12 +00002059#endif
Wanlong Gao354ebb42012-12-07 10:10:04 +08002060 fprintf(stream, "\t-t mintrans Min transfer length\n");
2061 fprintf(stream, "\t-T maxtrans Max transfer length\n");
2062 fprintf(stream, "\n");
2063 fprintf(stream,
2064 "\t[len:]file,... Test files to do IO against (note ssread/sswrite\n");
2065 fprintf(stream,
2066 "\t don't need a test file). The len: syntax\n");
2067 fprintf(stream,
2068 "\t informs iogen to first create/expand/truncate the\n");
2069 fprintf(stream, "\t to the desired length.\n");
2070 fprintf(stream, "\n");
2071 fprintf(stream,
2072 "\tNote: The ssd flag causes sds transfers to also be done.\n");
2073 fprintf(stream,
2074 "\t To totally eliminate sds transfers, you must eleminate sds\n");
2075 fprintf(stream,
2076 "\t from the flags (-f) and ssread,ssrite from the syscalls (-s)\n");
2077 fprintf(stream,
2078 "\tThe mintrans, maxtrans, and len: parameters are numbers of the\n");
2079 fprintf(stream,
2080 "\tform [0-9]+[bkm]. The optional trailing b, k, or m multiplies\n");
2081 fprintf(stream,
2082 "\tthe number by blocks, kilobytes, or megabytes. If no trailing\n");
2083 fprintf(stream,
2084 "\tmultiplier is present, the number is interpreted as bytes\n");
plars865695b2001-08-27 22:15:12 +00002085
Wanlong Gao354ebb42012-12-07 10:10:04 +08002086 return 0;
plars865695b2001-08-27 22:15:12 +00002087}
2088
2089/*
2090 * Obvious - usage clause
2091 */
2092
Wanlong Gao354ebb42012-12-07 10:10:04 +08002093int usage(FILE * stream)
plars865695b2001-08-27 22:15:12 +00002094{
Wanlong Gao354ebb42012-12-07 10:10:04 +08002095 fprintf(stream,
2096 "usage%s: iogen [-hoq] [-a aio_type,...] [-f flag[,flag...]] [-i iterations] [-p outpipe] [-m offset-mode] [-s syscall[,syscall...]] [-t mintrans] [-T maxtrans] [ -O file-create-flags ] [[len:]file ...]\n",
2097 TagName);
2098 return 0;
Alex Elder6b572162011-04-01 17:01:27 -05002099}