2 * Copyright (c) 2000 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * This program will grow a list of files.
20 * Each file will grow by grow_incr before the same
21 * file grows twice. Each file is open and closed before next file is opened.
23 * To just verify file contents: growfiles -g 0 -c 1 filename
25 * See help and prt_examples functions below.
29 * print debug message about options used
30 * setup signal handlers
31 * return control to user (if wanted - default action)
32 * fork number of desired childern (if wanted)
33 * re-exec self (if wanted)
34 * Determine number of files
35 * malloc space or i/o buffer
36 * Loop until stop is set
37 * Determine if hit iteration, time, max errors or num bytes reached
38 * Loop through each file
40 * fstat file - to determine if file is a fifo
41 * prealloc file space (if wanted)
50 * remove all files (if wanted)
52 * Author: Richard Logan
58 #ifdef HAVE_SYS_FILE_H
62 #include "dataascii.h"
63 #include "random_range.h"
67 extern char *openflags2symbols();
69 extern int parse_open_flags();
70 extern int background();
72 extern int datapidgen();
73 extern void databingen();
74 extern int datapidchk();
75 extern int databinchk();
76 extern int file_lock();
91 static void notify_others();
95 #define NEWIO 1 /* Use the tlibio.c functions */
98 #define NEWIO 0 /* specifies to use original iowrite.c */
99 /* functions instead of tlibio.c functions */
100 /* Once it is proven tlibio.c functions work properly, */
101 /* only tlibio.c functions will be used */
107 #define PATH_MAX 1023
112 #define DEF_FILE "gf"
119 int io_type = 0; /* I/O type -sync */
120 int open_flags = O_RDWR|O_CREAT; /* open flags */
122 #define MAX_FC_READ 196608 /* 4096 * 48 - 48 blocks */
124 #define PATTERN_ASCII 1 /* repeating alphabet letter pattern */
125 /* allows multiple writers and to be checked */
126 #define PATTERN_PID 2 /* <pid><words byte offset><pid> */
127 /* Assumes 64 bit word. Only allows single */
128 /* process to write and check */
130 * 1234567890123456789012345678901234567890123456789012345678901234
131 * ________________________________________________________________
132 * < pid >< offset in file of this word >< pid >
135 #define PATTERN_OFFSET 3 /* Like PATTERN_PID but has a fixed number */
136 /* (STATIC_NUM) instead of pid. */
137 /* Allows multiple processes to write/read */
138 #define PATTERN_ALT 4 /* alternating bit pattern (i.e. 0x5555555...) */
139 #define PATTERN_CHKER 5 /* checkerboard pattern (i.e. 0xff00ff00ff00...) */
140 #define PATTERN_CNTING 6 /* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
141 #define PATTERN_ONES 7 /* all bits set (i.e. 0xffffffffffffff...) */
142 #define PATTERN_ZEROS 8 /* all bits cleared (i.e. 0x000000000...) */
143 #define PATTERN_RANDOM 9 /* random integers - can not be checked */
144 #define STATIC_NUM 221849 /* used instead of pid when PATTERN_OFFSET */
146 #define MODE_RAND_SIZE 1 /* random write and trunc */
147 #define MODE_RAND_LSEEK 2 /* random lseek before write */
148 #define MODE_GROW_BY_LSEEK 4 /* lseek beyond end of file then write a byte */
149 #define RANDOM_OPEN 999876 /* if Open_flags set to this value, open flags */
150 /* will be randomly choosen from Open_flags[] */
151 #define MODE_FIFO S_IFIFO /* defined in stat.h 0010000 */
153 int num_files = 0; /* num_auto_files + cmd line files */
154 char *filenames; /* pointer to space containing filenames */
155 int remove_files = 0; /* if set, cleanup default is not to cleanup */
156 int bytes_consumed = 0; /* total bytes consumed, all files */
157 int bytes_to_consume = 0; /* non-zero if -B was specified, total bytes */
158 int Maxerrs = 100; /* Max number errors before forced exit */
159 int Errors = 0; /* number of encountered errors */
160 int Upanic_on_error = 0; /* call upanic if error and this variable set */
162 /* The *_size variables are only used when random iosize option (-r) is used */
164 int min_size=1; /* also set in option parsing */
165 int mult_size=1; /* when random iosz, iosz must be mult of mult_size */
166 /* the *_lseek variables are only used when radon lseek option (-R) is used */
167 int min_lseek=0; /* also set in option parsing */
168 int max_lseek=-1; /* -1 means size of file */
169 int Pattern=PATTERN_ASCII;
170 int Seed=-1; /* random number seed, < 0 == uninitialized */
171 int Nseeds=0; /* Number of seed specified by the user */
172 int *Seeds; /* malloc'ed arrary of ints holding user spec seeds */
174 int using_random=0; /* flag indicating randomization is being used */
175 float delaysecs=0.0; /* delay between iterations (in seconds) */
176 int delaytime; /* delay between iterations in clocks/uses */
177 int lockfile=0; /* if set, do file locking */
178 /* 1 = do file locking around write, trunc */
180 /* 2 = write lock around all file operations */
182 int Woffset=0; /* offset before last write */
183 int Grow_incr=4096; /* sz of last write */
184 int Mode=0; /* bitmask of write/trunc mode */
185 /* also knows if dealing with fifo */
186 char *Buffer = NULL; /* buffer used by write and write check */
187 int Alignment=0; /* if non word multiple, io will not be word aligned */
188 int Opid=0; /* original pid */
190 int Sync_with_others = 0; /* Flag indicating to stop other if we stop before DONE */
191 int Iter_cnt = 0; /* contains current iteration count value */
192 char TagName[40]; /* name of this growfiles (see Monster) */
202 * Define open flags that will be used when '-o random' option is used.
203 * Note: If there is more than one growfiles doing its thing to the same
204 * file, O_TRUNC will cause data mismatches. How you ask?
205 * timing of events, example:
206 * Process one Process two
207 * --------------- -------------
213 * write with wrong pattern
214 * because offset is wrong
216 * The second process truncated the file after the pattern was
217 * determined, thus the pattern is wrong for the file location.
219 * There can also be a timing problem with open flag O_APPEND if
220 * file locks are not being used (-l option). Things could happen
221 * between the fstat and the write. Thus, writing the wrong pattern.
222 * If all processes observe the file locks, O_APPEND should be ok
227 O_RDWR|O_CREAT|O_APPEND,
228 O_RDWR|O_CREAT|O_NDELAY,
229 O_RDWR|O_CREAT|O_SYNC,
230 O_RDWR|O_CREAT|O_SYNC|O_NDELAY,
231 O_RDWR|O_CREAT|O_APPEND|O_NDELAY,
235 #define REXEC_INIT 0 /* don't do re-exec of childern */
236 #define REXEC_DOIT 1 /* Do re-exec of childern */
237 #define REXEC_DONE 2 /* We've already been re-exec'ed */
243 #define USECS_PER_SEC 1000000 /* microseconds per second */
246 * Define marcos used when dealing with file locks.
248 #define LKLVL0 1 /* file lock around write/read/trunc */
249 #define LKLVL1 2 /* file lock after open to before close */
252 * Define special max lseek values
254 #define LSK_EOF -1 /* set fptr up to EOF */
255 #define LSK_EOFPLUSGROW -2 /* set fptr up to EOF + grow - leave whole */
256 #define LSK_EOFMINUSGROW -3 /* set fptr up to EOF-grow - no grow */
259 /***********************************************************************
261 ***********************************************************************/
267 extern char *optarg; /* used by getopt */
272 int first_file_ind = 0;
273 int num_auto_files = 0; /* files created by tool */
274 int seq_auto_files = 0; /* auto files created by tool created by tool */
275 char *auto_dir = DEF_DIR;
276 char *auto_file = DEF_FILE;
277 int grow_incr = 4096;
278 int trunc_incr = 4096;
279 int trunc_inter = 0; /* 0 means none, */
280 int unlink_inter = 0; /* 0 means none, 1 means always unlink */
281 int unlink_inter_ran = -1; /* -1 -use unlink_inter, otherwise randomly choose */
282 /* between unlink_inter and unlink_inter_ran */
283 int file_check_inter = 0; /* 0 means never, 1 means always */
284 int write_check_inter = 1; /* 0 means never, 1 means always */
285 int iterations = 1; /* number of increments to be added */
286 int no_file_check = 0; /* if set, no whole file checking will be done */
288 int fd; /* file descriptor */
289 int stop = 0; /* loop stopper if set */
293 int pre_alloc_space = 0;
294 int total_grow_value = 0; /* used in pre-allocations */
295 int backgrnd = 1; /* return control to user */
297 int time_iterval = -1;
298 time_t start_time = 0;
299 char reason[40]; /* reason for loop termination */
302 int reexec=REXEC_INIT; /* reexec info */
303 char *exec_path=NULL;
307 char *filename; /* name of file specified by user */
308 char *cptr; /* temp char pointer */
309 extern int Forker_npids; /* num of forked pid, defined in forker.c */
312 if ( argv[0][0] == '-' )
315 * Determine name of file used to invoke this program
317 if ((Progname=strrchr(argv[0], '/')) != NULL)
327 while ((ind=getopt(argc, argv,
328 "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) {
336 switch (sscanf(optarg, "%i%c",
337 &bytes_to_consume, &chr)) {
343 bytes_to_consume *= BSIZE;
346 "%s%s: --B option arg invalid\n",
354 fprintf(stderr, "%s%s: --B option arg invalid\n",
364 prt_examples(stdout);
367 case 'b' : /* batch */
372 if (sscanf(optarg, "%i", &write_check_inter) != 1 ) {
373 fprintf(stderr, "%s%s: --c option arg invalid\n",
381 if (sscanf(optarg, "%i", &file_check_inter) != 1 ) {
382 fprintf(stderr, "%s%s: --c option arg invalid\n",
392 if ( stat(auto_dir, &statbuf) == -1 ) {
393 if ( mkdir(auto_dir, 0777) == -1 ) {
394 if ( errno != EEXIST ) {
396 "%s%s: Unable to make dir %s\n",
397 Progname, TagName, auto_dir);
403 if ( ! (statbuf.st_mode & S_IFDIR) ) {
405 "%s%s: %s already exists and is not a directory\n",
406 Progname, TagName, auto_dir);
413 if (sscanf(optarg, "%i", &Debug) != 1 ) {
414 fprintf(stderr, "%s%s: --D option arg invalid\n",
422 if (sscanf(optarg, "%i", &Maxerrs) != 1 ) {
423 fprintf(stderr, "%s%s: --e option arg invalid\n",
435 if ((ret=sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1 ||
438 fprintf(stderr, "%s%s: --g option arg invalid\n",
444 if ( chr == 'b' || chr == 'B' )
448 "%s%s: --g option arg invalid\n",
457 if (sscanf(optarg, "%f", &delaysecs) != 1 || delaysecs < 0 ) {
459 fprintf(stderr, "%s%s: --H option arg invalid\n",
467 if (sscanf(optarg, "%i", &iterations) != 1 ||
470 fprintf(stderr, "%s%s: --i option arg invalid\n",
479 if((io_type=lio_parse_io_arg1(optarg)) == -1 ) {
481 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
485 if( io_type & LIO_RANDOM )
488 if((io_type=parse_io_arg(optarg)) == -1 ) {
490 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
494 if( io_type == 99 ) /* hold-over until tlibio.h */
502 lockfile=2; /* lockfile can only be 1 or 2 */
506 if (sscanf(optarg, "%i", &time_iterval) != 1 ||
508 fprintf(stderr, "%s%s: --L option arg invalid\n",
516 if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) < 1 ||
519 fprintf(stderr, "%s%s: --n option arg invalid\n",
528 if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
529 num_auto_files < 0 ) {
531 fprintf(stderr, "%s%s: --N option arg invalid\n",
539 if (sscanf(optarg, "%i", &Alignment) != 1 ||
540 num_auto_files < 0 ) {
542 fprintf(stderr, "%s%s: --O option arg invalid\n",
550 if ( strcmp(optarg, "random") == 0 ){
551 open_flags=RANDOM_OPEN;
554 } else if ((open_flags=parse_open_flags(optarg, NULL)) == -1 ) {
555 fprintf(stderr, "%s%s: --o arg contains invalid flag\n",
562 case 'p' : /* pre allocate space */
563 printf("%s%s: --p is illegal option on this system\n",
569 printf("%s%s: --P is illegal option on non-cray system\n",
574 case 'q': /* file content or pattern */
577 Pattern = PATTERN_ALT;
580 Pattern = PATTERN_ASCII;
583 Pattern = PATTERN_PID;
586 Pattern = PATTERN_OFFSET;
589 Pattern = PATTERN_CHKER;
592 Pattern = PATTERN_CNTING;
595 Pattern = PATTERN_RANDOM;
599 Pattern = PATTERN_ZEROS;
602 Pattern = PATTERN_ONES;
606 "%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
613 case 'R': /* random lseek before write arg: [min-]max*/
614 if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) != 2 ) {
615 min_lseek=1; /* same as default in define */
616 if (sscanf(optarg, "%i%c", &max_lseek, &chr) != 1 ) {
617 fprintf(stderr, "%s%s: --R option arg invalid: [min-]max\n",
622 if ( max_lseek < LSK_EOFMINUSGROW ) {
623 fprintf(stderr, "%s%s: --R option, max_lseek is invalid\n",
627 Mode |= MODE_RAND_LSEEK;
631 case 'r': /* random io size arg: [min-]max[:mult] */
633 /* min-max:mult format */
634 if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
635 &mult_size, &chr) != 3 ) {
637 /* max:mult format */
638 if (sscanf(optarg, "%i:%i%c", &max_size,
639 &mult_size, &chr) != 2 ) {
641 if (sscanf(optarg, "%i-%i%c", &min_size,
642 &max_size, &chr) != 2 ) {
644 if (sscanf(optarg, "%i%c", &max_size, &chr) != 1 ) {
646 "%s%s: --r option arg invalid: [min-]max[:mult]\n",
654 if ( max_size < 0 ) {
655 fprintf(stderr, "%s%s: --r option, max_size is invalid\n",
660 * If min and max are the same, no randomness
662 if ( min_size != max_size ) {
663 Mode |= MODE_RAND_SIZE;
669 if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
670 seq_auto_files < 0 ) {
672 fprintf(stderr, "%s%s: --S option arg invalid\n",
679 case 's': /* format: seed[,seed...] */
681 /* count the number of seeds */
683 for(Nseeds=1; *cptr ; Nseeds++) {
684 if ( (filename=strchr(cptr, ',')) == NULL )
689 Seeds=(int *)malloc(Nseeds*sizeof(int));
692 * check that each seed is valid and put them in
693 * the newly malloc'ed Seeds arrary.
695 filename=cptr=optarg;
696 for(Nseeds=0; *cptr; Nseeds++) {
697 if ( (filename=strchr(cptr, ',')) == NULL ) {
698 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
699 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
700 Progname, TagName, cptr);
709 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
710 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
711 Progname, TagName, cptr);
715 *filename=','; /* restore string */
722 if ((ret=sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1 ||
725 fprintf(stderr, "%s%s: --t option arg invalid\n",
731 if ( chr == 'b' || chr == 'B' )
735 "%s%s: --t option arg invalid\n",
743 case 'T': /* truncate interval */
744 if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
747 fprintf(stderr, "%s%s: --T option arg invalid\n",
758 case 'U': /* how often to unlink file */
761 * A-B - randomly pick interval between A and B
762 * X - unlink file every X iteration
764 if (sscanf(optarg, "%i-%i", &unlink_inter,
765 &unlink_inter_ran) == 2 ) {
767 if ( unlink_inter < 0 || unlink_inter_ran < 0 ) {
768 fprintf(stderr, "%s%s: --U option arg invalid\n",
773 /* ensure unlink_inter contains smaller value */
774 if ( unlink_inter > unlink_inter_ran ) {
775 tmp=unlink_inter_ran;
776 unlink_inter_ran=unlink_inter;
781 } else if (sscanf(optarg, "%i%c", &unlink_inter, &chr) != 1 ||
784 fprintf(stderr, "%s%s: --U option arg invalid\n",
792 if ( reexec != REXEC_DONE )
797 Mode |= MODE_GROW_BY_LSEEK;
801 sprintf( TagName, "(%.39s)", optarg );
816 cptr = getenv("TOUTPUT");
817 if( (cptr != NULL) && (strcmp( cptr, "NOPASS" ) == 0) ){
822 if ( Pattern == PATTERN_RANDOM ) {
824 if ( write_check_inter || file_check_inter )
825 printf("%s%s: %d Using random pattern - no data checking will be performed!\n",
826 Progname, TagName, (int)getpid());
828 else if ( max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK ) {
831 if ( file_check_inter )
832 printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
833 no whole file checking will be performed!\n", Progname, TagName, (int)getpid());
837 if ( Mode & MODE_RAND_SIZE )
847 printf("%s: %d DEBUG2 forking, returning control to the user\n",
849 background(Progname); /* give user their prompt back */
854 lio_set_debug(Debug-3);
856 set_iowrite_debug(Debug-3);
861 * Print some program information here if debug is turned on to
867 if ( Mode & MODE_GROW_BY_LSEEK )
868 printf("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
870 else if ( Pattern == PATTERN_OFFSET )
871 printf("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
872 Progname, Pid, STATIC_NUM, STATIC_NUM);
873 else if ( Pattern == PATTERN_PID )
874 printf("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
876 else if ( Pattern == PATTERN_ASCII )
877 printf("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
879 else if ( Pattern == PATTERN_ALT )
880 printf("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
882 else if ( Pattern == PATTERN_CHKER )
883 printf("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
885 else if ( Pattern == PATTERN_CNTING )
886 printf("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
888 else if ( Pattern == PATTERN_RANDOM )
889 printf("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
891 else if ( Pattern == PATTERN_ONES )
892 printf("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
894 else if ( Pattern == PATTERN_ZEROS )
895 printf("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
899 printf("%s: %d DEBUG3 unknown pattern\n",
901 if ( bytes_to_consume )
902 printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
903 Progname, Pid, bytes_to_consume);
904 printf("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n",
905 Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
907 printf("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
908 Progname, Pid, Debug, remove_files);
910 printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
912 if ( open_flags == RANDOM_OPEN )
913 printf("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n", Progname,
916 printf("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n", Progname,
917 Pid, open_flags, io_type);
919 if ( Mode & MODE_RAND_SIZE ) {
920 printf("%s: %d DEBUG3 random write/trunc: min=%d, max=%d, mult = %d\n",
921 Progname, Pid, min_size, max_size, mult_size);
924 printf("%s: %d DEBUG3 grow_incr = %d\n",
925 Progname, Pid, grow_incr);
927 if ( Mode & MODE_RAND_LSEEK ) {
928 if ( max_lseek == LSK_EOF )
929 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile>\n",
930 Progname, Pid, min_lseek);
931 else if ( max_lseek == LSK_EOFPLUSGROW )
932 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile+iosize>\n",
933 Progname, Pid, min_lseek);
934 else if ( max_lseek == LSK_EOFMINUSGROW )
935 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile-iosize>\n",
936 Progname, Pid, min_lseek);
938 printf("%s: %d DEBUG3 random lseek: min=%d, max=%d\n",
939 Progname, Pid, min_lseek, max_lseek);
942 printf("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
943 Progname, Pid, write_check_inter, file_check_inter);
945 printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
946 Progname, Pid, trunc_inter, trunc_incr);
949 printf("%s: %d DEBUG3 no whole file checking will be done\n",
952 if ( unlink_inter_ran == -1 ) {
953 printf("%s: %d DEBUG3 unlink_inter = %d\n",
954 Progname, Pid, unlink_inter);
956 printf("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n",
957 Progname, Pid, unlink_inter, unlink_inter_ran);
961 num=sizeof(Open_flags)/sizeof(int);
962 printf("%s: %d DEBUG9 random open flags values:\n", Progname, Pid);
963 for(ind=0; ind<num; ind++) {
964 printf("\t%#o\n", Open_flags[ind]);
967 } /* end of DEBUG > 2 */
969 if ( Debug > 1 && num_procs > 1 ) {
970 printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
974 fflush(stdout); /* ensure pending i/o is flushed before forking */
977 forker(num_procs, forker_mode, Progname);
979 Pid=getpid(); /* reset after the forks */
981 * If user specified random seed(s), get that random seed value.
982 * get random seed if it was not specified by the user.
983 * This is done after the forks, because pid is used to get the seed.
987 * If only one seed specified, all processes will get that seed.
990 } else if ( Nseeds > 1 ) {
992 * More than one seed was specified.
993 * The original process gets the first seed. Each
994 * process will be get the next seed in the specified list.
1000 * If user didn't specify enough seeds, use default method.
1002 if ( Forker_npids >= Nseeds )
1003 Seed=time(0) + Pid; /* default random seed */
1005 Seed=Seeds[Forker_npids];
1010 * Generate a random seed based on time and pid.
1011 * It has a good chance of being unique for each pid.
1013 Seed=time(0) + Pid; /* default random seed */
1016 random_range_seed(Seed);
1018 if ( using_random && Debug > 0 )
1019 printf("%s%s: %d DEBUG1 Using random seed of %d\n",
1020 Progname, TagName, Pid, Seed);
1022 if ( unlink_inter_ran > 0 ) {
1024 * Find unlinking file interval. This must be done after
1025 * the seed was set. This allows multiple copies to
1026 * get different intervals.
1029 unlink_inter=random_range(tmp, unlink_inter_ran, 1, NULL);
1032 printf("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
1033 Progname, Pid, unlink_inter, tmp, unlink_inter_ran);
1037 * re-exec all childern if reexec is set to REXEC_DOIT.
1038 * This is useful on MPP systems to get the
1039 * child process on another PE.
1041 if ( reexec == REXEC_DOIT && Opid != Pid ) {
1042 if ( exec_path == NULL ) {
1043 exec_path = argv[0];
1044 /* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
1045 argv[0] = (char *)malloc(strlen(exec_path) + 2);
1046 sprintf(argv[0], "-%s", exec_path);
1050 printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
1051 Progname, Pid, __FILE__, __LINE__, argv[0]);
1053 execvp(argv[0], argv);
1056 /*** begin filename stuff here *****/
1058 * Determine the number of files to be dealt with
1060 if ( optind == argc ) {
1062 * no cmd line files, therfore, set
1063 * the default number of auto created files
1065 if ( ! num_auto_files && ! seq_auto_files )
1069 first_file_ind=optind;
1070 num_files += argc-optind;
1073 if ( num_auto_files ) {
1074 num_files += num_auto_files;
1077 if ( seq_auto_files ) {
1078 num_files += seq_auto_files;
1082 * get space for file names
1084 if ((filenames=(char *)malloc(num_files*PATH_MAX)) == NULL) {
1085 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1086 Progname, TagName, Pid, __FILE__, __LINE__, num_files*PATH_MAX,
1092 * fill in filename cmd files then auto files.
1096 if ( first_file_ind ) {
1097 for(ind=first_file_ind; ind<argc; ind++, num++) {
1098 strcpy((char *)filenames+(num*PATH_MAX), argv[ind]);
1103 * construct auto filename and insert them into filenames space
1105 for(ind=0;ind<num_auto_files; ind++, num++) {
1106 sprintf((char *)filenames+(num*PATH_MAX), "%s/%s.%d",
1107 auto_dir, auto_file, ind);
1111 * construct auto seq filenames
1113 for(ind=1; ind<=seq_auto_files; ind++, num++) {
1114 sprintf((char *)filenames+(num*PATH_MAX), "%s/%s%d",
1115 auto_dir, auto_file, ind);
1118 /**** end filename stuff ****/
1120 if ( time_iterval > 0 )
1124 * get space for I/O buffer
1127 if ((Buffer=(char *)malloc(grow_incr+Alignment)) == NULL) {
1128 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1129 Progname, TagName, Pid, __FILE__, __LINE__, grow_incr, strerror(errno));
1133 Buffer = Buffer + Alignment;
1138 printf("%s: %d DEBUG3 num_files = %d\n",
1139 Progname, Pid, num_files);
1142 if ( pre_alloc_space ) {
1143 if ( iterations == 0 ) {
1144 fprintf(stderr, "%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
1145 Progname, TagName, Pid, __FILE__, __LINE__);
1148 if ( Mode & MODE_RAND_SIZE ) {
1150 "%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
1151 Progname, TagName, Pid, __FILE__, __LINE__);
1155 total_grow_value=grow_incr * iterations;
1160 if ( bytes_to_consume && bytes_to_consume < total_grow_value ) {
1161 total_grow_value=bytes_to_consume;
1166 * If delaying between iterations, get amount time to
1167 * delaysecs in clocks or usecs.
1170 delaytime=(int)((float)USECS_PER_SEC * delaysecs);
1174 * This is the main iteration loop.
1175 * Each iteration, all files can be opened, written to,
1176 * read to check the write, check the whole file,
1177 * truncated, and closed.
1179 for(Iter_cnt=1; ! stop ; Iter_cnt++) {
1181 if ( iterations && Iter_cnt >= iterations+1 ) {
1182 strcpy(reason, "Hit iteration value");
1187 if ( (time_iterval > 0) && (start_time + time_iterval < time(0)) ) {
1188 sprintf(reason, "Hit time value of %d", time_iterval);
1193 if ( bytes_to_consume && bytes_consumed >= bytes_to_consume) {
1194 sprintf(reason, "Hit bytes consumed value of %d", bytes_to_consume);
1200 * This loop will loop through all files.
1201 * Each iteration, a single file can be opened, written to,
1202 * read to check the write, check the whole file,
1203 * truncated, and closed.
1205 for(ind=0; ind<num_files; ind++) {
1210 filename=(char *)filenames+(ind*PATH_MAX);
1211 Fileinfo.filename=(char *)filenames+(ind*PATH_MAX);
1214 if ( open_flags == RANDOM_OPEN ) {
1215 ret=Open_flags[random_range(0, sizeof(Open_flags)/sizeof(int)-1, 1, NULL)];
1221 Fileinfo.openflags=ret;
1224 printf("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
1225 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret,
1226 openflags2symbols(ret, ",", NULL));
1227 } else if ( Debug > 2 ) {
1228 printf("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
1229 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret);
1233 * open file with desired flags.
1235 if ( (fd=open(filename, ret, 0777)) == -1 ) {
1237 "%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
1238 Progname, TagName, Pid, __FILE__, __LINE__, filename, ret, errno, strerror(errno));
1245 lkfile(fd, LOCK_EX, LKLVL1); /* lock if lockfile is LKLVL1 */
1248 * preallocation is only done once, if specified.
1250 if ( pre_alloc_space ) {
1251 if (pre_alloc(filename, fd, total_grow_value) != 0 ) {
1256 printf("%s: %d DEBUG2 %s/%d: pre_allocated %d for file %s\n",
1257 Progname, Pid, __FILE__, __LINE__, total_grow_value, filename);
1259 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1261 Iter_cnt=0; /* reset outside loop to restart from one */
1266 * grow file by desired amount.
1267 * growfile() will set the Grow_incr variable and
1268 * possiblly update the Mode variable indicating
1269 * if we are dealing with a FIFO file.
1272 if (growfile(fd, filename, grow_incr, Buffer) != 0 ) {
1274 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1280 * check if last write is not corrupted
1282 if ( check_write(fd, write_check_inter, filename,
1288 * Check that whole file is not corrupted.
1290 if ( check_file(fd, file_check_inter, filename,
1291 no_file_check) != 0 ) {
1296 * shrink file by desired amount if it is time
1299 if ( shrinkfile(fd, filename, trunc_incr, trunc_inter, Mode) != 0 ) {
1303 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1306 printf("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n",
1307 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, fd);
1311 * Unlink the file if that is desired
1313 if ( unlink_inter && (Iter_cnt % unlink_inter == 0) ) {
1316 printf("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n",
1317 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename);
1323 * delay while staying active for "delaysecs" seconds.
1328 struct timeval curtime;
1329 gettimeofday(&curtime, NULL);
1330 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1332 while ( ct < end ) {
1334 gettimeofday(&curtime, NULL);
1335 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1340 * if Iter_cnt == 0, then we pre allocated space to all files
1341 * and we are starting outside loop over. Set pre_alloc_space
1342 * to zero otherwise we get in infinite loop
1344 if ( Iter_cnt == 0 ) {
1347 } /* end iteration for loop */
1351 printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
1352 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, num_files, reason);
1361 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1362 Progname, TagName, Pid, Errors);
1363 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1368 printf("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n", Progname, TagName, Pid, __FILE__, __LINE__);
1372 /***********************************************************************
1374 ***********************************************************************/
1382 * now loop through all signals and set the handlers
1385 for (sig = 1; sig < NSIG; sig++) {
1392 #endif /* SIGCKPT */
1395 #endif /* SIGRESTART */
1400 signal(sig, sig_handler);
1409 /***********************************************************************
1411 ***********************************************************************/
1418 if ( sig == SIGUSR2 ) {
1419 fprintf(stdout, "%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
1420 Progname, TagName, Pid, __FILE__, __LINE__, sig);
1421 signal(sig, sig_handler); /* allow us to get this signal more than once */
1423 } else if( sig == SIGINT ){
1424 /* The user has told us to cleanup, don't pretend it's an error. */
1427 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1428 Pid, __FILE__, __LINE__, sig);
1431 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1432 Pid, __FILE__, __LINE__, sig);
1438 printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
1439 Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
1444 /***********************************************************************
1445 * this function attempts to send SIGUSR2 to other growfiles processes
1446 * telling them to stop.
1448 ***********************************************************************/
1452 static int send_signals = 0;
1454 extern int Forker_pids[];
1455 extern int Forker_npids;
1457 if ( Sync_with_others && send_signals == 0 ) {
1459 send_signals=1; /* only send signals once */
1461 for (ind=0; ind< Forker_npids; ind++) {
1462 if ( Forker_pids[ind] != Pid )
1464 printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
1465 Progname, TagName, Pid, __FILE__, __LINE__, Forker_pids[ind]);
1466 kill(Forker_pids[ind], SIGUSR2);
1472 /***********************************************************************
1473 * this function will count the number of errors encountered.
1474 * This function will call upanic if wanted or cleanup and
1475 * and exit is Maxerrs were encountered.
1476 ***********************************************************************/
1482 if ( Maxerrs && Errors >= Maxerrs ) {
1483 printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n",
1484 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, Maxerrs);
1489 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1490 Progname, TagName, Pid, Errors);
1491 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1500 /***********************************************************************
1502 ***********************************************************************/
1508 if ( remove_files ) {
1510 printf("%s: %d DEBUG3 Removing all %d files\n",
1511 Progname, Pid, num_files);
1512 for(ind=0; ind<=num_files; ind++) {
1513 unlink(filenames+(ind*PATH_MAX));
1516 if ( using_random && Debug > 1 )
1517 printf("%s%s: %d DEBUG2 Used random seed: %d\n",
1518 Progname, TagName, Pid, Seed);
1522 /***********************************************************************
1524 ***********************************************************************/
1529 "Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
1530 Progname, TagName );
1532 "[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
1534 "[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
1536 "[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
1540 } /* end of usage */
1542 /***********************************************************************
1544 ***********************************************************************/
1551 -h Specfied to print this help and exit.\n\
1552 -b Specfied to execute in sync mode.(def async mode)\n\
1553 -B maxbytes Max bytes to consume by all files. growfiles exits when more\n\
1554 than maxbytes have been consumed. (def no chk) If maxbytes ends\n\
1555 with the letter 'b', maxbytes is multiplied by BSIZE\n\
1556 -C write_chk Specifies how often to check the last write (default 1)\n\
1557 -c file_chk Specifies how often to check whole file (default 0)\n\
1558 -d auto_dir Specifies the directory to auto created files. (default .)\n\
1559 -D debug_lvl Specifies the debug level (default 1)\n\
1560 -E Print examples and exit\n\
1561 -e errs The number errors that will terminate this program (def 100)\n\
1562 -f auto_file Specifies the base filename files created. (default \"gf\")\n\
1563 -g grow_incr Specfied to grow by incr for each num. (default 4096)\n\
1564 grow_incr may end in b for blocks\n\
1565 If -r option is used, this option is ignored and size is random\n\
1566 -H delay Amount of time to delay between each file (default 0.0)\n\
1567 -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
1568 l - listio sync, L - listio async, r - random\n\
1569 -i iteration Specfied to grow each file num times. 0 means forever (default 1)\n\
1570 -l Specfied to do file locking around write/read/trunc\n\
1571 If specified twice, file locking after open to just before close\n\
1572 -L time Specfied to exit after time secs, must be used with -i.\n\
1573 -N num_files Specifies the number of files to be created.\n\
1574 The default is zero if cmd line files.\n\
1575 The default is one if no cmd line files.\n\
1576 -n num_procs Specifies the number of copies of this cmd.\n\
1577 -o op_type Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
1578 -O offset adjust i/o buffer alignment by offset bytes\n\
1579 -P PANIC Specifies to call upanic on error.\n\
1580 -p Specifies to pre-allocate space\n\
1581 -q pattern pattern can be a - ascii, p - pid with boff, o boff (def)\n\
1582 A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
1583 c - checkboard, C - counting\n\
1584 -R [min-]max random lseek before write and trunc, max of -1 means filesz,\n\
1585 -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
1586 -r [min-]max random io write size (min def is 1)\n\
1587 -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
1588 -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
1589 -t trunc_incr Specfied the amount to shrink file. (default 4096)\n\
1590 trunc_inter may end in b for blocks\n\
1591 If -R option is used, this option is ignored and trunc is random\n\
1592 -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
1593 -u unlink files before exit\n\
1594 -U ui[-ui2] Unlink files each ui iteration (def 0)\n\
1595 -w Specfied to grow via lseek instead of writes.\n\
1596 -W tag-name Who-am-i. My Monster tag name. (used by Monster).\n\
1597 -x Re-exec children before continuing - useful on MPP systems\n\
1598 -y Attempt to sync copies - if one fails it will send sigusr2 to others\n\
1599 Action to each file every iteration is open, write, write check\n\
1600 file check, trunc and closed.\n");
1605 /***********************************************************************
1607 ***********************************************************************/
1609 prt_examples(FILE *stream)
1611 /* This example creates 200 files in directory dir1. It writes */
1612 /* 4090 bytes 100 times then truncates 408990 bytes off the file */
1613 /* The file contents are checked every 1000 grow. */
1615 "# run forever: writes of 4090 bytes then on every 100 iterval\n\
1616 # truncate file by 408990 bytes. Done to 200 files in dir1.\n\
1617 %s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n", Progname);
1619 /* same as above with 5000 byte grow and a 499990 byte tuncate */
1621 "# same as above with writes of 5000 bytes and truncs of 499990\n\
1622 %s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n", Progname);
1624 /* This example beats on opens and closes */
1626 "# runs forever: beats on opens and closes of file ocfile - no io\n\
1627 %s -i 0 -g 0 -c 0 -C 0 ocfile\n\n", Progname);
1630 "# writes 4096 to files until 50 blocks are written\n\
1631 %s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
1634 "# write one byte to 750 files in gdir then unlinks them\n\
1635 %s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
1638 "# run 30 secs: random iosize, random lseek up to eof\n\
1639 %s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
1642 "# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
1643 %s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10 g_sleek1 g_lseek2\n\n", Progname);
1646 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1647 # rand io types doing a trunc every 5 iterations, with unlinks.\n\
1648 %s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n",
1652 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1653 # random open flags, rand io types doing a trunc every 10 iterations.\n\
1654 %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",
1661 /***********************************************************************
1663 * The file descriptor current offset is assumed to be the end of the
1665 * Woffset will be set to the offset before the write.
1666 * Grow_incr will be set to the size of the write or lseek write.
1667 ***********************************************************************/
1669 growfile(fd, file, grow_incr, buf)
1680 int fsize; /* current size of file */
1681 int size_grew; /* size the file grew */
1686 * Do a stat on the open file.
1687 * If the file is a fifo, set the bit in Mode variable.
1688 * This fifo check must be done prior to growfile() returning.
1689 * Also get the current size of the file.
1691 if ( fstat(fd, &stbuf) != -1 ) {
1692 if ( S_ISFIFO(stbuf.st_mode) ) {
1693 Fileinfo.mode |= MODE_FIFO;
1696 printf("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
1697 Progname, Pid, __FILE__, __LINE__);
1699 fsize = stbuf.st_size;
1702 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1703 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1709 if ( grow_incr <= 0 ) { /* don't attempt i/o if grow_incr <= 0 */
1711 Grow_incr=grow_incr;
1713 printf("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
1714 Progname, Pid, __FILE__, __LINE__, grow_incr);
1718 if ( Mode & MODE_RAND_SIZE ) {
1719 grow_incr=random_range(min_size, max_size, mult_size, &errmsg);
1720 if (errmsg != NULL) {
1721 fprintf(stderr, "%s%s: %d %s/%d: random_range() failed - %s\n", Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
1724 Grow_incr=grow_incr;
1727 Grow_incr=grow_incr;
1729 if ( ! (Mode & MODE_FIFO) ) {
1730 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
1731 fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
1732 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1737 if ( Mode & MODE_GROW_BY_LSEEK ) {
1740 printf("%s: %d DEBUG3 %s/%d: Current size of file is %d\n", Progname,
1741 Pid, __FILE__, __LINE__, Woffset);
1742 printf("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n", Progname,
1743 Pid, __FILE__, __LINE__, grow_incr-1);
1746 if ((noffset=lseek(fd, grow_incr-1, SEEK_END)) == -1 ) {
1747 fprintf(stderr, "%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
1748 Progname, TagName, __FILE__, __LINE__, grow_incr-1, strerror(errno));
1752 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1755 ret=lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg,0);
1757 ret=write_buffer(fd, io_type, "w", 1, 0, &errmsg);
1761 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
1762 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
1763 if ( ret == -ENOSPC ) {
1772 lkfile(fd, LOCK_UN, LKLVL0);
1775 printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
1776 Progname, Pid, __FILE__, __LINE__, Iter_cnt);
1778 } else { /* end of grow by lseek */
1780 if ( Fileinfo.openflags & O_APPEND ) {
1782 * Deal with special case of the open flag containing O_APPEND.
1783 * If it does, the current offset does not matter since the write
1784 * will be done end of the file.
1787 printf("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
1788 Progname, Pid, __FILE__, __LINE__ );
1789 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1792 * do fstat again to get size of the file.
1793 * This is done inside a file lock (if locks are being used).
1795 if ( fstat(fd, &stbuf) != -1 ) {
1796 Woffset = stbuf.st_size;
1798 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1799 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1801 lkfile(fd, LOCK_UN, LKLVL0); /* release lock */
1805 printf("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
1806 Progname, Pid, __FILE__, __LINE__, (int)stbuf.st_size);
1809 } else if ( Mode & MODE_RAND_LSEEK ) {
1810 if ( max_lseek == LSK_EOF ) { /* within file size */
1811 noffset=random_range(min_lseek, fsize, 1, NULL);
1813 else if ( max_lseek == LSK_EOFPLUSGROW ) {
1814 /* max to beyond file size */
1815 noffset=random_range(min_lseek, fsize+grow_incr, 1, NULL);
1817 else if ( max_lseek == LSK_EOFMINUSGROW ) {
1819 * Attempt to not grow the file.
1820 * If the i/o will fit from min_lseek to EOF,
1821 * pick offset to allow it to fit.
1822 * Otherwise, pick the min_lseek offset and grow
1823 * file by smallest amount.
1824 * If min_lseek is != 0, there will be a problem
1825 * with whole file checking if file is ever smaller
1828 if ( fsize <= min_lseek + grow_incr )
1829 noffset=min_lseek; /* file will still grow */
1831 noffset=random_range(min_lseek, fsize-grow_incr, 1, NULL);
1834 noffset=random_range(min_lseek, max_lseek, 1, NULL);
1837 if ((Woffset=lseek(fd, noffset, SEEK_SET)) == -1 ) {
1838 fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l2 failed: %s\n",
1839 Progname, TagName, Pid, __FILE__, __LINE__, fd, noffset, strerror(errno));
1842 else if ( Debug > 2 )
1843 printf("%s: %d DEBUG3 %s/%d: lseeked to random offset %d (fsz:%d)\n",
1844 Progname, Pid, __FILE__, __LINE__, Woffset,
1845 (int)stbuf.st_size);
1850 * lseek to end of file only if not fifo
1852 else if ( ! (Mode & MODE_FIFO) ) {
1853 if ((Woffset=lseek(fd, 0, SEEK_END)) == -1 ) {
1854 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
1855 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1858 else if ( Debug > 2 )
1859 printf("%s: %d DEBUG3 %s/%d: lseeked to end of file, offset %d\n",
1860 Progname, Pid, __FILE__, __LINE__, Woffset);
1863 if ( Pattern == PATTERN_OFFSET )
1864 datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
1865 else if ( Pattern == PATTERN_PID )
1866 datapidgen(Pid, buf, grow_incr, Woffset);
1867 else if ( Pattern == PATTERN_ASCII )
1868 dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
1869 else if ( Pattern == PATTERN_RANDOM )
1870 databingen('r', buf, grow_incr, Woffset);
1871 else if ( Pattern == PATTERN_ALT )
1872 databingen('a', buf, grow_incr, Woffset);
1873 else if ( Pattern == PATTERN_CHKER )
1874 databingen('c', buf, grow_incr, Woffset);
1875 else if ( Pattern == PATTERN_CNTING )
1876 databingen('C', buf, grow_incr, Woffset);
1877 else if ( Pattern == PATTERN_ZEROS )
1878 databingen('z', buf, grow_incr, Woffset);
1879 else if ( Pattern == PATTERN_ONES )
1880 databingen('o', buf, grow_incr, Woffset);
1882 dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
1885 printf("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
1886 Progname, Pid, __FILE__, __LINE__, grow_incr);
1888 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1891 ret=write(fd, buf, grow_incr);
1895 lkfile(fd, LOCK_UN, LKLVL0);
1897 if ( ret != grow_incr) {
1898 fprintf(stderr, "%s: %s/%d: write failed: %s\n",
1899 Progname, __FILE__, __LINE__, strerror(errno));
1905 ret=lio_write_buffer(fd, io_type, (char *)buf, grow_incr,
1906 SIGUSR1, &errmsg,0);
1908 ret=write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
1911 if( Mode & MODE_FIFO ){
1912 /* If it is a fifo then just pretend the file
1913 * offset is where we think it should be.
1915 tmp = Woffset + grow_incr;
1918 if( (tmp=lseek(fd,0,SEEK_CUR)) < 0 ){ /* get offset after the write */
1919 fprintf(stderr, "%s%s: %s/%d: tell(2) failed: %d %s\n",
1920 Progname, TagName, __FILE__, __LINE__, errno, strerror(errno) );
1925 lkfile(fd, LOCK_UN, LKLVL0);
1927 if ( ret != grow_incr ) {
1928 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
1929 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
1930 if ( ret == -ENOSPC ) {
1938 * Check for a condition where the file was truncated just before
1941 if ( tmp != Woffset + grow_incr) {
1943 * The offset after the write was not as expected.
1944 * This could be caused by the following:
1945 * - file truncated after the lseek and before the write.
1946 * - the file was written to after fstat and before the write
1947 * and the file was opened with O_APPEND.
1949 * The pattern written to the file will be considered corrupted.
1951 if ( Debug > 0 && lockfile ) {
1952 printf("%s%s: %d DEBUG1 %s/%d: offset after write(%d) not as exp(%d+%d=%d)\n",
1953 Progname, TagName, Pid, __FILE__, __LINE__, tmp, Woffset, grow_incr, Woffset+grow_incr);
1954 printf("%s%s: %d DEBUG1 %s/%d: %d Assuming file changed by another process, resetting offset:%d (expect pattern mismatch)\n",
1955 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, tmp-grow_incr);
1958 printf("%s: %d DEBUG5 %s/%d: about to chop Woffset. tmp=%d, grow_incr=%d, Woffset was %d\n",
1959 Progname, Pid, __FILE__, __LINE__, tmp, grow_incr, Woffset);
1961 Woffset=tmp-grow_incr;
1966 } /* end of grow by write */
1970 * Woffset - holds start of grow (start of write expect in grow by lseek)
1971 * Grow_incr - holds size of grow (write).
1972 * fsize - holds size of file before write
1974 size_grew=(Woffset + Grow_incr) - fsize;
1976 if ( Mode & MODE_FIFO ) {
1977 printf("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
1978 Progname, Pid, __FILE__, __LINE__, Grow_incr, Iter_cnt);
1981 else if ( size_grew > 0 )
1982 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), grew file by %d bytes\n",
1983 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset, size_grew);
1985 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), did not grow file\n",
1986 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset);
1989 bytes_consumed += size_grew;
1992 } /* end of growfile */
1994 /***********************************************************************
1995 * shrinkfile file by trunc_incr. file can not be made smaller than
1996 * size zero. Therefore, if trunc_incr is larger than file size,
1997 * file will be truncated to zero.
1998 * The file descriptor current offset is assumed to be the end of the
2001 ***********************************************************************/
2003 shrinkfile(fd, filename, trunc_incr, trunc_inter, just_trunc)
2007 int trunc_inter; /* interval */
2008 int just_trunc; /* lseek has already been done for you */
2010 static int shrink_cnt = 0;
2017 if ( trunc_inter == 0 || (shrink_cnt % trunc_inter != 0)) {
2019 printf("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
2020 Progname, Pid, __FILE__, __LINE__, trunc_inter, shrink_cnt);
2021 return 0; /* not this time */
2024 if ( Mode & MODE_FIFO ) {
2026 printf("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
2027 Progname, Pid, __FILE__, __LINE__);
2028 return 0; /* can not truncate fifo */
2031 lkfile(fd, LOCK_EX, LKLVL0);
2033 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
2034 fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
2035 Progname, TagName, Pid, __FILE__, __LINE__, fd, strerror(errno));
2036 lkfile(fd, LOCK_UN, LKLVL0);
2040 if ( Mode & MODE_RAND_LSEEK ) {
2041 if ( max_lseek <= -1 ) {
2042 if ( (new_offset=file_size(fd)) == -1 ) {
2043 lkfile(fd, LOCK_UN, LKLVL0);
2047 if ( new_offset < min_lseek )
2048 new_offset=min_lseek;
2050 new_offset=random_range(min_lseek, new_offset, 1, NULL);
2053 new_offset=random_range(min_lseek, max_lseek, 1, NULL);
2057 else { /* remove trunc_incr from file */
2059 new_offset = cur_offset-trunc_incr;
2061 if ( new_offset < 0 )
2065 ret=ftruncate(fd, new_offset );
2066 if( (ret == 0) && (Debug > 3) ){
2067 printf("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
2068 Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
2071 lkfile(fd, LOCK_UN, LKLVL0);
2074 fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
2075 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
2080 printf("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
2081 Progname, Pid, __FILE__, __LINE__, cur_offset-new_offset, new_offset);
2085 bytes_consumed -= (cur_offset - new_offset);
2088 } /* end of shrinkfile */
2090 /***********************************************************************
2092 ***********************************************************************/
2094 check_write(fd, cf_inter, filename, mode)
2096 int cf_inter; /* check file interval */
2097 char *filename; /* needed for error messages */
2098 int mode; /* write mode */
2101 static int cf_count = 0;
2109 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2111 printf("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
2112 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2113 return 0; /* no check done */
2116 if ( Grow_incr <= 0 ) {
2118 printf("%s: %d DEBUG4 %s/%d: No write validation, Grow_incr = %d, offset = %d\n",
2119 Progname, Pid, __FILE__, __LINE__, Grow_incr, Woffset);
2120 return 0; /* no check */
2126 * Get the shared file lock. We need to hold the lock from before
2127 * we do the stat until after the read.
2129 lkfile(fd, LOCK_SH, LKLVL0);
2131 if ((fsize=file_size(fd)) == -1 ) {
2132 lkfile(fd, LOCK_UN, LKLVL0);
2135 } else if ( fsize <= Woffset ) {
2137 * The file was truncated between write and now.
2138 * The contents of our last write is totally gone, no check.
2141 printf("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than where last wrote (%d)- no write validation\n",
2142 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, Woffset);
2143 lkfile(fd, LOCK_UN, LKLVL0);
2144 return 0; /* no validation, but not an error */
2146 } else if ( fsize < (Woffset + Grow_incr)) {
2148 * The file was truncated between write and now.
2149 * Part of our last write has been truncated, adjust our Grow_incr
2154 Grow_incr=fsize-Woffset;
2158 printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of wrt(off:%d, sz:%d), adj=%d\n",
2159 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, tmp-Grow_incr, Woffset, tmp, Grow_incr);
2165 printf("%s: %d DEBUG3 %s/%d: about to do write validation, offset = %d, size = %d\n",
2166 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2168 if ( ! (mode & MODE_FIFO) ) {
2170 if ( lseek(fd, Woffset, 0) == -1 ) {
2171 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, 0) failed: %s\n",
2172 Progname, TagName, Pid, __FILE__, __LINE__, Woffset, strerror(errno));
2175 printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%d\n",
2176 Progname, Pid, __FILE__, __LINE__, Woffset);
2180 * Read last writes data
2183 ret=lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,0);
2185 ret=read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
2189 * report the error and debug information before releasing
2192 if ( ret != Grow_incr ) {
2193 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2198 printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n",
2199 Progname, TagName, Pid, __FILE__, __LINE__, fd,
2200 (int)lseek(fd,SEEK_CUR,0), /* FIXME: 64bit/LFS ? */
2202 Fileinfo.openflags);
2205 lkfile(fd, LOCK_UN, LKLVL0);
2210 lkfile(fd, LOCK_UN, LKLVL0);
2212 if ( Mode & MODE_GROW_BY_LSEEK ) {
2213 /* check that all zeros upto last character */
2214 for(ptr=Buffer; ptr < (Buffer+Grow_incr-1); ptr++) {
2215 if ( *ptr != '\0' ) {
2217 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2218 Progname, TagName, Pid, __FILE__, __LINE__,
2219 (int)(Woffset+(Grow_incr-(Buffer-ptr))),
2225 /* check that the last char is a 'w' */
2226 if ( *ptr != 'w' ) {
2228 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2229 Progname, TagName, Pid, __FILE__, __LINE__,
2230 (int)(Woffset+(Grow_incr-(Buffer-ptr))), 'w',
2235 return 0; /* all is well */
2238 else if ( Pattern == PATTERN_OFFSET )
2239 ret=datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
2240 else if ( Pattern == PATTERN_PID )
2241 ret=datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
2242 else if ( Pattern == PATTERN_ASCII )
2243 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2244 else if ( Pattern == PATTERN_RANDOM )
2245 ; /* no check for random */
2246 else if ( Pattern == PATTERN_ALT )
2247 ret=databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
2248 else if ( Pattern == PATTERN_CHKER )
2249 ret=databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
2250 else if ( Pattern == PATTERN_CNTING )
2251 ret=databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
2252 else if ( Pattern == PATTERN_ZEROS )
2253 ret=databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
2254 else if ( Pattern == PATTERN_ONES )
2255 ret=databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
2257 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2260 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
2261 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2264 printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, offset:%d, sz:%d open flags:%#o %s\n",
2265 Progname, TagName, Pid, __FILE__, __LINE__, fd, lockfile,
2266 Woffset, Grow_incr, Fileinfo.openflags, openflags2symbols(Fileinfo.openflags, ",", NULL));
2273 printf("%s: %d DEBUG7 %s/%d: No corruption detected on write validation , offset = %d, size = %d\n",
2274 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2276 return 0; /* all is well */
2281 /***********************************************************************
2283 ***********************************************************************/
2285 check_file(fd, cf_inter, filename, no_file_check)
2287 int cf_inter; /* check file interval */
2288 char *filename; /* needed for error messages */
2289 int no_file_check; /* if set, do not do file content check */
2292 static int cf_count = 0;
2302 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2304 printf("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
2305 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2306 return 0; /* no check done */
2310 * if we can't determine file content, don't bother checking
2312 if ( no_file_check ) {
2314 printf("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
2315 Progname, Pid, __FILE__, __LINE__);
2320 * Lock the file. We need to have the file lock before
2321 * the stat and until after the last read to prevent
2322 * a trunc/truncate from "corrupting" our data.
2324 lkfile(fd, LOCK_SH, LKLVL0);
2326 if ((fsize=file_size(fd)) == -1 ) {
2327 lkfile(fd, LOCK_UN, LKLVL0);
2333 printf("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
2334 Progname, Pid, __FILE__, __LINE__);
2336 lkfile(fd, LOCK_UN, LKLVL0);
2341 printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
2342 Progname, Pid, __FILE__, __LINE__);
2344 if ( fsize > MAX_FC_READ ) {
2346 * read the file in MAX_FC_READ chuncks.
2349 if ((buf=(char *)malloc(MAX_FC_READ)) == NULL ) {
2350 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2351 __FILE__, __LINE__, MAX_FC_READ, strerror(errno));
2352 lkfile(fd, LOCK_UN, LKLVL0);
2356 lseek(fd, 0, SEEK_SET);
2358 lkfile(fd, LOCK_SH, LKLVL0); /* get lock on file before getting file size */
2361 while (rd_cnt < fsize ) {
2362 if ( fsize - rd_cnt > MAX_FC_READ )
2363 rd_size=MAX_FC_READ;
2365 rd_size=fsize - rd_cnt;
2368 ret=lio_read_buffer(fd, io_type, buf, rd_size,
2369 SIGUSR1, &errmsg,0);
2371 ret=read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
2374 if (ret != rd_size ) {
2375 fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n",
2376 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2378 lkfile(fd, LOCK_UN, LKLVL0);
2382 read(fd, buf, rd_size);
2385 if ( Pattern == PATTERN_OFFSET )
2386 ret=datapidchk(STATIC_NUM, buf, rd_size, rd_cnt, &errmsg);
2387 else if ( Pattern == PATTERN_PID )
2388 ret=datapidchk(Pid, buf, rd_size, rd_cnt, &errmsg);
2389 else if ( Pattern == PATTERN_ASCII )
2390 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2391 else if ( Pattern == PATTERN_RANDOM )
2392 ; /* no checks for random */
2393 else if ( Pattern == PATTERN_ALT )
2394 ret=databinchk('a', buf, rd_size, rd_cnt, &errmsg);
2395 else if ( Pattern == PATTERN_CHKER )
2396 ret=databinchk('c', buf, rd_size, rd_cnt, &errmsg);
2397 else if ( Pattern == PATTERN_CNTING )
2398 ret=databinchk('C', buf, rd_size, rd_cnt, &errmsg);
2399 else if ( Pattern == PATTERN_ZEROS )
2400 ret=databinchk('z', buf, rd_size, rd_cnt, &errmsg);
2401 else if ( Pattern == PATTERN_ONES )
2402 ret=databinchk('o', buf, rd_size, rd_cnt, &errmsg);
2404 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2409 "%s%s: %d %s/%d: %d CFp %s in file %s\n",
2410 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2413 lkfile(fd, LOCK_UN, LKLVL0);
2419 lkfile(fd, LOCK_UN, LKLVL0);
2426 * Read the whole file in a single read
2428 if((buf=(char *)malloc(fsize)) == NULL ) {
2429 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2430 __FILE__, __LINE__, fsize, strerror(errno));
2435 lseek(fd, 0, SEEK_SET);
2438 read(fd, buf, fsize);
2441 ret=lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,0);
2443 ret=read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
2446 /* unlock the file as soon as we can */
2447 lkfile(fd, LOCK_UN, LKLVL0);
2450 if ( ret != fsize ) {
2451 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n",
2452 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2456 if ( Pattern == PATTERN_OFFSET )
2457 ret=datapidchk(STATIC_NUM, buf, fsize, 0, &errmsg);
2458 else if ( Pattern == PATTERN_PID )
2459 ret=datapidchk(Pid, buf, fsize, 0, &errmsg);
2460 else if ( Pattern == PATTERN_ASCII )
2461 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2462 else if ( Pattern == PATTERN_RANDOM )
2463 ; /* no check for random */
2464 else if ( Pattern == PATTERN_ALT )
2465 ret=databinchk('a', buf, fsize, 0, &errmsg);
2466 else if ( Pattern == PATTERN_CHKER )
2467 ret=databinchk('c', buf, fsize, 0, &errmsg);
2468 else if ( Pattern == PATTERN_CNTING )
2469 ret=databinchk('C', buf, fsize, 0, &errmsg);
2470 else if ( Pattern == PATTERN_ZEROS )
2471 ret=databinchk('z', buf, fsize, 0, &errmsg);
2472 else if ( Pattern == PATTERN_ONES )
2473 ret=databinchk('o', buf, fsize, 0, &errmsg);
2475 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2478 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s in file %s\n",
2479 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2489 } /* end of check_file */
2491 /***********************************************************************
2493 ***********************************************************************/
2499 if (fstat(fd, &sb) < 0) {
2500 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
2501 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
2509 /***********************************************************************
2510 * do file lock/unlock action.
2511 ***********************************************************************/
2513 lkfile(int fd, int operation, int lklevel)
2518 if ( lockfile == lklevel) {
2521 switch (operation) {
2523 printf("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n",
2524 Progname, Pid, __FILE__, __LINE__, fd);
2528 printf("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n",
2529 Progname, Pid, __FILE__, __LINE__, fd);
2533 printf("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n",
2534 Progname, Pid, __FILE__, __LINE__, fd);
2540 * Attempt to get/release desired lock.
2541 * file_lock will attempt to do action over and over again until
2542 * either an unretryable error or the action is completed.
2545 if ( file_lock(fd, operation, &errmsg) != 0 ) {
2546 printf("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
2547 Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
2549 /* do we count this as an error? handle_error(); */
2554 switch (operation) {
2556 printf("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n",
2557 Progname, Pid, __FILE__, __LINE__, fd);
2561 printf("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n",
2562 Progname, Pid, __FILE__, __LINE__, fd);
2566 printf("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n",
2567 Progname, Pid, __FILE__, __LINE__, fd);
2571 printf("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n",
2572 Progname, Pid, __FILE__, __LINE__, operation, fd);
2581 /***********************************************************************
2583 ***********************************************************************/
2585 pre_alloc(file, fd, size)
2591 #ifdef XFS_IOC_RESVSP
2592 struct xfs_flock64 f;
2598 /* non-zeroing reservation */
2599 if( xfsctl( file, fd, XFS_IOC_RESVSP, &f ) == -1 ){
2600 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: xfsctl(XFS_IOC_RESVSP) failed: %d %s\n",
2602 __FILE__, __LINE__, errno, strerror(errno));
2612 /* non-zeroing reservation */
2613 if( fcntl( fd, F_RESVSP64, &f ) == -1 ){
2614 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: fcntl(F_RESVSP) failed: %d %s\n",
2616 __FILE__, __LINE__, errno, strerror(errno));