2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
4 * 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.
8 * 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.
12 * 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.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
28 * For further information regarding this notice, see:
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
33 * This program will grow a list of files.
34 * Each file will grow by grow_incr before the same
35 * file grows twice. Each file is open and closed before next file is opened.
37 * To just verify file contents: growfiles -g 0 -c 1 filename
39 * See help and prt_examples functions below.
43 * print debug message about options used
44 * setup signal handlers
45 * return control to user (if wanted - default action)
46 * fork number of desired childern (if wanted)
47 * re-exec self (if wanted)
48 * Determine number of files
49 * malloc space or i/o buffer
50 * Loop until stop is set
51 * Determine if hit iteration, time, max errors or num bytes reached
52 * Loop through each file
54 * fstat file - to determine if file is a fifo
55 * prealloc file space (if wanted)
64 * remove all files (if wanted)
66 * Author: Richard Logan
77 #include <sys/types.h>
80 #include <sys/param.h>
81 #include <sys/signal.h>
84 #include "dataascii.h"
85 #include "random_range.h"
89 #include <xfs/libxfs.h>
93 #include <sys/panic.h>
94 #include <sys/category.h>
97 extern char *openflags2symbols();
99 extern int parse_open_flags();
100 extern int background();
102 extern int datapidgen();
103 extern void databingen();
104 extern int datapidchk();
105 extern int databinchk();
106 extern int file_lock();
121 static void notify_others();
127 #define NEWIO 1 /* Use the tlibio.c functions */
130 #define NEWIO 0 /* specifies to use original iowrite.c */
131 /* functions instead of tlibio.c functions */
132 /* Once it is proven tlibio.c functions work properly, */
133 /* only tlibio.c functions will be used */
139 #define PATH_MAX 1023
144 #define DEF_FILE "gf"
151 int io_type = 0; /* I/O type -sync */
152 int open_flags = O_RDWR|O_CREAT; /* open flags */
154 #define MAX_FC_READ 196608 /* 4096 * 48 - 48 blocks */
156 #define PATTERN_ASCII 1 /* repeating alphabet letter pattern */
157 /* allows multiple writers and to be checked */
158 #define PATTERN_PID 2 /* <pid><words byte offset><pid> */
159 /* Assumes 64 bit word. Only allows single */
160 /* process to write and check */
162 * 1234567890123456789012345678901234567890123456789012345678901234
163 * ________________________________________________________________
164 * < pid >< offset in file of this word >< pid >
167 #define PATTERN_OFFSET 3 /* Like PATTERN_PID but has a fixed number */
168 /* (STATIC_NUM) instead of pid. */
169 /* Allows multiple processes to write/read */
170 #define PATTERN_ALT 4 /* alternating bit pattern (i.e. 0x5555555...) */
171 #define PATTERN_CHKER 5 /* checkerboard pattern (i.e. 0xff00ff00ff00...) */
172 #define PATTERN_CNTING 6 /* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
173 #define PATTERN_ONES 7 /* all bits set (i.e. 0xffffffffffffff...) */
174 #define PATTERN_ZEROS 8 /* all bits cleared (i.e. 0x000000000...) */
175 #define PATTERN_RANDOM 9 /* random integers - can not be checked */
176 #define STATIC_NUM 221849 /* used instead of pid when PATTERN_OFFSET */
178 #define MODE_RAND_SIZE 1 /* random write and trunc */
179 #define MODE_RAND_LSEEK 2 /* random lseek before write */
180 #define MODE_GROW_BY_LSEEK 4 /* lseek beyond end of file then write a byte */
181 #define RANDOM_OPEN 999876 /* if Open_flags set to this value, open flags */
182 /* will be randomly choosen from Open_flags[] */
183 #define MODE_FIFO S_IFIFO /* defined in stat.h 0010000 */
185 int num_files = 0; /* num_auto_files + cmd line files */
186 char *filenames; /* pointer to space containing filenames */
187 int remove_files = 0; /* if set, cleanup default is not to cleanup */
188 int bytes_consumed = 0; /* total bytes consumed, all files */
189 int bytes_to_consume = 0; /* non-zero if -B was specified, total bytes */
190 int Maxerrs = 100; /* Max number errors before forced exit */
191 int Errors = 0; /* number of encountered errors */
192 int Upanic_on_error = 0; /* call upanic if error and this variable set */
194 /* The *_size variables are only used when random iosize option (-r) is used */
196 int min_size=1; /* also set in option parsing */
197 int mult_size=1; /* when random iosz, iosz must be mult of mult_size */
198 /* the *_lseek variables are only used when radon lseek option (-R) is used */
199 int min_lseek=0; /* also set in option parsing */
200 int max_lseek=-1; /* -1 means size of file */
202 int Pattern=PATTERN_OFFSET; /* This pattern is 64 bit word based */
204 int Pattern=PATTERN_ASCII;
206 int Seed=-1; /* random number seed, < 0 == uninitialized */
207 int Nseeds=0; /* Number of seed specified by the user */
208 int *Seeds; /* malloc'ed arrary of ints holding user spec seeds */
210 int using_random=0; /* flag indicating randomization is being used */
211 float delaysecs=0.0; /* delay between iterations (in seconds) */
212 int delaytime; /* delay between iterations in clocks/uses */
213 int lockfile=0; /* if set, do file locking */
214 /* 1 = do file locking around write, trunc */
216 /* 2 = write lock around all file operations */
218 int Woffset=0; /* offset before last write */
219 int Grow_incr=4096; /* sz of last write */
220 int Mode=0; /* bitmask of write/trunc mode */
221 /* also knows if dealing with fifo */
222 char *Buffer = NULL; /* buffer used by write and write check */
223 int Alignment=0; /* if non word multiple, io will not be word aligned */
224 int Opid=0; /* original pid */
226 int Sync_with_others = 0; /* Flag indicating to stop other if we stop before DONE */
227 int Iter_cnt = 0; /* contains current iteration count value */
228 char TagName[40]; /* name of this growfiles (see Monster) */
238 * Define open flags that will be used when '-o random' option is used.
239 * Note: If there is more than one growfiles doing its thing to the same
240 * file, O_TRUNC will cause data mismatches. How you ask?
241 * timing of events, example:
242 * Process one Process two
243 * --------------- -------------
249 * write with wrong pattern
250 * because offset is wrong
252 * The second process truncated the file after the pattern was
253 * determined, thus the pattern is wrong for the file location.
255 * There can also be a timing problem with open flag O_APPEND if
256 * file locks are not being used (-l option). Things could happen
257 * between the fstat and the write. Thus, writing the wrong pattern.
258 * If all processes observe the file locks, O_APPEND should be ok
264 O_RDWR|O_CREAT|O_RAW,
265 O_RDWR|O_CREAT|O_BIG,
266 O_RDWR|O_CREAT|O_APPEND,
267 O_RDWR|O_CREAT|O_NDELAY,
268 O_RDWR|O_CREAT|O_PLACE,
269 O_RDWR|O_CREAT|O_SYNC,
270 O_RDWR|O_CREAT|O_RAW|O_SYNC,
271 O_RDWR|O_CREAT|O_NDELAY|O_SYNC,
272 O_RDWR|O_CREAT|O_NDELAY|O_SYNC|O_BIG,
273 O_RDWR|O_CREAT|O_RAW,
274 O_RDWR|O_CREAT|O_RAW|O_APPEND,
275 O_RDWR|O_CREAT|O_RAW|O_BIG,
276 O_RDWR|O_CREAT|O_RAW|O_APPEND|O_BIG,
278 * O_WELLFORMED makes -o random require well formed i/o
280 #if ALLOW_O_WELLFORMED
282 O_RDWR|O_CREAT|O_PARALLEL|O_WELLFORMED|O_RAW,
283 O_RDWR|O_CREAT|O_PARALLEL|O_WELLFORMED|O_RAW|O_TRUNC,
284 #endif /* O_PARALLEL */
289 O_RDWR|O_CREAT|O_APPEND,
290 O_RDWR|O_CREAT|O_NDELAY,
291 O_RDWR|O_CREAT|O_SYNC,
292 O_RDWR|O_CREAT|O_SYNC|O_NDELAY,
293 O_RDWR|O_CREAT|O_APPEND|O_NDELAY,
298 #define REXEC_INIT 0 /* don't do re-exec of childern */
299 #define REXEC_DOIT 1 /* Do re-exec of childern */
300 #define REXEC_DONE 2 /* We've already been re-exec'ed */
310 #define USECS_PER_SEC 1000000 /* microseconds per second */
313 * Define marcos used when dealing with file locks.
315 #define LKLVL0 1 /* file lock around write/read/trunc */
316 #define LKLVL1 2 /* file lock after open to before close */
319 * Define special max lseek values
321 #define LSK_EOF -1 /* set fptr up to EOF */
322 #define LSK_EOFPLUSGROW -2 /* set fptr up to EOF + grow - leave whole */
323 #define LSK_EOFMINUSGROW -3 /* set fptr up to EOF-grow - no grow */
326 /***********************************************************************
328 ***********************************************************************/
334 extern char *optarg; /* used by getopt */
339 int first_file_ind = 0;
340 int num_auto_files = 0; /* files created by tool */
341 int seq_auto_files = 0; /* auto files created by tool created by tool */
342 char *auto_dir = DEF_DIR;
343 char *auto_file = DEF_FILE;
344 int grow_incr = 4096;
345 int trunc_incr = 4096;
346 int trunc_inter = 0; /* 0 means none, */
347 int unlink_inter = 0; /* 0 means none, 1 means always unlink */
348 int unlink_inter_ran = -1; /* -1 -use unlink_inter, otherwise randomly choose */
349 /* between unlink_inter and unlink_inter_ran */
350 int file_check_inter = 0; /* 0 means never, 1 means always */
351 int write_check_inter = 1; /* 0 means never, 1 means always */
352 int iterations = 1; /* number of increments to be added */
353 int no_file_check = 0; /* if set, no whole file checking will be done */
355 int fd; /* file descriptor */
356 int stop = 0; /* loop stopper if set */
360 int pre_alloc_space = 0;
362 int total_grow_value = 0; /* used in pre-allocations */
364 int backgrnd = 1; /* return control to user */
366 int time_iterval = -1;
367 time_t start_time = 0;
368 char reason[40]; /* reason for loop termination */
371 int reexec=REXEC_INIT; /* reexec info */
372 char *exec_path=NULL;
376 char *filename; /* name of file specified by user */
377 char *cptr; /* temp char pointer */
378 extern int Forker_npids; /* num of forked pid, defined in forker.c */
381 if ( argv[0][0] == '-' )
384 * Determine name of file used to invoke this program
386 if ((Progname=strrchr(argv[0], '/')) != NULL)
396 while ((ind=getopt(argc, argv,
397 "hB:C:c:bd:D:e:Ef:g:H:I:i:lL:n:N:O:o:pP:q:wt:r:R:s:S:T:uU:W:xy")) != EOF) {
405 switch (sscanf(optarg, "%i%c",
406 &bytes_to_consume, &chr)) {
412 bytes_to_consume *= BSIZE;
415 "%s%s: --B option arg invalid\n",
423 fprintf(stderr, "%s%s: --B option arg invalid\n",
433 prt_examples(stdout);
436 case 'b' : /* batch */
441 if (sscanf(optarg, "%i", &write_check_inter) != 1 ) {
442 fprintf(stderr, "%s%s: --c option arg invalid\n",
450 if (sscanf(optarg, "%i", &file_check_inter) != 1 ) {
451 fprintf(stderr, "%s%s: --c option arg invalid\n",
462 unsetenv("TMPDIR"); /* force the use of auto_dir */
464 if ( stat(auto_dir, &statbuf) == -1 ) {
465 if ( mkdir(auto_dir, 0777) == -1 ) {
466 if ( errno != EEXIST ) {
468 "%s%s: Unable to make dir %s\n",
469 Progname, TagName, auto_dir);
475 if ( ! (statbuf.st_mode & S_IFDIR) ) {
477 "%s%s: %s already exists and is not a directory\n",
478 Progname, TagName, auto_dir);
485 if (sscanf(optarg, "%i", &Debug) != 1 ) {
486 fprintf(stderr, "%s%s: --D option arg invalid\n",
494 if (sscanf(optarg, "%i", &Maxerrs) != 1 ) {
495 fprintf(stderr, "%s%s: --e option arg invalid\n",
507 if ((ret=sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1 ||
510 fprintf(stderr, "%s%s: --g option arg invalid\n",
516 if ( chr == 'b' || chr == 'B' )
520 "%s%s: --g option arg invalid\n",
529 if (sscanf(optarg, "%f", &delaysecs) != 1 || delaysecs < 0 ) {
531 fprintf(stderr, "%s%s: --H option arg invalid\n",
539 if (sscanf(optarg, "%i", &iterations) != 1 ||
542 fprintf(stderr, "%s%s: --i option arg invalid\n",
551 if((io_type=lio_parse_io_arg1(optarg)) == -1 ) {
553 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
557 if( io_type & LIO_RANDOM )
560 if((io_type=parse_io_arg(optarg)) == -1 ) {
562 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
566 if( io_type == 99 ) /* hold-over until tlibio.h */
574 lockfile=2; /* lockfile can only be 1 or 2 */
578 if (sscanf(optarg, "%i", &time_iterval) != 1 ||
580 fprintf(stderr, "%s%s: --L option arg invalid\n",
588 if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) < 1 ||
591 fprintf(stderr, "%s%s: --n option arg invalid\n",
600 if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
601 num_auto_files < 0 ) {
603 fprintf(stderr, "%s%s: --N option arg invalid\n",
611 if (sscanf(optarg, "%i", &Alignment) != 1 ||
612 num_auto_files < 0 ) {
614 fprintf(stderr, "%s%s: --O option arg invalid\n",
622 if ( strcmp(optarg, "random") == 0 ){
623 open_flags=RANDOM_OPEN;
626 } else if ((open_flags=parse_open_flags(optarg, NULL)) == -1 ) {
627 fprintf(stderr, "%s%s: --o arg contains invalid flag\n",
634 case 'p' : /* pre allocate space */
636 printf("%s%s: --p is illegal option on this system\n",
646 if (strcmp(optarg, "PANIC") != 0 ) {
647 fprintf(stderr, "%s%s: --P arg must be PANIC\n", Progname, TagName);
651 printf("%s: Will call upanic after writes\n");
653 printf("%s%s: --P is illegal option on non-cray system\n",
659 case 'q': /* file content or pattern */
662 Pattern = PATTERN_ALT;
665 Pattern = PATTERN_ASCII;
668 Pattern = PATTERN_PID;
671 Pattern = PATTERN_OFFSET;
674 Pattern = PATTERN_CHKER;
677 Pattern = PATTERN_CNTING;
680 Pattern = PATTERN_RANDOM;
684 Pattern = PATTERN_ZEROS;
687 Pattern = PATTERN_ONES;
691 "%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
698 case 'R': /* random lseek before write arg: [min-]max*/
699 if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) != 2 ) {
700 min_lseek=1; /* same as default in define */
701 if (sscanf(optarg, "%i%c", &max_lseek, &chr) != 1 ) {
702 fprintf(stderr, "%s%s: --R option arg invalid: [min-]max\n",
707 if ( max_lseek < LSK_EOFMINUSGROW ) {
708 fprintf(stderr, "%s%s: --R option, max_lseek is invalid\n",
712 Mode |= MODE_RAND_LSEEK;
716 case 'r': /* random io size arg: [min-]max[:mult] */
718 /* min-max:mult format */
719 if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
720 &mult_size, &chr) != 3 ) {
722 /* max:mult format */
723 if (sscanf(optarg, "%i:%i%c", &max_size,
724 &mult_size, &chr) != 2 ) {
726 if (sscanf(optarg, "%i-%i%c", &min_size,
727 &max_size, &chr) != 2 ) {
729 if (sscanf(optarg, "%i%c", &max_size, &chr) != 1 ) {
731 "%s%s: --r option arg invalid: [min-]max[:mult]\n",
739 if ( max_size < 0 ) {
740 fprintf(stderr, "%s%s: --r option, max_size is invalid\n",
745 * If min and max are the same, no randomness
747 if ( min_size != max_size ) {
748 Mode |= MODE_RAND_SIZE;
754 if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
755 seq_auto_files < 0 ) {
757 fprintf(stderr, "%s%s: --S option arg invalid\n",
764 case 's': /* format: seed[,seed...] */
766 /* count the number of seeds */
768 for(Nseeds=1; *cptr ; Nseeds++) {
769 if ( (filename=strchr(cptr, ',')) == NULL )
774 Seeds=(int *)malloc(Nseeds*sizeof(int));
777 * check that each seed is valid and put them in
778 * the newly malloc'ed Seeds arrary.
780 filename=cptr=optarg;
781 for(Nseeds=0; *cptr; Nseeds++) {
782 if ( (filename=strchr(cptr, ',')) == NULL ) {
783 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
784 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
785 Progname, TagName, cptr);
794 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
795 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
796 Progname, TagName, cptr);
800 *filename=','; /* restore string */
807 if ((ret=sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1 ||
810 fprintf(stderr, "%s%s: --t option arg invalid\n",
816 if ( chr == 'b' || chr == 'B' )
820 "%s%s: --t option arg invalid\n",
828 case 'T': /* truncate interval */
829 if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
832 fprintf(stderr, "%s%s: --T option arg invalid\n",
843 case 'U': /* how often to unlink file */
846 * A-B - randomly pick interval between A and B
847 * X - unlink file every X iteration
849 if (sscanf(optarg, "%i-%i", &unlink_inter,
850 &unlink_inter_ran) == 2 ) {
852 if ( unlink_inter < 0 || unlink_inter_ran < 0 ) {
853 fprintf(stderr, "%s%s: --U option arg invalid\n",
858 /* ensure unlink_inter contains smaller value */
859 if ( unlink_inter > unlink_inter_ran ) {
860 tmp=unlink_inter_ran;
861 unlink_inter_ran=unlink_inter;
866 } else if (sscanf(optarg, "%i%c", &unlink_inter, &chr) != 1 ||
869 fprintf(stderr, "%s%s: --U option arg invalid\n",
877 if ( reexec != REXEC_DONE )
882 Mode |= MODE_GROW_BY_LSEEK;
886 sprintf( TagName, "(%.39s)", optarg );
901 cptr = getenv("TOUTPUT");
902 if( (cptr != NULL) && (strcmp( cptr, "NOPASS" ) == 0) ){
907 if ( Pattern == PATTERN_RANDOM ) {
909 if ( write_check_inter || file_check_inter )
910 printf("%s%s: %d Using random pattern - no data checking will be performed!\n",
911 Progname, TagName, getpid());
913 else if ( max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK ) {
916 if ( file_check_inter )
917 printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
918 no whole file checking will be performed!\n", Progname, TagName, getpid());
922 if ( Mode & MODE_RAND_SIZE )
932 printf("%s: %d DEBUG2 forking, returning control to the user\n",
934 background(Progname); /* give user their prompt back */
938 if ( Sync_with_others )
944 lio_set_debug(Debug-3);
946 set_iowrite_debug(Debug-3);
951 * Print some program information here if debug is turned on to
957 if ( Mode & MODE_GROW_BY_LSEEK )
958 printf("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
960 else if ( Pattern == PATTERN_OFFSET )
961 printf("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
962 Progname, Pid, STATIC_NUM, STATIC_NUM);
963 else if ( Pattern == PATTERN_PID )
964 printf("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
966 else if ( Pattern == PATTERN_ASCII )
967 printf("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
969 else if ( Pattern == PATTERN_ALT )
970 printf("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
972 else if ( Pattern == PATTERN_CHKER )
973 printf("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
975 else if ( Pattern == PATTERN_CNTING )
976 printf("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
978 else if ( Pattern == PATTERN_RANDOM )
979 printf("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
981 else if ( Pattern == PATTERN_ONES )
982 printf("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
984 else if ( Pattern == PATTERN_ZEROS )
985 printf("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
989 printf("%s: %d DEBUG3 unknown pattern\n",
991 if ( bytes_to_consume )
992 printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
993 Progname, Pid, bytes_to_consume);
994 printf("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n",
995 Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
997 printf("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
998 Progname, Pid, Debug, remove_files);
1000 printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
1002 if ( open_flags == RANDOM_OPEN )
1003 printf("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n", Progname,
1006 printf("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n", Progname,
1007 Pid, open_flags, io_type);
1009 if ( Mode & MODE_RAND_SIZE ) {
1010 printf("%s: %d DEBUG3 random write/trunc: min=%d, max=%d, mult = %d\n",
1011 Progname, Pid, min_size, max_size, mult_size);
1014 printf("%s: %d DEBUG3 grow_incr = %d\n",
1015 Progname, Pid, grow_incr);
1017 if ( Mode & MODE_RAND_LSEEK ) {
1018 if ( max_lseek == LSK_EOF )
1019 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile>\n",
1020 Progname, Pid, min_lseek);
1021 else if ( max_lseek == LSK_EOFPLUSGROW )
1022 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile+iosize>\n",
1023 Progname, Pid, min_lseek);
1024 else if ( max_lseek == LSK_EOFMINUSGROW )
1025 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile-iosize>\n",
1026 Progname, Pid, min_lseek);
1028 printf("%s: %d DEBUG3 random lseek: min=%d, max=%d\n",
1029 Progname, Pid, min_lseek, max_lseek);
1032 printf("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
1033 Progname, Pid, write_check_inter, file_check_inter);
1035 printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
1036 Progname, Pid, trunc_inter, trunc_incr);
1038 if ( no_file_check )
1039 printf("%s: %d DEBUG3 no whole file checking will be done\n",
1042 if ( unlink_inter_ran == -1 ) {
1043 printf("%s: %d DEBUG3 unlink_inter = %d\n",
1044 Progname, Pid, unlink_inter);
1046 printf("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n",
1047 Progname, Pid, unlink_inter, unlink_inter_ran);
1051 num=sizeof(Open_flags)/sizeof(int);
1052 printf("%s: %d DEBUG9 random open flags values:\n", Progname, Pid);
1053 for(ind=0; ind<num; ind++) {
1054 printf("\t%#o\n", Open_flags[ind]);
1057 } /* end of DEBUG > 2 */
1059 if ( Debug > 1 && num_procs > 1 ) {
1060 printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
1064 fflush(stdout); /* ensure pending i/o is flushed before forking */
1067 forker(num_procs, forker_mode, Progname);
1069 Pid=getpid(); /* reset after the forks */
1071 * If user specified random seed(s), get that random seed value.
1072 * get random seed if it was not specified by the user.
1073 * This is done after the forks, because pid is used to get the seed.
1075 if ( Nseeds == 1 ) {
1077 * If only one seed specified, all processes will get that seed.
1080 } else if ( Nseeds > 1 ) {
1082 * More than one seed was specified.
1083 * The original process gets the first seed. Each
1084 * process will be get the next seed in the specified list.
1086 if ( Opid == Pid ) {
1090 * If user didn't specify enough seeds, use default method.
1092 if ( Forker_npids >= Nseeds )
1093 Seed=time(0) + Pid; /* default random seed */
1095 Seed=Seeds[Forker_npids];
1100 * Generate a random seed based on time and pid.
1101 * It has a good chance of being unique for each pid.
1103 Seed=time(0) + Pid; /* default random seed */
1106 random_range_seed(Seed);
1108 if ( using_random && Debug > 0 )
1109 printf("%s%s: %d DEBUG1 Using random seed of %d\n",
1110 Progname, TagName, Pid, Seed);
1112 if ( unlink_inter_ran > 0 ) {
1114 * Find unlinking file interval. This must be done after
1115 * the seed was set. This allows multiple copies to
1116 * get different intervals.
1119 unlink_inter=random_range(tmp, unlink_inter_ran, 1, NULL);
1122 printf("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
1123 Progname, Pid, unlink_inter, tmp, unlink_inter_ran);
1127 * re-exec all childern if reexec is set to REXEC_DOIT.
1128 * This is useful on MPP systems to get the
1129 * child process on another PE.
1131 if ( reexec == REXEC_DOIT && Opid != Pid ) {
1132 if ( exec_path == NULL ) {
1133 exec_path = argv[0];
1134 /* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
1135 argv[0] = (char *)malloc(strlen(exec_path) + 2);
1136 sprintf(argv[0], "-%s", exec_path);
1140 printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
1141 Progname, Pid, __FILE__, __LINE__, argv[0]);
1143 execvp(argv[0], argv);
1146 /*** begin filename stuff here *****/
1148 * Determine the number of files to be dealt with
1150 if ( optind == argc ) {
1152 * no cmd line files, therfore, set
1153 * the default number of auto created files
1155 if ( ! num_auto_files && ! seq_auto_files )
1159 first_file_ind=optind;
1160 num_files += argc-optind;
1163 if ( num_auto_files ) {
1164 num_files += num_auto_files;
1167 if ( seq_auto_files ) {
1168 num_files += seq_auto_files;
1172 * get space for file names
1174 if ((filenames=(char *)malloc(num_files*PATH_MAX)) == NULL) {
1175 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1176 Progname, TagName, Pid, __FILE__, __LINE__, num_files*PATH_MAX,
1182 * fill in filename cmd files then auto files.
1186 if ( first_file_ind ) {
1187 for(ind=first_file_ind; ind<argc; ind++, num++) {
1188 strcpy((char *)filenames+(num*PATH_MAX), argv[ind]);
1193 * construct auto filename and insert them into filenames space
1196 for(ind=0;ind<num_auto_files; ind++, num++) {
1197 sprintf((char *)filenames+(num*PATH_MAX), "%s.%d",
1198 tempnam(auto_dir, auto_file), ind );
1202 * construct auto seq filenames
1204 for(ind=1; ind<=seq_auto_files; ind++, num++) {
1205 sprintf((char *)filenames+(num*PATH_MAX), "%s/%s%d",
1206 auto_dir, auto_file, ind);
1209 /**** end filename stuff ****/
1211 if ( time_iterval > 0 )
1215 * get space for I/O buffer
1218 if ((Buffer=(char *)malloc(grow_incr+Alignment)) == NULL) {
1219 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1220 Progname, TagName, Pid, __FILE__, __LINE__, grow_incr, strerror(errno));
1224 Buffer = Buffer + Alignment;
1229 printf("%s: %d DEBUG3 num_files = %d\n",
1230 Progname, Pid, num_files);
1234 if ( pre_alloc_space ) {
1235 if ( iterations == 0 ) {
1236 fprintf(stderr, "%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
1237 Progname, TagName, Pid, __FILE__, __LINE__);
1240 if ( Mode & MODE_RAND_SIZE ) {
1242 "%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
1243 Progname, TagName, Pid, __FILE__, __LINE__);
1247 total_grow_value=grow_incr * iterations;
1252 if ( bytes_to_consume && bytes_to_consume < total_grow_value ) {
1253 total_grow_value=bytes_to_consume;
1259 * If delaying between iterations, get amount time to
1260 * delaysecs in clocks or usecs.
1261 * If on the CRAY, delaytime is in clocks since
1262 * _rtc() will be used, which does not have the overhead
1263 * of gettimeofday(2).
1268 hz=sysconf(_SC_CLK_TCK);
1269 delaytime=(int)((float)hz * delaysecs);
1271 delaytime=(int)((float)USECS_PER_SEC * delaysecs);
1276 * This is the main iteration loop.
1277 * Each iteration, all files can be opened, written to,
1278 * read to check the write, check the whole file,
1279 * truncated, and closed.
1281 for(Iter_cnt=1; ! stop ; Iter_cnt++) {
1283 if ( iterations && Iter_cnt >= iterations+1 ) {
1284 strcpy(reason, "Hit iteration value");
1289 if ( (time_iterval > 0) && (start_time + time_iterval < time(0)) ) {
1290 sprintf(reason, "Hit time value of %d", time_iterval);
1295 if ( bytes_to_consume && bytes_consumed >= bytes_to_consume) {
1296 sprintf(reason, "Hit bytes consumed value of %d", bytes_to_consume);
1302 * This loop will loop through all files.
1303 * Each iteration, a single file can be opened, written to,
1304 * read to check the write, check the whole file,
1305 * truncated, and closed.
1307 for(ind=0; ind<num_files; ind++) {
1312 filename=(char *)filenames+(ind*PATH_MAX);
1313 Fileinfo.filename=(char *)filenames+(ind*PATH_MAX);
1316 if ( open_flags == RANDOM_OPEN ) {
1317 ret=Open_flags[random_range(0, sizeof(Open_flags)/sizeof(int)-1, 1, NULL)];
1323 Fileinfo.openflags=ret;
1326 printf("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
1327 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret,
1328 openflags2symbols(ret, ",", NULL));
1329 } else if ( Debug > 2 ) {
1330 printf("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
1331 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret);
1335 * open file with desired flags.
1337 if ( (fd=open(filename, ret, 0777)) == -1 ) {
1339 "%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
1340 Progname, TagName, Pid, __FILE__, __LINE__, filename, ret, errno, strerror(errno));
1347 lkfile(fd, LOCK_EX, LKLVL1); /* lock if lockfile is LKLVL1 */
1351 * preallocation is only done once, if specified.
1353 if ( pre_alloc_space ) {
1354 if (pre_alloc(filename, fd, total_grow_value) != 0 ) {
1359 printf("%s: %d DEBUG2 %s/%d: pre_allocated %d for file %s\n",
1360 Progname, Pid, __FILE__, __LINE__, total_grow_value, filename);
1362 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1364 Iter_cnt=0; /* reset outside loop to restart from one */
1370 * grow file by desired amount.
1371 * growfile() will set the Grow_incr variable and
1372 * possiblly update the Mode variable indicating
1373 * if we are dealing with a FIFO file.
1376 if (growfile(fd, filename, grow_incr, Buffer) != 0 ) {
1378 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1384 * check if last write is not corrupted
1386 if ( check_write(fd, write_check_inter, filename,
1392 * Check that whole file is not corrupted.
1394 if ( check_file(fd, file_check_inter, filename,
1395 no_file_check) != 0 ) {
1400 * shrink file by desired amount if it is time
1403 if ( shrinkfile(fd, filename, trunc_incr, trunc_inter, Mode) != 0 ) {
1407 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1410 printf("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n",
1411 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, fd);
1415 * Unlink the file if that is desired
1417 if ( unlink_inter && (Iter_cnt % unlink_inter == 0) ) {
1420 printf("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n",
1421 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename);
1427 * delay while staying active for "delaysecs" seconds.
1435 while ( ct < end ) {
1439 struct timeval curtime;
1440 gettimeofday(&curtime, NULL);
1441 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1443 while ( ct < end ) {
1445 gettimeofday(&curtime, NULL);
1446 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1453 * if Iter_cnt == 0, then we pre allocated space to all files
1454 * and we are starting outside loop over. Set pre_alloc_space
1455 * to zero otherwise we get in infinite loop
1457 if ( Iter_cnt == 0 ) {
1463 } /* end iteration for loop */
1467 printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
1468 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, num_files, reason);
1477 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1478 Progname, TagName, Pid, Errors);
1479 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1484 printf("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n", Progname, TagName, Pid, __FILE__, __LINE__);
1488 /***********************************************************************
1490 ***********************************************************************/
1498 * now loop through all signals and set the handlers
1501 for (sig = 1; sig < NSIG; sig++) {
1512 #endif /* SIGCKPT */
1515 #endif /* SIGRESTART */
1521 sigset( sig, sig_handler );
1523 /* linux and cray */
1524 signal(sig, sig_handler);
1534 /***********************************************************************
1536 ***********************************************************************/
1543 if ( sig == SIGUSR2 ) {
1544 fprintf(stdout, "%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
1545 Progname, TagName, Pid, __FILE__, __LINE__, sig);
1547 signal(sig, sig_handler); /* allow us to get this signal more than once */
1550 } else if( sig == SIGINT ){
1551 /* The user has told us to cleanup, don't pretend it's an error. */
1554 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1555 Pid, __FILE__, __LINE__, sig);
1558 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1559 Pid, __FILE__, __LINE__, sig);
1565 printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
1566 Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
1571 /***********************************************************************
1572 * this function attempts to send SIGUSR2 to other growfiles processes
1573 * telling them to stop.
1575 ***********************************************************************/
1579 static int send_signals = 0;
1581 extern int Forker_pids[];
1582 extern int Forker_npids;
1584 if ( Sync_with_others && send_signals == 0 ) {
1587 send_signals=1; /* only send signals once */
1589 printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pgrp\n",
1590 Progname, TagName, Pid, __FILE__, __LINE__);
1591 killm(C_PGRP, getpgrp(), SIGUSR2);
1593 send_signals=1; /* only send signals once */
1595 for (ind=0; ind< Forker_npids; ind++) {
1596 if ( Forker_pids[ind] != Pid )
1598 printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
1599 Progname, TagName, Pid, __FILE__, __LINE__, Forker_pids[ind]);
1600 kill(Forker_pids[ind], SIGUSR2);
1607 /***********************************************************************
1608 * this function will count the number of errors encountered.
1609 * This function will call upanic if wanted or cleanup and
1610 * and exit is Maxerrs were encountered.
1611 ***********************************************************************/
1618 if ( Errors & Upanic_on_error ) {
1623 if ( Maxerrs && Errors >= Maxerrs ) {
1624 printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n",
1625 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, Maxerrs);
1630 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1631 Progname, TagName, Pid, Errors);
1632 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1641 /***********************************************************************
1643 ***********************************************************************/
1649 if ( remove_files ) {
1651 printf("%s: %d DEBUG3 Removing all %d files\n",
1652 Progname, Pid, num_files);
1653 for(ind=0; ind<=num_files; ind++) {
1654 unlink(filenames+(ind*PATH_MAX));
1657 if ( using_random && Debug > 1 )
1658 printf("%s%s: %d DEBUG2 Used random seed: %d\n",
1659 Progname, TagName, Pid, Seed);
1663 /***********************************************************************
1665 ***********************************************************************/
1670 "Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
1671 Progname, TagName );
1673 "[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
1675 "[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
1677 "[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
1681 } /* end of usage */
1683 /***********************************************************************
1685 ***********************************************************************/
1692 -h Specfied to print this help and exit.\n\
1693 -b Specfied to execute in sync mode.(def async mode)\n\
1694 -B maxbytes Max bytes to consume by all files. growfiles exits when more\n\
1695 than maxbytes have been consumed. (def no chk) If maxbytes ends\n\
1696 with the letter 'b', maxbytes is multiplied by BSIZE\n\
1697 -C write_chk Specifies how often to check the last write (default 1)\n\
1698 -c file_chk Specifies how often to check whole file (default 0)\n\
1699 -d auto_dir Specifies the directory to auto created files. (default .)\n\
1700 -D debug_lvl Specifies the debug level (default 1)\n\
1701 -E Print examples and exit\n\
1702 -e errs The number errors that will terminate this program (def 100)\n\
1703 -f auto_file Specifies the base filename files created. (default \"gf\")\n\
1704 -g grow_incr Specfied to grow by incr for each num. (default 4096)\n\
1705 grow_incr may end in b for blocks\n\
1706 If -r option is used, this option is ignored and size is random\n\
1707 -H delay Amount of time to delay between each file (default 0.0)\n\
1708 -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
1709 l - listio sync, L - listio async, r - random\n\
1710 -i iteration Specfied to grow each file num times. 0 means forever (default 1)\n\
1711 -l Specfied to do file locking around write/read/trunc\n\
1712 If specified twice, file locking after open to just before close\n\
1713 -L time Specfied to exit after time secs, must be used with -i.\n\
1714 -N num_files Specifies the number of files to be created.\n\
1715 The default is zero if cmd line files.\n\
1716 The default is one if no cmd line files.\n\
1717 -n num_procs Specifies the number of copies of this cmd.\n\
1718 -o op_type Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
1719 -O offset adjust i/o buffer alignment by offset bytes\n\
1720 -P PANIC Specifies to call upanic on error.\n\
1721 -p Specifies to pre-allocate space\n\
1722 -q pattern pattern can be a - ascii, p - pid with boff, o boff (def)\n\
1723 A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
1724 c - checkboard, C - counting\n\
1725 -R [min-]max random lseek before write and trunc, max of -1 means filesz,\n\
1726 -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
1727 -r [min-]max random io write size (min def is 1)\n\
1728 -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
1729 -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
1730 -t trunc_incr Specfied the amount to shrink file. (default 4096)\n\
1731 trunc_inter may end in b for blocks\n\
1732 If -R option is used, this option is ignored and trunc is random\n\
1733 -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
1734 -u unlink files before exit\n\
1735 -U ui[-ui2] Unlink files each ui iteration (def 0)\n\
1736 -w Specfied to grow via lseek instead of writes.\n\
1737 -W tag-name Who-am-i. My Monster tag name. (used by Monster).\n\
1738 -x Re-exec children before continuing - useful on MPP systems\n\
1739 -y Attempt to sync copies - if one fails it will send sigusr2 to others\n\
1740 Action to each file every iteration is open, write, write check\n\
1741 file check, trunc and closed.\n");
1746 /***********************************************************************
1748 ***********************************************************************/
1750 prt_examples(FILE *stream)
1752 /* This example creates 200 files in directory dir1. It writes */
1753 /* 4090 bytes 100 times then truncates 408990 bytes off the file */
1754 /* The file contents are checked every 1000 grow. */
1756 "# run forever: writes of 4090 bytes then on every 100 iterval\n\
1757 # truncate file by 408990 bytes. Done to 200 files in dir1.\n\
1758 %s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n", Progname);
1760 /* same as above with 5000 byte grow and a 499990 byte tuncate */
1762 "# same as above with writes of 5000 bytes and truncs of 499990\n\
1763 %s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n", Progname);
1765 /* This example beats on opens and closes */
1767 "# runs forever: beats on opens and closes of file ocfile - no io\n\
1768 %s -i 0 -g 0 -c 0 -C 0 ocfile\n\n", Progname);
1771 "# writes 4096 to files until 50 blocks are written\n\
1772 %s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
1775 "# write one byte to 750 files in gdir then unlinks them\n\
1776 %s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
1779 "# run 30 secs: random iosize, random lseek up to eof\n\
1780 %s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
1783 "# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
1784 %s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10 g_sleek1 g_lseek2\n\n", Progname);
1787 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1788 # rand io types doing a trunc every 5 iterations, with unlinks.\n\
1789 %s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n",
1793 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1794 # random open flags, rand io types doing a trunc every 10 iterations.\n\
1795 %s -i0 -r 1-50000 -R 0--2 -o random -I r -C0 -l -T 20 -uU100-200 -n 5 gf_rand1 gf_rand2\n",
1802 /***********************************************************************
1804 * The file descriptor current offset is assumed to be the end of the
1806 * Woffset will be set to the offset before the write.
1807 * Grow_incr will be set to the size of the write or lseek write.
1808 ***********************************************************************/
1810 growfile(fd, file, grow_incr, buf)
1820 int fsize; /* current size of file */
1821 int size_grew; /* size the file grew */
1826 * Do a stat on the open file.
1827 * If the file is a fifo, set the bit in Mode variable.
1828 * This fifo check must be done prior to growfile() returning.
1829 * Also get the current size of the file.
1831 if ( fstat(fd, &stbuf) != -1 ) {
1832 if ( S_ISFIFO(stbuf.st_mode) ) {
1833 Fileinfo.mode |= MODE_FIFO;
1836 printf("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
1837 Progname, Pid, __FILE__, __LINE__);
1839 fsize = stbuf.st_size;
1842 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1843 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1849 if ( grow_incr <= 0 ) { /* don't attempt i/o if grow_incr <= 0 */
1851 Grow_incr=grow_incr;
1853 printf("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
1854 Progname, Pid, __FILE__, __LINE__, grow_incr);
1858 if ( Mode & MODE_RAND_SIZE ) {
1859 grow_incr=random_range(min_size, max_size, mult_size, &errmsg);
1860 if (errmsg != NULL) {
1861 fprintf(stderr, "%s%s: %d %s/%d: random_range() failed - %s\n", Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
1864 Grow_incr=grow_incr;
1867 Grow_incr=grow_incr;
1869 if ( ! (Mode & MODE_FIFO) ) {
1870 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
1871 fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
1872 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1877 if ( Mode & MODE_GROW_BY_LSEEK ) {
1880 printf("%s: %d DEBUG3 %s/%d: Current size of file is %d\n", Progname,
1881 Pid, __FILE__, __LINE__, Woffset);
1882 printf("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n", Progname,
1883 Pid, __FILE__, __LINE__, grow_incr-1);
1886 if ((noffset=lseek(fd, grow_incr-1, SEEK_END)) == -1 ) {
1887 fprintf(stderr, "%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
1888 Progname, TagName, __FILE__, __LINE__, grow_incr-1, strerror(errno));
1892 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1895 ret=lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg,0);
1897 ret=write_buffer(fd, io_type, "w", 1, 0, &errmsg);
1901 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
1902 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
1903 if ( ret == -ENOSPC ) {
1912 lkfile(fd, LOCK_UN, LKLVL0);
1915 printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
1916 Progname, Pid, __FILE__, __LINE__, Iter_cnt);
1918 } else { /* end of grow by lseek */
1920 if ( Fileinfo.openflags & O_APPEND ) {
1922 * Deal with special case of the open flag containing O_APPEND.
1923 * If it does, the current offset does not matter since the write
1924 * will be done end of the file.
1927 printf("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
1928 Progname, Pid, __FILE__, __LINE__ );
1929 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1932 * do fstat again to get size of the file.
1933 * This is done inside a file lock (if locks are being used).
1935 if ( fstat(fd, &stbuf) != -1 ) {
1936 Woffset = stbuf.st_size;
1938 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1939 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1941 lkfile(fd, LOCK_UN, LKLVL0); /* release lock */
1945 printf("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
1946 Progname, Pid, __FILE__, __LINE__, (int)stbuf.st_size);
1949 } else if ( Mode & MODE_RAND_LSEEK ) {
1950 if ( max_lseek == LSK_EOF ) { /* within file size */
1951 noffset=random_range(min_lseek, fsize, 1, NULL);
1953 else if ( max_lseek == LSK_EOFPLUSGROW ) {
1954 /* max to beyond file size */
1955 noffset=random_range(min_lseek, fsize+grow_incr, 1, NULL);
1957 else if ( max_lseek == LSK_EOFMINUSGROW ) {
1959 * Attempt to not grow the file.
1960 * If the i/o will fit from min_lseek to EOF,
1961 * pick offset to allow it to fit.
1962 * Otherwise, pick the min_lseek offset and grow
1963 * file by smallest amount.
1964 * If min_lseek is != 0, there will be a problem
1965 * with whole file checking if file is ever smaller
1968 if ( fsize <= min_lseek + grow_incr )
1969 noffset=min_lseek; /* file will still grow */
1971 noffset=random_range(min_lseek, fsize-grow_incr, 1, NULL);
1974 noffset=random_range(min_lseek, max_lseek, 1, NULL);
1977 if ((Woffset=lseek(fd, noffset, SEEK_SET)) == -1 ) {
1978 fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l2 failed: %s\n",
1979 Progname, TagName, Pid, __FILE__, __LINE__, fd, noffset, strerror(errno));
1982 else if ( Debug > 2 )
1983 printf("%s: %d DEBUG3 %s/%d: lseeked to random offset %d (fsz:%d)\n",
1984 Progname, Pid, __FILE__, __LINE__, Woffset,
1985 (int)stbuf.st_size);
1990 * lseek to end of file only if not fifo
1992 else if ( ! (Mode & MODE_FIFO) ) {
1993 if ((Woffset=lseek(fd, 0, SEEK_END)) == -1 ) {
1994 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
1995 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1998 else if ( Debug > 2 )
1999 printf("%s: %d DEBUG3 %s/%d: lseeked to end of file, offset %d\n",
2000 Progname, Pid, __FILE__, __LINE__, Woffset);
2003 if ( Pattern == PATTERN_OFFSET )
2004 datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
2005 else if ( Pattern == PATTERN_PID )
2006 datapidgen(Pid, buf, grow_incr, Woffset);
2007 else if ( Pattern == PATTERN_ASCII )
2008 dataasciigen(NULL, buf, grow_incr, Woffset);
2009 else if ( Pattern == PATTERN_RANDOM )
2010 databingen('r', buf, grow_incr, Woffset);
2011 else if ( Pattern == PATTERN_ALT )
2012 databingen('a', buf, grow_incr, Woffset);
2013 else if ( Pattern == PATTERN_CHKER )
2014 databingen('c', buf, grow_incr, Woffset);
2015 else if ( Pattern == PATTERN_CNTING )
2016 databingen('C', buf, grow_incr, Woffset);
2017 else if ( Pattern == PATTERN_ZEROS )
2018 databingen('z', buf, grow_incr, Woffset);
2019 else if ( Pattern == PATTERN_ONES )
2020 databingen('o', buf, grow_incr, Woffset);
2022 dataasciigen(NULL, buf, grow_incr, Woffset);
2025 printf("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
2026 Progname, Pid, __FILE__, __LINE__, grow_incr);
2028 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
2031 ret=write(fd, buf, grow_incr);
2035 lkfile(fd, LOCK_UN, LKLVL0);
2037 if ( ret != grow_incr) {
2038 fprintf(stderr, "%s: %s/%d: write failed: %s\n",
2039 Progname, __FILE__, __LINE__, strerror(errno));
2045 ret=lio_write_buffer(fd, io_type, buf, grow_incr,
2046 SIGUSR1, &errmsg,0);
2048 ret=write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
2051 if( Mode & MODE_FIFO ){
2052 /* If it is a fifo then just pretend the file
2053 * offset is where we think it should be.
2055 tmp = Woffset + grow_incr;
2058 if( (tmp=lseek(fd,0,SEEK_CUR)) < 0 ){ /* get offset after the write */
2059 fprintf(stderr, "%s%s: %s/%d: tell(2) failed: %d %s\n",
2060 Progname, TagName, __FILE__, __LINE__, errno, strerror(errno) );
2065 /* If this is POSIX I/O and it is via aio_{read,write}
2066 * or lio_listio then after completion of the I/O the
2067 * value of the file offset for the file is
2068 * unspecified--which means we cannot trust what
2069 * tell() told us. Fudge it here.
2071 if( (io_type & LIO_IO_ASYNC_TYPES) || (io_type & LIO_RANDOM) ){
2072 if( tmp != Woffset + grow_incr ){
2074 printf("%s: %d DEBUG6 %s/%d: posix fudge, forcing tmp (%d) to match Woffset+grow_incr (%d)\n",
2075 Progname, Pid, __FILE__, __LINE__, tmp, Woffset+grow_incr);
2077 tmp = Woffset + grow_incr;
2084 lkfile(fd, LOCK_UN, LKLVL0);
2086 if ( ret != grow_incr ) {
2087 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
2088 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2089 if ( ret == -ENOSPC ) {
2097 * Check for a condition where the file was truncated just before
2100 if ( tmp != Woffset + grow_incr) {
2102 * The offset after the write was not as expected.
2103 * This could be caused by the following:
2104 * - file truncated after the lseek and before the write.
2105 * - the file was written to after fstat and before the write
2106 * and the file was opened with O_APPEND.
2108 * The pattern written to the file will be considered corrupted.
2110 if ( Debug > 0 && lockfile ) {
2111 printf("%s%s: %d DEBUG1 %s/%d: offset after write(%d) not as exp(%d+%d=%d)\n",
2112 Progname, TagName, Pid, __FILE__, __LINE__, tmp, Woffset, grow_incr, Woffset+grow_incr);
2113 printf("%s%s: %d DEBUG1 %s/%d: %d Assuming file changed by another process, resetting offset:%d (expect pattern mismatch)\n",
2114 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, tmp-grow_incr);
2117 printf("%s: %d DEBUG5 %s/%d: about to chop Woffset. tmp=%d, grow_incr=%d, Woffset was %d\n",
2118 Progname, Pid, __FILE__, __LINE__, tmp, grow_incr, Woffset);
2120 Woffset=tmp-grow_incr;
2125 } /* end of grow by write */
2129 * Woffset - holds start of grow (start of write expect in grow by lseek)
2130 * Grow_incr - holds size of grow (write).
2131 * fsize - holds size of file before write
2133 size_grew=(Woffset + Grow_incr) - fsize;
2135 if ( Mode & MODE_FIFO ) {
2136 printf("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
2137 Progname, Pid, __FILE__, __LINE__, Grow_incr, Iter_cnt);
2140 else if ( size_grew > 0 )
2141 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), grew file by %d bytes\n",
2142 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset, size_grew);
2144 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), did not grow file\n",
2145 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset);
2148 bytes_consumed += size_grew;
2151 } /* end of growfile */
2153 /***********************************************************************
2154 * shrinkfile file by trunc_incr. file can not be made smaller than
2155 * size zero. Therefore, if trunc_incr is larger than file size,
2156 * file will be truncated to zero.
2157 * The file descriptor current offset is assumed to be the end of the
2160 ***********************************************************************/
2162 shrinkfile(fd, filename, trunc_incr, trunc_inter, just_trunc)
2166 int trunc_inter; /* interval */
2167 int just_trunc; /* lseek has already been done for you */
2169 static int shrink_cnt = 0;
2179 if ( trunc_inter == 0 || (shrink_cnt % trunc_inter != 0)) {
2181 printf("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
2182 Progname, Pid, __FILE__, __LINE__, trunc_inter, shrink_cnt);
2183 return 0; /* not this time */
2186 if ( Mode & MODE_FIFO ) {
2188 printf("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
2189 Progname, Pid, __FILE__, __LINE__);
2190 return 0; /* can not truncate fifo */
2193 lkfile(fd, LOCK_EX, LKLVL0);
2195 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
2196 fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
2197 Progname, TagName, Pid, __FILE__, __LINE__, fd, strerror(errno));
2198 lkfile(fd, LOCK_UN, LKLVL0);
2202 if ( Mode & MODE_RAND_LSEEK ) {
2203 if ( max_lseek <= -1 ) {
2204 if ( (new_offset=file_size(fd)) == -1 ) {
2205 lkfile(fd, LOCK_UN, LKLVL0);
2209 if ( new_offset < min_lseek )
2210 new_offset=min_lseek;
2212 new_offset=random_range(min_lseek, new_offset, 1, NULL);
2215 new_offset=random_range(min_lseek, max_lseek, 1, NULL);
2219 if ((offset=lseek(fd, new_offset, SEEK_SET)) == -1 ) {
2220 fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l3 failed: %s\n",
2221 Progname, TagName, Pid, __FILE__, __LINE__, fd, new_offset, strerror(errno));
2222 lkfile(fd, LOCK_UN, LKLVL0);
2225 else if ( Debug > 3 )
2226 printf("%s: %d DEBUG4 %s/%d: lseeked to random offset %d\n",
2227 Progname, Pid, __FILE__, __LINE__, offset);
2232 else { /* remove trunc_incr from file */
2234 new_offset = cur_offset-trunc_incr;
2236 if ( new_offset < 0 )
2240 if ( lseek(fd, new_offset, SEEK_SET) == -1 ) {
2241 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, SEEK_SET) l4 failed: %s\n",
2242 Progname, TagName, Pid, __FILE__, __LINE__, new_offset, strerror(errno));
2243 lkfile(fd, LOCK_UN, LKLVL0);
2246 else if ( Debug > 3 )
2247 printf("%s: %d DEBUG4 %s/%d: lseeked to offset %d, %d bytes from end\n",
2248 Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
2256 ret=ftruncate(fd, new_offset );
2257 if( (ret == 0) && (Debug > 3) ){
2258 printf("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
2259 Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
2263 lkfile(fd, LOCK_UN, LKLVL0);
2267 fprintf(stderr, "%s%s: %d %s/%d: trunc failed: %s\n",
2268 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
2270 fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
2271 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
2277 printf("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
2278 Progname, Pid, __FILE__, __LINE__, cur_offset-new_offset, new_offset);
2282 bytes_consumed -= (cur_offset - new_offset);
2285 } /* end of shrinkfile */
2287 /***********************************************************************
2289 ***********************************************************************/
2291 check_write(fd, cf_inter, filename, mode)
2293 int cf_inter; /* check file interval */
2294 char *filename; /* needed for error messages */
2295 int mode; /* write mode */
2298 static int cf_count = 0;
2306 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2308 printf("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
2309 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2310 return 0; /* no check done */
2313 if ( Grow_incr <= 0 ) {
2315 printf("%s: %d DEBUG4 %s/%d: No write validation, Grow_incr = %d, offset = %d\n",
2316 Progname, Pid, __FILE__, __LINE__, Grow_incr, Woffset);
2317 return 0; /* no check */
2323 * Get the shared file lock. We need to hold the lock from before
2324 * we do the stat until after the read.
2326 lkfile(fd, LOCK_SH, LKLVL0);
2328 if ((fsize=file_size(fd)) == -1 ) {
2329 lkfile(fd, LOCK_UN, LKLVL0);
2332 } else if ( fsize <= Woffset ) {
2334 * The file was truncated between write and now.
2335 * The contents of our last write is totally gone, no check.
2338 printf("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than where last wrote (%d)- no write validation\n",
2339 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, Woffset);
2340 lkfile(fd, LOCK_UN, LKLVL0);
2341 return 0; /* no validation, but not an error */
2343 } else if ( fsize < (Woffset + Grow_incr)) {
2345 * The file was truncated between write and now.
2346 * Part of our last write has been truncated, adjust our Grow_incr
2351 Grow_incr=fsize-Woffset;
2355 printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of wrt(off:%d, sz:%d), adj=%d\n",
2356 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, tmp-Grow_incr, Woffset, tmp, Grow_incr);
2362 printf("%s: %d DEBUG3 %s/%d: about to do write validation, offset = %d, size = %d\n",
2363 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2365 if ( ! (mode & MODE_FIFO) ) {
2367 if ( lseek(fd, Woffset, 0) == -1 ) {
2368 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, 0) failed: %s\n",
2369 Progname, TagName, Pid, __FILE__, __LINE__, Woffset, strerror(errno));
2372 printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%d\n",
2373 Progname, Pid, __FILE__, __LINE__, Woffset);
2377 * Read last writes data
2380 ret=lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,0);
2382 ret=read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
2386 * report the error and debug information before releasing
2389 if ( ret != Grow_incr ) {
2390 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2395 printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n",
2396 Progname, TagName, Pid, __FILE__, __LINE__, fd,
2397 (int)lseek(fd,SEEK_CUR,0), /* FIXME: 64bit/LFS ? */
2399 Fileinfo.openflags);
2402 lkfile(fd, LOCK_UN, LKLVL0);
2407 lkfile(fd, LOCK_UN, LKLVL0);
2409 if ( Mode & MODE_GROW_BY_LSEEK ) {
2410 /* check that all zeros upto last character */
2411 for(ptr=Buffer; ptr < (Buffer+Grow_incr-1); ptr++) {
2412 if ( *ptr != '\0' ) {
2414 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2415 Progname, TagName, Pid, __FILE__, __LINE__,
2416 (int)(Woffset+(Grow_incr-(Buffer-ptr))),
2422 /* check that the last char is a 'w' */
2423 if ( *ptr != 'w' ) {
2425 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2426 Progname, TagName, Pid, __FILE__, __LINE__,
2427 (int)(Woffset+(Grow_incr-(Buffer-ptr))), 'w',
2432 return 0; /* all is well */
2435 else if ( Pattern == PATTERN_OFFSET )
2436 ret=datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
2437 else if ( Pattern == PATTERN_PID )
2438 ret=datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
2439 else if ( Pattern == PATTERN_ASCII )
2440 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2441 else if ( Pattern == PATTERN_RANDOM )
2442 ; /* no check for random */
2443 else if ( Pattern == PATTERN_ALT )
2444 ret=databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
2445 else if ( Pattern == PATTERN_CHKER )
2446 ret=databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
2447 else if ( Pattern == PATTERN_CNTING )
2448 ret=databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
2449 else if ( Pattern == PATTERN_ZEROS )
2450 ret=databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
2451 else if ( Pattern == PATTERN_ONES )
2452 ret=databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
2454 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2457 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
2458 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2461 printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, offset:%d, sz:%d open flags:%#o %s\n",
2462 Progname, TagName, Pid, __FILE__, __LINE__, fd, lockfile,
2463 Woffset, Grow_incr, Fileinfo.openflags, openflags2symbols(Fileinfo.openflags, ",", NULL));
2470 printf("%s: %d DEBUG7 %s/%d: No corruption detected on write validation , offset = %d, size = %d\n",
2471 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2473 return 0; /* all is well */
2478 /***********************************************************************
2480 ***********************************************************************/
2482 check_file(fd, cf_inter, filename, no_file_check)
2484 int cf_inter; /* check file interval */
2485 char *filename; /* needed for error messages */
2486 int no_file_check; /* if set, do not do file content check */
2489 static int cf_count = 0;
2499 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2501 printf("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
2502 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2503 return 0; /* no check done */
2507 * if we can't determine file content, don't bother checking
2509 if ( no_file_check ) {
2511 printf("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
2512 Progname, Pid, __FILE__, __LINE__);
2517 * Lock the file. We need to have the file lock before
2518 * the stat and until after the last read to prevent
2519 * a trunc/truncate from "corrupting" our data.
2521 lkfile(fd, LOCK_SH, LKLVL0);
2523 if ((fsize=file_size(fd)) == -1 ) {
2524 lkfile(fd, LOCK_UN, LKLVL0);
2530 printf("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
2531 Progname, Pid, __FILE__, __LINE__);
2533 lkfile(fd, LOCK_UN, LKLVL0);
2538 printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
2539 Progname, Pid, __FILE__, __LINE__);
2541 if ( fsize > MAX_FC_READ ) {
2543 * read the file in MAX_FC_READ chuncks.
2546 if ((buf=(char *)malloc(MAX_FC_READ)) == NULL ) {
2547 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2548 __FILE__, __LINE__, MAX_FC_READ, strerror(errno));
2549 lkfile(fd, LOCK_UN, LKLVL0);
2553 lseek(fd, 0, SEEK_SET);
2555 lkfile(fd, LOCK_SH, LKLVL0); /* get lock on file before getting file size */
2558 while (rd_cnt < fsize ) {
2559 if ( fsize - rd_cnt > MAX_FC_READ )
2560 rd_size=MAX_FC_READ;
2562 rd_size=fsize - rd_cnt;
2565 ret=lio_read_buffer(fd, io_type, buf, rd_size,
2566 SIGUSR1, &errmsg,0);
2568 ret=read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
2571 if (ret != rd_size ) {
2572 fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n",
2573 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2575 lkfile(fd, LOCK_UN, LKLVL0);
2579 read(fd, buf, rd_size);
2582 if ( Pattern == PATTERN_OFFSET )
2583 ret=datapidchk(STATIC_NUM, buf, rd_size, rd_cnt, &errmsg);
2584 else if ( Pattern == PATTERN_PID )
2585 ret=datapidchk(Pid, buf, rd_size, rd_cnt, &errmsg);
2586 else if ( Pattern == PATTERN_ASCII )
2587 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2588 else if ( Pattern == PATTERN_RANDOM )
2589 ; /* no checks for random */
2590 else if ( Pattern == PATTERN_ALT )
2591 ret=databinchk('a', buf, rd_size, rd_cnt, &errmsg);
2592 else if ( Pattern == PATTERN_CHKER )
2593 ret=databinchk('c', buf, rd_size, rd_cnt, &errmsg);
2594 else if ( Pattern == PATTERN_CNTING )
2595 ret=databinchk('C', buf, rd_size, rd_cnt, &errmsg);
2596 else if ( Pattern == PATTERN_ZEROS )
2597 ret=databinchk('z', buf, rd_size, rd_cnt, &errmsg);
2598 else if ( Pattern == PATTERN_ONES )
2599 ret=databinchk('o', buf, rd_size, rd_cnt, &errmsg);
2601 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2606 "%s%s: %d %s/%d: %d CFp %s in file %s\n",
2607 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2610 lkfile(fd, LOCK_UN, LKLVL0);
2616 lkfile(fd, LOCK_UN, LKLVL0);
2623 * Read the whole file in a single read
2625 if((buf=(char *)malloc(fsize)) == NULL ) {
2626 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2627 __FILE__, __LINE__, fsize, strerror(errno));
2632 lseek(fd, 0, SEEK_SET);
2635 read(fd, buf, fsize);
2638 ret=lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,0);
2640 ret=read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
2643 /* unlock the file as soon as we can */
2644 lkfile(fd, LOCK_UN, LKLVL0);
2647 if ( ret != fsize ) {
2648 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n",
2649 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2653 if ( Pattern == PATTERN_OFFSET )
2654 ret=datapidchk(STATIC_NUM, buf, fsize, 0, &errmsg);
2655 else if ( Pattern == PATTERN_PID )
2656 ret=datapidchk(Pid, buf, fsize, 0, &errmsg);
2657 else if ( Pattern == PATTERN_ASCII )
2658 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2659 else if ( Pattern == PATTERN_RANDOM )
2660 ; /* no check for random */
2661 else if ( Pattern == PATTERN_ALT )
2662 ret=databinchk('a', buf, fsize, 0, &errmsg);
2663 else if ( Pattern == PATTERN_CHKER )
2664 ret=databinchk('c', buf, fsize, 0, &errmsg);
2665 else if ( Pattern == PATTERN_CNTING )
2666 ret=databinchk('C', buf, fsize, 0, &errmsg);
2667 else if ( Pattern == PATTERN_ZEROS )
2668 ret=databinchk('z', buf, fsize, 0, &errmsg);
2669 else if ( Pattern == PATTERN_ONES )
2670 ret=databinchk('o', buf, fsize, 0, &errmsg);
2672 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2675 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s in file %s\n",
2676 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2686 } /* end of check_file */
2688 /***********************************************************************
2690 ***********************************************************************/
2696 if (fstat(fd, &sb) < 0) {
2697 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
2698 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
2706 /***********************************************************************
2707 * do file lock/unlock action.
2708 ***********************************************************************/
2710 lkfile(int fd, int operation, int lklevel)
2715 if ( lockfile == lklevel) {
2718 switch (operation) {
2720 printf("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n",
2721 Progname, Pid, __FILE__, __LINE__, fd);
2725 printf("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n",
2726 Progname, Pid, __FILE__, __LINE__, fd);
2730 printf("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n",
2731 Progname, Pid, __FILE__, __LINE__, fd);
2737 * Attempt to get/release desired lock.
2738 * file_lock will attempt to do action over and over again until
2739 * either an unretryable error or the action is completed.
2742 if ( file_lock(fd, operation, &errmsg) != 0 ) {
2743 printf("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
2744 Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
2746 /* do we count this as an error? handle_error(); */
2751 switch (operation) {
2753 printf("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n",
2754 Progname, Pid, __FILE__, __LINE__, fd);
2758 printf("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n",
2759 Progname, Pid, __FILE__, __LINE__, fd);
2763 printf("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n",
2764 Progname, Pid, __FILE__, __LINE__, fd);
2768 printf("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n",
2769 Progname, Pid, __FILE__, __LINE__, operation, fd);
2779 /***********************************************************************
2781 ***********************************************************************/
2783 pre_alloc(file, fd, size)
2792 if ( ialloc(fd, size, IA_CONT, &avl) == -1 ) {
2793 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: ialloc failed: %d %s\n",
2795 __FILE__, __LINE__, errno, strerror(errno));
2801 struct xfs_flock64 f;
2807 /* non-zeroing reservation */
2808 if( xfsctl( file, fd, XFS_IOC_RESVSP, &f ) == -1 ){
2809 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: xfsctl(XFS_IOC_RESVSP) failed: %d %s\n",
2811 __FILE__, __LINE__, errno, strerror(errno));