1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000 Silicon Graphics, Inc.
7 * This program will grow a list of files.
8 * Each file will grow by grow_incr before the same
9 * file grows twice. Each file is open and closed before next file is opened.
11 * To just verify file contents: growfiles -g 0 -c 1 filename
13 * See help and prt_examples functions below.
17 * print debug message about options used
18 * setup signal handlers
19 * return control to user (if wanted - default action)
20 * fork number of desired childern (if wanted)
21 * re-exec self (if wanted)
22 * Determine number of files
23 * malloc space or i/o buffer
24 * Loop until stop is set
25 * Determine if hit iteration, time, max errors or num bytes reached
26 * Loop through each file
28 * fstat file - to determine if file is a fifo
29 * prealloc file space (if wanted)
38 * remove all files (if wanted)
40 * Author: Richard Logan
46 #ifdef HAVE_SYS_FILE_H
50 #include "dataascii.h"
51 #include "random_range.h"
53 #include "open_flags.h"
55 #include "file_lock.h"
57 extern int datapidgen(int pid, unsigned char *buffer, int bsize, int offset);
58 extern void databingen(int mode, unsigned char *buffer, int bsize, int offset);
59 extern int datapidchk(int pid, char *buffer, int bsize, int offset, char **errmsg);
60 extern int databinchk(int mode, char *buffer, int bsize, int offset, char **errmsg);
62 int file_size(int fd);
63 int check_write(int fd, int cf_inter, char *filename, int mode);
64 int shrinkfile(int fd, char *filename, int trunc_incr, int trunc_inter, int just_trunc);
65 int check_file(int fd, int cf_inter, char *filename, int no_file_check);
66 int growfile(int fd, char *file, int grow_incr, unsigned char *buf);
69 int lkfile(int fd, int operation, int lklevel);
72 void prt_examples(FILE *stream);
75 static void notify_others();
76 int pre_alloc(char *file, int fd, int size);
79 #define NEWIO 1 /* Use the tlibio.c functions */
82 #define NEWIO 0 /* specifies to use original iowrite.c */
83 /* functions instead of tlibio.c functions */
84 /* Once it is proven tlibio.c functions work properly, */
85 /* only tlibio.c functions will be used */
103 int io_type = 0; /* I/O type -sync */
104 int open_flags = O_RDWR|O_CREAT; /* open flags */
106 #define MAX_FC_READ 196608 /* 4096 * 48 - 48 blocks */
108 #define PATTERN_ASCII 1 /* repeating alphabet letter pattern */
109 /* allows multiple writers and to be checked */
110 #define PATTERN_PID 2 /* <pid><words byte offset><pid> */
111 /* Assumes 64 bit word. Only allows single */
112 /* process to write and check */
114 * 1234567890123456789012345678901234567890123456789012345678901234
115 * ________________________________________________________________
116 * < pid >< offset in file of this word >< pid >
119 #define PATTERN_OFFSET 3 /* Like PATTERN_PID but has a fixed number */
120 /* (STATIC_NUM) instead of pid. */
121 /* Allows multiple processes to write/read */
122 #define PATTERN_ALT 4 /* alternating bit pattern (i.e. 0x5555555...) */
123 #define PATTERN_CHKER 5 /* checkerboard pattern (i.e. 0xff00ff00ff00...) */
124 #define PATTERN_CNTING 6 /* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
125 #define PATTERN_ONES 7 /* all bits set (i.e. 0xffffffffffffff...) */
126 #define PATTERN_ZEROS 8 /* all bits cleared (i.e. 0x000000000...) */
127 #define PATTERN_RANDOM 9 /* random integers - can not be checked */
128 #define STATIC_NUM 221849 /* used instead of pid when PATTERN_OFFSET */
130 #define MODE_RAND_SIZE 1 /* random write and trunc */
131 #define MODE_RAND_LSEEK 2 /* random lseek before write */
132 #define MODE_GROW_BY_LSEEK 4 /* lseek beyond end of file then write a byte */
133 #define RANDOM_OPEN 999876 /* if Open_flags set to this value, open flags */
134 /* will be randomly choosen from Open_flags[] */
135 #define MODE_FIFO S_IFIFO /* defined in stat.h 0010000 */
137 int num_files = 0; /* num_auto_files + cmd line files */
138 char *filenames; /* pointer to space containing filenames */
139 int remove_files = 0; /* if set, cleanup default is not to cleanup */
140 int bytes_consumed = 0; /* total bytes consumed, all files */
141 int bytes_to_consume = 0; /* non-zero if -B was specified, total bytes */
142 int Maxerrs = 100; /* Max number errors before forced exit */
143 int Errors = 0; /* number of encountered errors */
144 int Upanic_on_error = 0; /* call upanic if error and this variable set */
146 /* The *_size variables are only used when random iosize option (-r) is used */
148 int min_size=1; /* also set in option parsing */
149 int mult_size=1; /* when random iosz, iosz must be mult of mult_size */
150 /* the *_lseek variables are only used when radon lseek option (-R) is used */
151 int min_lseek=0; /* also set in option parsing */
152 int max_lseek=-1; /* -1 means size of file */
153 int Pattern=PATTERN_ASCII;
154 int Seed=-1; /* random number seed, < 0 == uninitialized */
155 int Nseeds=0; /* Number of seed specified by the user */
156 int *Seeds; /* malloc'ed arrary of ints holding user spec seeds */
158 int using_random=0; /* flag indicating randomization is being used */
159 float delaysecs=0.0; /* delay between iterations (in seconds) */
160 int delaytime; /* delay between iterations in clocks/uses */
161 int lockfile=0; /* if set, do file locking */
162 /* 1 = do file locking around write, trunc */
164 /* 2 = write lock around all file operations */
166 int Woffset=0; /* offset before last write */
167 int Grow_incr=4096; /* sz of last write */
168 int Mode=0; /* bitmask of write/trunc mode */
169 /* also knows if dealing with fifo */
170 char *Buffer = NULL; /* buffer used by write and write check */
171 int Alignment=0; /* if non word multiple, io will not be word aligned */
172 int Opid=0; /* original pid */
174 int Sync_with_others = 0; /* Flag indicating to stop other if we stop before DONE */
175 int Iter_cnt = 0; /* contains current iteration count value */
176 char TagName[40]; /* name of this growfiles (see Monster) */
186 * Define open flags that will be used when '-o random' option is used.
187 * Note: If there is more than one growfiles doing its thing to the same
188 * file, O_TRUNC will cause data mismatches. How you ask?
189 * timing of events, example:
190 * Process one Process two
191 * --------------- -------------
197 * write with wrong pattern
198 * because offset is wrong
200 * The second process truncated the file after the pattern was
201 * determined, thus the pattern is wrong for the file location.
203 * There can also be a timing problem with open flag O_APPEND if
204 * file locks are not being used (-l option). Things could happen
205 * between the fstat and the write. Thus, writing the wrong pattern.
206 * If all processes observe the file locks, O_APPEND should be ok
211 O_RDWR|O_CREAT|O_APPEND,
212 O_RDWR|O_CREAT|O_NDELAY,
213 O_RDWR|O_CREAT|O_SYNC,
214 O_RDWR|O_CREAT|O_SYNC|O_NDELAY,
215 O_RDWR|O_CREAT|O_APPEND|O_NDELAY,
219 #define REXEC_INIT 0 /* don't do re-exec of childern */
220 #define REXEC_DOIT 1 /* Do re-exec of childern */
221 #define REXEC_DONE 2 /* We've already been re-exec'ed */
227 #define USECS_PER_SEC 1000000 /* microseconds per second */
230 * Define marcos used when dealing with file locks.
232 #define LKLVL0 1 /* file lock around write/read/trunc */
233 #define LKLVL1 2 /* file lock after open to before close */
236 * Define special max lseek values
238 #define LSK_EOF -1 /* set fptr up to EOF */
239 #define LSK_EOFPLUSGROW -2 /* set fptr up to EOF + grow - leave whole */
240 #define LSK_EOFMINUSGROW -3 /* set fptr up to EOF-grow - no grow */
243 /***********************************************************************
245 ***********************************************************************/
251 extern char *optarg; /* used by getopt */
256 int first_file_ind = 0;
257 int num_auto_files = 0; /* files created by tool */
258 int seq_auto_files = 0; /* auto files created by tool created by tool */
259 char *auto_dir = DEF_DIR;
260 char *auto_file = DEF_FILE;
261 int grow_incr = 4096;
262 int trunc_incr = 4096;
263 int trunc_inter = 0; /* 0 means none, */
264 int unlink_inter = 0; /* 0 means none, 1 means always unlink */
265 int unlink_inter_ran = -1; /* -1 -use unlink_inter, otherwise randomly choose */
266 /* between unlink_inter and unlink_inter_ran */
267 int file_check_inter = 0; /* 0 means never, 1 means always */
268 int write_check_inter = 1; /* 0 means never, 1 means always */
269 int iterations = 1; /* number of increments to be added */
270 int no_file_check = 0; /* if set, no whole file checking will be done */
272 int fd; /* file descriptor */
273 int stop = 0; /* loop stopper if set */
277 int pre_alloc_space = 0;
278 int total_grow_value = 0; /* used in pre-allocations */
279 int backgrnd = 1; /* return control to user */
281 int time_iterval = -1;
282 time_t start_time = 0;
283 char reason[40]; /* reason for loop termination */
286 int reexec=REXEC_INIT; /* reexec info */
287 char *exec_path=NULL;
291 char *filename; /* name of file specified by user */
292 char *cptr; /* temp char pointer */
293 extern int Forker_npids; /* num of forked pid, defined in forker.c */
296 if ( argv[0][0] == '-' )
299 * Determine name of file used to invoke this program
301 if ((Progname=strrchr(argv[0], '/')) != NULL)
311 while ((ind=getopt(argc, argv,
312 "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) {
320 switch (sscanf(optarg, "%i%c",
321 &bytes_to_consume, &chr)) {
327 bytes_to_consume *= BSIZE;
330 "%s%s: --B option arg invalid\n",
338 fprintf(stderr, "%s%s: --B option arg invalid\n",
348 prt_examples(stdout);
351 case 'b' : /* batch */
356 if (sscanf(optarg, "%i", &write_check_inter) != 1 ) {
357 fprintf(stderr, "%s%s: --c option arg invalid\n",
365 if (sscanf(optarg, "%i", &file_check_inter) != 1 ) {
366 fprintf(stderr, "%s%s: --c option arg invalid\n",
376 if ( stat(auto_dir, &statbuf) == -1 ) {
377 if ( mkdir(auto_dir, 0777) == -1 ) {
378 if ( errno != EEXIST ) {
380 "%s%s: Unable to make dir %s\n",
381 Progname, TagName, auto_dir);
387 if ( ! (statbuf.st_mode & S_IFDIR) ) {
389 "%s%s: %s already exists and is not a directory\n",
390 Progname, TagName, auto_dir);
397 if (sscanf(optarg, "%i", &Debug) != 1 ) {
398 fprintf(stderr, "%s%s: --D option arg invalid\n",
406 if (sscanf(optarg, "%i", &Maxerrs) != 1 ) {
407 fprintf(stderr, "%s%s: --e option arg invalid\n",
419 if ((ret=sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1 ||
422 fprintf(stderr, "%s%s: --g option arg invalid\n",
428 if ( chr == 'b' || chr == 'B' )
432 "%s%s: --g option arg invalid\n",
441 if (sscanf(optarg, "%f", &delaysecs) != 1 || delaysecs < 0 ) {
443 fprintf(stderr, "%s%s: --H option arg invalid\n",
451 if (sscanf(optarg, "%i", &iterations) != 1 ||
454 fprintf(stderr, "%s%s: --i option arg invalid\n",
463 if((io_type=lio_parse_io_arg1(optarg)) == -1 ) {
465 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
469 if( io_type & LIO_RANDOM )
472 if((io_type=parse_io_arg(optarg)) == -1 ) {
474 "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
478 if( io_type == 99 ) /* hold-over until tlibio.h */
486 lockfile=2; /* lockfile can only be 1 or 2 */
490 if (sscanf(optarg, "%i", &time_iterval) != 1 ||
492 fprintf(stderr, "%s%s: --L option arg invalid\n",
500 if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) < 1 ||
503 fprintf(stderr, "%s%s: --n option arg invalid\n",
512 if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
513 num_auto_files < 0 ) {
515 fprintf(stderr, "%s%s: --N option arg invalid\n",
523 if (sscanf(optarg, "%i", &Alignment) != 1 ||
524 num_auto_files < 0 ) {
526 fprintf(stderr, "%s%s: --O option arg invalid\n",
534 if ( strcmp(optarg, "random") == 0 ){
535 open_flags=RANDOM_OPEN;
538 } else if ((open_flags=parse_open_flags(optarg, NULL)) == -1 ) {
539 fprintf(stderr, "%s%s: --o arg contains invalid flag\n",
546 case 'p' : /* pre allocate space */
547 printf("%s%s: --p is illegal option on this system\n",
553 printf("%s%s: --P is illegal option on non-cray system\n",
558 case 'q': /* file content or pattern */
561 Pattern = PATTERN_ALT;
564 Pattern = PATTERN_ASCII;
567 Pattern = PATTERN_PID;
570 Pattern = PATTERN_OFFSET;
573 Pattern = PATTERN_CHKER;
576 Pattern = PATTERN_CNTING;
579 Pattern = PATTERN_RANDOM;
583 Pattern = PATTERN_ZEROS;
586 Pattern = PATTERN_ONES;
590 "%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
597 case 'R': /* random lseek before write arg: [min-]max*/
598 if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) != 2 ) {
599 min_lseek=1; /* same as default in define */
600 if (sscanf(optarg, "%i%c", &max_lseek, &chr) != 1 ) {
601 fprintf(stderr, "%s%s: --R option arg invalid: [min-]max\n",
606 if ( max_lseek < LSK_EOFMINUSGROW ) {
607 fprintf(stderr, "%s%s: --R option, max_lseek is invalid\n",
611 Mode |= MODE_RAND_LSEEK;
615 case 'r': /* random io size arg: [min-]max[:mult] */
617 /* min-max:mult format */
618 if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
619 &mult_size, &chr) != 3 ) {
621 /* max:mult format */
622 if (sscanf(optarg, "%i:%i%c", &max_size,
623 &mult_size, &chr) != 2 ) {
625 if (sscanf(optarg, "%i-%i%c", &min_size,
626 &max_size, &chr) != 2 ) {
628 if (sscanf(optarg, "%i%c", &max_size, &chr) != 1 ) {
630 "%s%s: --r option arg invalid: [min-]max[:mult]\n",
638 if ( max_size < 0 ) {
639 fprintf(stderr, "%s%s: --r option, max_size is invalid\n",
644 * If min and max are the same, no randomness
646 if ( min_size != max_size ) {
647 Mode |= MODE_RAND_SIZE;
653 if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
654 seq_auto_files < 0 ) {
656 fprintf(stderr, "%s%s: --S option arg invalid\n",
663 case 's': /* format: seed[,seed...] */
665 /* count the number of seeds */
667 for(Nseeds=1; *cptr ; Nseeds++) {
668 if ( (filename=strchr(cptr, ',')) == NULL )
673 Seeds=(int *)malloc(Nseeds*sizeof(int));
676 * check that each seed is valid and put them in
677 * the newly malloc'ed Seeds arrary.
679 filename=cptr=optarg;
680 for(Nseeds=0; *cptr; Nseeds++) {
681 if ( (filename=strchr(cptr, ',')) == NULL ) {
682 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
683 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
684 Progname, TagName, cptr);
693 if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
694 fprintf(stderr, "%s%s: --s option arg %s invalid\n",
695 Progname, TagName, cptr);
699 *filename=','; /* restore string */
706 if ((ret=sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1 ||
709 fprintf(stderr, "%s%s: --t option arg invalid\n",
715 if ( chr == 'b' || chr == 'B' )
719 "%s%s: --t option arg invalid\n",
727 case 'T': /* truncate interval */
728 if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
731 fprintf(stderr, "%s%s: --T option arg invalid\n",
742 case 'U': /* how often to unlink file */
745 * A-B - randomly pick interval between A and B
746 * X - unlink file every X iteration
748 if (sscanf(optarg, "%i-%i", &unlink_inter,
749 &unlink_inter_ran) == 2 ) {
751 if ( unlink_inter < 0 || unlink_inter_ran < 0 ) {
752 fprintf(stderr, "%s%s: --U option arg invalid\n",
757 /* ensure unlink_inter contains smaller value */
758 if ( unlink_inter > unlink_inter_ran ) {
759 tmp=unlink_inter_ran;
760 unlink_inter_ran=unlink_inter;
765 } else if (sscanf(optarg, "%i%c", &unlink_inter, &chr) != 1 ||
768 fprintf(stderr, "%s%s: --U option arg invalid\n",
776 if ( reexec != REXEC_DONE )
781 Mode |= MODE_GROW_BY_LSEEK;
785 sprintf( TagName, "(%.37s)", optarg );
800 cptr = getenv("TOUTPUT");
801 if( (cptr != NULL) && (strcmp( cptr, "NOPASS" ) == 0) ){
806 if ( Pattern == PATTERN_RANDOM ) {
808 if ( write_check_inter || file_check_inter )
809 printf("%s%s: %d Using random pattern - no data checking will be performed!\n",
810 Progname, TagName, (int)getpid());
812 else if ( max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK ) {
815 if ( file_check_inter )
816 printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
817 no whole file checking will be performed!\n", Progname, TagName, (int)getpid());
821 if ( Mode & MODE_RAND_SIZE )
831 printf("%s: %d DEBUG2 forking, returning control to the user\n",
833 background(Progname); /* give user their prompt back */
838 lio_set_debug(Debug-3);
840 set_iowrite_debug(Debug-3);
845 * Print some program information here if debug is turned on to
851 if ( Mode & MODE_GROW_BY_LSEEK )
852 printf("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
854 else if ( Pattern == PATTERN_OFFSET )
855 printf("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
856 Progname, Pid, STATIC_NUM, STATIC_NUM);
857 else if ( Pattern == PATTERN_PID )
858 printf("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
860 else if ( Pattern == PATTERN_ASCII )
861 printf("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
863 else if ( Pattern == PATTERN_ALT )
864 printf("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
866 else if ( Pattern == PATTERN_CHKER )
867 printf("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
869 else if ( Pattern == PATTERN_CNTING )
870 printf("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
872 else if ( Pattern == PATTERN_RANDOM )
873 printf("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
875 else if ( Pattern == PATTERN_ONES )
876 printf("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
878 else if ( Pattern == PATTERN_ZEROS )
879 printf("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
883 printf("%s: %d DEBUG3 unknown pattern\n",
885 if ( bytes_to_consume )
886 printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
887 Progname, Pid, bytes_to_consume);
888 printf("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n",
889 Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
891 printf("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
892 Progname, Pid, Debug, remove_files);
894 printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
896 if ( open_flags == RANDOM_OPEN )
897 printf("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n", Progname,
900 printf("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n", Progname,
901 Pid, open_flags, io_type);
903 if ( Mode & MODE_RAND_SIZE ) {
904 printf("%s: %d DEBUG3 random write/trunc: min=%d, max=%d, mult = %d\n",
905 Progname, Pid, min_size, max_size, mult_size);
908 printf("%s: %d DEBUG3 grow_incr = %d\n",
909 Progname, Pid, grow_incr);
911 if ( Mode & MODE_RAND_LSEEK ) {
912 if ( max_lseek == LSK_EOF )
913 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile>\n",
914 Progname, Pid, min_lseek);
915 else if ( max_lseek == LSK_EOFPLUSGROW )
916 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile+iosize>\n",
917 Progname, Pid, min_lseek);
918 else if ( max_lseek == LSK_EOFMINUSGROW )
919 printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile-iosize>\n",
920 Progname, Pid, min_lseek);
922 printf("%s: %d DEBUG3 random lseek: min=%d, max=%d\n",
923 Progname, Pid, min_lseek, max_lseek);
926 printf("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
927 Progname, Pid, write_check_inter, file_check_inter);
929 printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
930 Progname, Pid, trunc_inter, trunc_incr);
933 printf("%s: %d DEBUG3 no whole file checking will be done\n",
936 if ( unlink_inter_ran == -1 ) {
937 printf("%s: %d DEBUG3 unlink_inter = %d\n",
938 Progname, Pid, unlink_inter);
940 printf("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n",
941 Progname, Pid, unlink_inter, unlink_inter_ran);
945 num=sizeof(Open_flags)/sizeof(int);
946 printf("%s: %d DEBUG9 random open flags values:\n", Progname, Pid);
947 for(ind=0; ind<num; ind++) {
948 printf("\t%#o\n", Open_flags[ind]);
951 } /* end of DEBUG > 2 */
953 if ( Debug > 1 && num_procs > 1 ) {
954 printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
958 fflush(stdout); /* ensure pending i/o is flushed before forking */
961 forker(num_procs, forker_mode, Progname);
963 Pid=getpid(); /* reset after the forks */
965 * If user specified random seed(s), get that random seed value.
966 * get random seed if it was not specified by the user.
967 * This is done after the forks, because pid is used to get the seed.
971 * If only one seed specified, all processes will get that seed.
974 } else if ( Nseeds > 1 ) {
976 * More than one seed was specified.
977 * The original process gets the first seed. Each
978 * process will be get the next seed in the specified list.
984 * If user didn't specify enough seeds, use default method.
986 if ( Forker_npids >= Nseeds )
987 Seed=time(0) + Pid; /* default random seed */
989 Seed=Seeds[Forker_npids];
994 * Generate a random seed based on time and pid.
995 * It has a good chance of being unique for each pid.
997 Seed=time(0) + Pid; /* default random seed */
1000 random_range_seed(Seed);
1002 if ( using_random && Debug > 0 )
1003 printf("%s%s: %d DEBUG1 Using random seed of %d\n",
1004 Progname, TagName, Pid, Seed);
1006 if ( unlink_inter_ran > 0 ) {
1008 * Find unlinking file interval. This must be done after
1009 * the seed was set. This allows multiple copies to
1010 * get different intervals.
1013 unlink_inter=random_range(tmp, unlink_inter_ran, 1, NULL);
1016 printf("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
1017 Progname, Pid, unlink_inter, tmp, unlink_inter_ran);
1021 * re-exec all childern if reexec is set to REXEC_DOIT.
1022 * This is useful on MPP systems to get the
1023 * child process on another PE.
1025 if ( reexec == REXEC_DOIT && Opid != Pid ) {
1026 if ( exec_path == NULL ) {
1027 exec_path = argv[0];
1028 /* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
1029 argv[0] = (char *)malloc(strlen(exec_path) + 2);
1030 sprintf(argv[0], "-%s", exec_path);
1034 printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
1035 Progname, Pid, __FILE__, __LINE__, argv[0]);
1037 execvp(argv[0], argv);
1040 /*** begin filename stuff here *****/
1042 * Determine the number of files to be dealt with
1044 if ( optind == argc ) {
1046 * no cmd line files, therfore, set
1047 * the default number of auto created files
1049 if ( ! num_auto_files && ! seq_auto_files )
1053 first_file_ind=optind;
1054 num_files += argc-optind;
1057 if ( num_auto_files ) {
1058 num_files += num_auto_files;
1061 if ( seq_auto_files ) {
1062 num_files += seq_auto_files;
1066 * get space for file names
1068 if ((filenames=(char *)malloc(num_files*PATH_MAX)) == NULL) {
1069 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1070 Progname, TagName, Pid, __FILE__, __LINE__, num_files*PATH_MAX,
1076 * fill in filename cmd files then auto files.
1080 if ( first_file_ind ) {
1081 for(ind=first_file_ind; ind<argc; ind++, num++) {
1082 strcpy((char *)filenames+(num*PATH_MAX), argv[ind]);
1087 * construct auto filename and insert them into filenames space
1089 for(ind=0;ind<num_auto_files; ind++, num++) {
1090 sprintf((char *)filenames+(num*PATH_MAX), "%s/%s.%d",
1091 auto_dir, auto_file, ind);
1095 * construct auto seq filenames
1097 for(ind=1; ind<=seq_auto_files; ind++, num++) {
1098 sprintf((char *)filenames+(num*PATH_MAX), "%s/%s%d",
1099 auto_dir, auto_file, ind);
1102 /**** end filename stuff ****/
1104 if ( time_iterval > 0 )
1108 * get space for I/O buffer
1111 if ((Buffer=(char *)malloc(grow_incr+Alignment)) == NULL) {
1112 fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
1113 Progname, TagName, Pid, __FILE__, __LINE__, grow_incr, strerror(errno));
1117 Buffer = Buffer + Alignment;
1122 printf("%s: %d DEBUG3 num_files = %d\n",
1123 Progname, Pid, num_files);
1126 if ( pre_alloc_space ) {
1127 if ( iterations == 0 ) {
1128 fprintf(stderr, "%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
1129 Progname, TagName, Pid, __FILE__, __LINE__);
1132 if ( Mode & MODE_RAND_SIZE ) {
1134 "%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
1135 Progname, TagName, Pid, __FILE__, __LINE__);
1139 total_grow_value=grow_incr * iterations;
1144 if ( bytes_to_consume && bytes_to_consume < total_grow_value ) {
1145 total_grow_value=bytes_to_consume;
1150 * If delaying between iterations, get amount time to
1151 * delaysecs in clocks or usecs.
1154 delaytime=(int)((float)USECS_PER_SEC * delaysecs);
1158 * This is the main iteration loop.
1159 * Each iteration, all files can be opened, written to,
1160 * read to check the write, check the whole file,
1161 * truncated, and closed.
1163 for(Iter_cnt=1; ! stop ; Iter_cnt++) {
1165 if ( iterations && Iter_cnt >= iterations+1 ) {
1166 strcpy(reason, "Hit iteration value");
1171 if ( (time_iterval > 0) && (start_time + time_iterval < time(0)) ) {
1172 sprintf(reason, "Hit time value of %d", time_iterval);
1177 if ( bytes_to_consume && bytes_consumed >= bytes_to_consume) {
1178 sprintf(reason, "Hit bytes consumed value of %d", bytes_to_consume);
1184 * This loop will loop through all files.
1185 * Each iteration, a single file can be opened, written to,
1186 * read to check the write, check the whole file,
1187 * truncated, and closed.
1189 for(ind=0; ind<num_files; ind++) {
1194 filename=(char *)filenames+(ind*PATH_MAX);
1195 Fileinfo.filename=(char *)filenames+(ind*PATH_MAX);
1198 if ( open_flags == RANDOM_OPEN ) {
1199 ret=Open_flags[random_range(0, sizeof(Open_flags)/sizeof(int)-1, 1, NULL)];
1205 Fileinfo.openflags=ret;
1208 printf("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
1209 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret,
1210 openflags2symbols(ret, ",", 0));
1211 } else if ( Debug > 2 ) {
1212 printf("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
1213 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret);
1217 * open file with desired flags.
1219 if ( (fd=open(filename, ret, 0777)) == -1 ) {
1221 "%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
1222 Progname, TagName, Pid, __FILE__, __LINE__, filename, ret, errno, strerror(errno));
1229 lkfile(fd, LOCK_EX, LKLVL1); /* lock if lockfile is LKLVL1 */
1232 * preallocation is only done once, if specified.
1234 if ( pre_alloc_space ) {
1235 if (pre_alloc(filename, fd, total_grow_value) != 0 ) {
1240 printf("%s: %d DEBUG2 %s/%d: pre_allocated %d for file %s\n",
1241 Progname, Pid, __FILE__, __LINE__, total_grow_value, filename);
1243 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1245 Iter_cnt=0; /* reset outside loop to restart from one */
1250 * grow file by desired amount.
1251 * growfile() will set the Grow_incr variable and
1252 * possiblly update the Mode variable indicating
1253 * if we are dealing with a FIFO file.
1256 if (growfile(fd, filename, grow_incr, (unsigned char *)Buffer) != 0 ) {
1258 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1264 * check if last write is not corrupted
1266 if ( check_write(fd, write_check_inter, filename,
1272 * Check that whole file is not corrupted.
1274 if ( check_file(fd, file_check_inter, filename,
1275 no_file_check) != 0 ) {
1280 * shrink file by desired amount if it is time
1283 if ( shrinkfile(fd, filename, trunc_incr, trunc_inter, Mode) != 0 ) {
1287 lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
1290 printf("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n",
1291 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, fd);
1295 * Unlink the file if that is desired
1297 if ( unlink_inter && (Iter_cnt % unlink_inter == 0) ) {
1300 printf("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n",
1301 Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename);
1307 * delay while staying active for "delaysecs" seconds.
1312 struct timeval curtime;
1313 gettimeofday(&curtime, NULL);
1314 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1316 while ( ct < end ) {
1318 gettimeofday(&curtime, NULL);
1319 ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
1324 * if Iter_cnt == 0, then we pre allocated space to all files
1325 * and we are starting outside loop over. Set pre_alloc_space
1326 * to zero otherwise we get in infinite loop
1328 if ( Iter_cnt == 0 ) {
1331 } /* end iteration for loop */
1335 printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
1336 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, num_files, reason);
1345 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1346 Progname, TagName, Pid, Errors);
1347 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1352 printf("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n", Progname, TagName, Pid, __FILE__, __LINE__);
1356 /***********************************************************************
1358 ***********************************************************************/
1366 * now loop through all signals and set the handlers
1369 for (sig = 1; sig < NSIG; sig++) {
1376 #endif /* SIGCKPT */
1379 #endif /* SIGRESTART */
1384 signal(sig, sig_handler);
1393 /***********************************************************************
1395 ***********************************************************************/
1402 if ( sig == SIGUSR2 ) {
1403 fprintf(stdout, "%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
1404 Progname, TagName, Pid, __FILE__, __LINE__, sig);
1405 signal(sig, sig_handler); /* allow us to get this signal more than once */
1407 } else if( sig == SIGINT ){
1408 /* The user has told us to cleanup, don't pretend it's an error. */
1411 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1412 Pid, __FILE__, __LINE__, sig);
1415 fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
1416 Pid, __FILE__, __LINE__, sig);
1422 printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
1423 Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
1428 /***********************************************************************
1429 * this function attempts to send SIGUSR2 to other growfiles processes
1430 * telling them to stop.
1432 ***********************************************************************/
1436 static int send_signals = 0;
1438 extern int Forker_pids[];
1439 extern int Forker_npids;
1441 if ( Sync_with_others && send_signals == 0 ) {
1443 send_signals=1; /* only send signals once */
1445 for (ind=0; ind< Forker_npids; ind++) {
1446 if ( Forker_pids[ind] != Pid ) {
1448 printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
1449 Progname, TagName, Pid, __FILE__, __LINE__, Forker_pids[ind]);
1450 kill(Forker_pids[ind], SIGUSR2);
1457 /***********************************************************************
1458 * this function will count the number of errors encountered.
1459 * This function will call upanic if wanted or cleanup and
1460 * and exit is Maxerrs were encountered.
1461 ***********************************************************************/
1467 if ( Maxerrs && Errors >= Maxerrs ) {
1468 printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n",
1469 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, Maxerrs);
1474 printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
1475 Progname, TagName, Pid, Errors);
1476 printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
1485 /***********************************************************************
1487 ***********************************************************************/
1493 if ( remove_files ) {
1495 printf("%s: %d DEBUG3 Removing all %d files\n",
1496 Progname, Pid, num_files);
1497 for(ind=0; ind<=num_files; ind++) {
1498 unlink(filenames+(ind*PATH_MAX));
1501 if ( using_random && Debug > 1 )
1502 printf("%s%s: %d DEBUG2 Used random seed: %d\n",
1503 Progname, TagName, Pid, Seed);
1507 /***********************************************************************
1509 ***********************************************************************/
1514 "Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
1515 Progname, TagName );
1517 "[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
1519 "[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
1521 "[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
1525 } /* end of usage */
1527 /***********************************************************************
1529 ***********************************************************************/
1536 -h Specfied to print this help and exit.\n\
1537 -b Specfied to execute in sync mode.(def async mode)\n\
1538 -B maxbytes Max bytes to consume by all files. growfiles exits when more\n\
1539 than maxbytes have been consumed. (def no chk) If maxbytes ends\n\
1540 with the letter 'b', maxbytes is multiplied by BSIZE\n\
1541 -C write_chk Specifies how often to check the last write (default 1)\n\
1542 -c file_chk Specifies how often to check whole file (default 0)\n\
1543 -d auto_dir Specifies the directory to auto created files. (default .)\n\
1544 -D debug_lvl Specifies the debug level (default 1)\n\
1545 -E Print examples and exit\n\
1546 -e errs The number errors that will terminate this program (def 100)\n\
1547 -f auto_file Specifies the base filename files created. (default \"gf\")\n\
1548 -g grow_incr Specfied to grow by incr for each num. (default 4096)\n\
1549 grow_incr may end in b for blocks\n\
1550 If -r option is used, this option is ignored and size is random\n\
1551 -H delay Amount of time to delay between each file (default 0.0)\n\
1552 -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
1553 l - listio sync, L - listio async, r - random\n\
1554 -i iteration Specfied to grow each file num times. 0 means forever (default 1)\n\
1555 -l Specfied to do file locking around write/read/trunc\n\
1556 If specified twice, file locking after open to just before close\n\
1557 -L time Specfied to exit after time secs, must be used with -i.\n\
1558 -N num_files Specifies the number of files to be created.\n\
1559 The default is zero if cmd line files.\n\
1560 The default is one if no cmd line files.\n\
1561 -n num_procs Specifies the number of copies of this cmd.\n\
1562 -o op_type Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
1563 -O offset adjust i/o buffer alignment by offset bytes\n\
1564 -P PANIC Specifies to call upanic on error.\n\
1565 -p Specifies to pre-allocate space\n\
1566 -q pattern pattern can be a - ascii, p - pid with boff, o boff (def)\n\
1567 A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
1568 c - checkboard, C - counting\n\
1569 -R [min-]max random lseek before write and trunc, max of -1 means filesz,\n\
1570 -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
1571 -r [min-]max random io write size (min def is 1)\n\
1572 -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
1573 -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
1574 -t trunc_incr Specfied the amount to shrink file. (default 4096)\n\
1575 trunc_inter may end in b for blocks\n\
1576 If -R option is used, this option is ignored and trunc is random\n\
1577 -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
1578 -u unlink files before exit\n\
1579 -U ui[-ui2] Unlink files each ui iteration (def 0)\n\
1580 -w Specfied to grow via lseek instead of writes.\n\
1581 -W tag-name Who-am-i. My Monster tag name. (used by Monster).\n\
1582 -x Re-exec children before continuing - useful on MPP systems\n\
1583 -y Attempt to sync copies - if one fails it will send sigusr2 to others\n\
1584 Action to each file every iteration is open, write, write check\n\
1585 file check, trunc and closed.\n");
1590 /***********************************************************************
1592 ***********************************************************************/
1594 prt_examples(FILE *stream)
1596 /* This example creates 200 files in directory dir1. It writes */
1597 /* 4090 bytes 100 times then truncates 408990 bytes off the file */
1598 /* The file contents are checked every 1000 grow. */
1600 "# run forever: writes of 4090 bytes then on every 100 iterval\n\
1601 # truncate file by 408990 bytes. Done to 200 files in dir1.\n\
1602 %s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n", Progname);
1604 /* same as above with 5000 byte grow and a 499990 byte tuncate */
1606 "# same as above with writes of 5000 bytes and truncs of 499990\n\
1607 %s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n", Progname);
1609 /* This example beats on opens and closes */
1611 "# runs forever: beats on opens and closes of file ocfile - no io\n\
1612 %s -i 0 -g 0 -c 0 -C 0 ocfile\n\n", Progname);
1615 "# writes 4096 to files until 50 blocks are written\n\
1616 %s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
1619 "# write one byte to 750 files in gdir then unlinks them\n\
1620 %s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
1623 "# run 30 secs: random iosize, random lseek up to eof\n\
1624 %s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
1627 "# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
1628 %s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10 g_sleek1 g_lseek2\n\n", Progname);
1631 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1632 # rand io types doing a trunc every 5 iterations, with unlinks.\n\
1633 %s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n",
1637 "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
1638 # random open flags, rand io types doing a trunc every 10 iterations.\n\
1639 %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",
1646 /***********************************************************************
1648 * The file descriptor current offset is assumed to be the end of the
1650 * Woffset will be set to the offset before the write.
1651 * Grow_incr will be set to the size of the write or lseek write.
1652 ***********************************************************************/
1654 growfile(fd, file, grow_incr, buf)
1665 int fsize; /* current size of file */
1666 int size_grew; /* size the file grew */
1671 * Do a stat on the open file.
1672 * If the file is a fifo, set the bit in Mode variable.
1673 * This fifo check must be done prior to growfile() returning.
1674 * Also get the current size of the file.
1676 if ( fstat(fd, &stbuf) != -1 ) {
1677 if ( S_ISFIFO(stbuf.st_mode) ) {
1678 Fileinfo.mode |= MODE_FIFO;
1681 printf("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
1682 Progname, Pid, __FILE__, __LINE__);
1684 fsize = stbuf.st_size;
1687 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1688 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1694 if ( grow_incr <= 0 ) { /* don't attempt i/o if grow_incr <= 0 */
1696 Grow_incr=grow_incr;
1698 printf("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
1699 Progname, Pid, __FILE__, __LINE__, grow_incr);
1703 if ( Mode & MODE_RAND_SIZE ) {
1704 grow_incr=random_range(min_size, max_size, mult_size, &errmsg);
1705 if (errmsg != NULL) {
1706 fprintf(stderr, "%s%s: %d %s/%d: random_range() failed - %s\n", Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
1709 Grow_incr=grow_incr;
1712 Grow_incr=grow_incr;
1714 if ( ! (Mode & MODE_FIFO) ) {
1715 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
1716 fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
1717 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1722 if ( Mode & MODE_GROW_BY_LSEEK ) {
1725 printf("%s: %d DEBUG3 %s/%d: Current size of file is %d\n", Progname,
1726 Pid, __FILE__, __LINE__, Woffset);
1727 printf("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n", Progname,
1728 Pid, __FILE__, __LINE__, grow_incr-1);
1731 if ((noffset=lseek(fd, grow_incr-1, SEEK_END)) == -1 ) {
1732 fprintf(stderr, "%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
1733 Progname, TagName, __FILE__, __LINE__, grow_incr-1, strerror(errno));
1737 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1740 ret=lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg,0);
1742 ret=write_buffer(fd, io_type, "w", 1, 0, &errmsg);
1746 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
1747 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
1748 if ( ret == -ENOSPC ) {
1757 lkfile(fd, LOCK_UN, LKLVL0);
1760 printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
1761 Progname, Pid, __FILE__, __LINE__, Iter_cnt);
1763 } else { /* end of grow by lseek */
1765 if ( Fileinfo.openflags & O_APPEND ) {
1767 * Deal with special case of the open flag containing O_APPEND.
1768 * If it does, the current offset does not matter since the write
1769 * will be done end of the file.
1772 printf("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
1773 Progname, Pid, __FILE__, __LINE__ );
1774 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1777 * do fstat again to get size of the file.
1778 * This is done inside a file lock (if locks are being used).
1780 if ( fstat(fd, &stbuf) != -1 ) {
1781 Woffset = stbuf.st_size;
1783 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
1784 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
1786 lkfile(fd, LOCK_UN, LKLVL0); /* release lock */
1790 printf("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
1791 Progname, Pid, __FILE__, __LINE__, (int)stbuf.st_size);
1794 } else if ( Mode & MODE_RAND_LSEEK ) {
1795 if ( max_lseek == LSK_EOF ) { /* within file size */
1796 noffset=random_range(min_lseek, fsize, 1, NULL);
1798 else if ( max_lseek == LSK_EOFPLUSGROW ) {
1799 /* max to beyond file size */
1800 noffset=random_range(min_lseek, fsize+grow_incr, 1, NULL);
1802 else if ( max_lseek == LSK_EOFMINUSGROW ) {
1804 * Attempt to not grow the file.
1805 * If the i/o will fit from min_lseek to EOF,
1806 * pick offset to allow it to fit.
1807 * Otherwise, pick the min_lseek offset and grow
1808 * file by smallest amount.
1809 * If min_lseek is != 0, there will be a problem
1810 * with whole file checking if file is ever smaller
1813 if ( fsize <= min_lseek + grow_incr )
1814 noffset=min_lseek; /* file will still grow */
1816 noffset=random_range(min_lseek, fsize-grow_incr, 1, NULL);
1819 noffset=random_range(min_lseek, max_lseek, 1, NULL);
1822 if ((Woffset=lseek(fd, noffset, SEEK_SET)) == -1 ) {
1823 fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l2 failed: %s\n",
1824 Progname, TagName, Pid, __FILE__, __LINE__, fd, noffset, strerror(errno));
1827 else if ( Debug > 2 )
1828 printf("%s: %d DEBUG3 %s/%d: lseeked to random offset %d (fsz:%d)\n",
1829 Progname, Pid, __FILE__, __LINE__, Woffset,
1830 (int)stbuf.st_size);
1835 * lseek to end of file only if not fifo
1837 else if ( ! (Mode & MODE_FIFO) ) {
1838 if ((Woffset=lseek(fd, 0, SEEK_END)) == -1 ) {
1839 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
1840 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
1843 else if ( Debug > 2 )
1844 printf("%s: %d DEBUG3 %s/%d: lseeked to end of file, offset %d\n",
1845 Progname, Pid, __FILE__, __LINE__, Woffset);
1848 if ( Pattern == PATTERN_OFFSET )
1849 datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
1850 else if ( Pattern == PATTERN_PID )
1851 datapidgen(Pid, buf, grow_incr, Woffset);
1852 else if ( Pattern == PATTERN_ASCII )
1853 dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
1854 else if ( Pattern == PATTERN_RANDOM )
1855 databingen('r', buf, grow_incr, Woffset);
1856 else if ( Pattern == PATTERN_ALT )
1857 databingen('a', buf, grow_incr, Woffset);
1858 else if ( Pattern == PATTERN_CHKER )
1859 databingen('c', buf, grow_incr, Woffset);
1860 else if ( Pattern == PATTERN_CNTING )
1861 databingen('C', buf, grow_incr, Woffset);
1862 else if ( Pattern == PATTERN_ZEROS )
1863 databingen('z', buf, grow_incr, Woffset);
1864 else if ( Pattern == PATTERN_ONES )
1865 databingen('o', buf, grow_incr, Woffset);
1867 dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
1870 printf("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
1871 Progname, Pid, __FILE__, __LINE__, grow_incr);
1873 lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
1876 ret=write(fd, buf, grow_incr);
1880 lkfile(fd, LOCK_UN, LKLVL0);
1882 if ( ret != grow_incr) {
1883 fprintf(stderr, "%s: %s/%d: write failed: %s\n",
1884 Progname, __FILE__, __LINE__, strerror(errno));
1890 ret=lio_write_buffer(fd, io_type, (char *)buf, grow_incr,
1891 SIGUSR1, &errmsg,0);
1893 ret=write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
1896 if( Mode & MODE_FIFO ){
1897 /* If it is a fifo then just pretend the file
1898 * offset is where we think it should be.
1900 tmp = Woffset + grow_incr;
1903 if( (tmp=lseek(fd,0,SEEK_CUR)) < 0 ){ /* get offset after the write */
1904 fprintf(stderr, "%s%s: %s/%d: tell(2) failed: %d %s\n",
1905 Progname, TagName, __FILE__, __LINE__, errno, strerror(errno) );
1910 lkfile(fd, LOCK_UN, LKLVL0);
1912 if ( ret != grow_incr ) {
1913 fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
1914 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
1915 if ( ret == -ENOSPC ) {
1923 * Check for a condition where the file was truncated just before
1926 if ( tmp != Woffset + grow_incr) {
1928 * The offset after the write was not as expected.
1929 * This could be caused by the following:
1930 * - file truncated after the lseek and before the write.
1931 * - the file was written to after fstat and before the write
1932 * and the file was opened with O_APPEND.
1934 * The pattern written to the file will be considered corrupted.
1936 if ( Debug > 0 && lockfile ) {
1937 printf("%s%s: %d DEBUG1 %s/%d: offset after write(%d) not as exp(%d+%d=%d)\n",
1938 Progname, TagName, Pid, __FILE__, __LINE__, tmp, Woffset, grow_incr, Woffset+grow_incr);
1939 printf("%s%s: %d DEBUG1 %s/%d: %d Assuming file changed by another process, resetting offset:%d (expect pattern mismatch)\n",
1940 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, tmp-grow_incr);
1943 printf("%s: %d DEBUG5 %s/%d: about to chop Woffset. tmp=%d, grow_incr=%d, Woffset was %d\n",
1944 Progname, Pid, __FILE__, __LINE__, tmp, grow_incr, Woffset);
1946 Woffset=tmp-grow_incr;
1951 } /* end of grow by write */
1955 * Woffset - holds start of grow (start of write expect in grow by lseek)
1956 * Grow_incr - holds size of grow (write).
1957 * fsize - holds size of file before write
1959 size_grew=(Woffset + Grow_incr) - fsize;
1961 if ( Mode & MODE_FIFO ) {
1962 printf("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
1963 Progname, Pid, __FILE__, __LINE__, Grow_incr, Iter_cnt);
1966 else if ( size_grew > 0 )
1967 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), grew file by %d bytes\n",
1968 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset, size_grew);
1970 printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), did not grow file\n",
1971 Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset);
1974 bytes_consumed += size_grew;
1977 } /* end of growfile */
1979 /***********************************************************************
1980 * shrinkfile file by trunc_incr. file can not be made smaller than
1981 * size zero. Therefore, if trunc_incr is larger than file size,
1982 * file will be truncated to zero.
1983 * The file descriptor current offset is assumed to be the end of the
1986 ***********************************************************************/
1988 shrinkfile(fd, filename, trunc_incr, trunc_inter, just_trunc)
1992 int trunc_inter; /* interval */
1993 int just_trunc; /* lseek has already been done for you */
1995 static int shrink_cnt = 0;
2002 if ( trunc_inter == 0 || (shrink_cnt % trunc_inter != 0)) {
2004 printf("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
2005 Progname, Pid, __FILE__, __LINE__, trunc_inter, shrink_cnt);
2006 return 0; /* not this time */
2009 if ( Mode & MODE_FIFO ) {
2011 printf("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
2012 Progname, Pid, __FILE__, __LINE__);
2013 return 0; /* can not truncate fifo */
2016 lkfile(fd, LOCK_EX, LKLVL0);
2018 if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
2019 fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
2020 Progname, TagName, Pid, __FILE__, __LINE__, fd, strerror(errno));
2021 lkfile(fd, LOCK_UN, LKLVL0);
2025 if ( Mode & MODE_RAND_LSEEK ) {
2026 if ( max_lseek <= -1 ) {
2027 if ( (new_offset=file_size(fd)) == -1 ) {
2028 lkfile(fd, LOCK_UN, LKLVL0);
2032 if ( new_offset < min_lseek )
2033 new_offset=min_lseek;
2035 new_offset=random_range(min_lseek, new_offset, 1, NULL);
2038 new_offset=random_range(min_lseek, max_lseek, 1, NULL);
2042 else { /* remove trunc_incr from file */
2044 new_offset = cur_offset-trunc_incr;
2046 if ( new_offset < 0 )
2050 ret=ftruncate(fd, new_offset );
2051 if( (ret == 0) && (Debug > 3) ){
2052 printf("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
2053 Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
2056 lkfile(fd, LOCK_UN, LKLVL0);
2059 fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
2060 Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
2065 printf("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
2066 Progname, Pid, __FILE__, __LINE__, cur_offset-new_offset, new_offset);
2070 bytes_consumed -= (cur_offset - new_offset);
2073 } /* end of shrinkfile */
2075 /***********************************************************************
2077 ***********************************************************************/
2079 check_write(fd, cf_inter, filename, mode)
2081 int cf_inter; /* check file interval */
2082 char *filename; /* needed for error messages */
2083 int mode; /* write mode */
2086 static int cf_count = 0;
2094 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2096 printf("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
2097 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2098 return 0; /* no check done */
2101 if ( Grow_incr <= 0 ) {
2103 printf("%s: %d DEBUG4 %s/%d: No write validation, Grow_incr = %d, offset = %d\n",
2104 Progname, Pid, __FILE__, __LINE__, Grow_incr, Woffset);
2105 return 0; /* no check */
2111 * Get the shared file lock. We need to hold the lock from before
2112 * we do the stat until after the read.
2114 lkfile(fd, LOCK_SH, LKLVL0);
2116 if ((fsize=file_size(fd)) == -1 ) {
2117 lkfile(fd, LOCK_UN, LKLVL0);
2120 } else if ( fsize <= Woffset ) {
2122 * The file was truncated between write and now.
2123 * The contents of our last write is totally gone, no check.
2126 printf("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than where last wrote (%d)- no write validation\n",
2127 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, Woffset);
2128 lkfile(fd, LOCK_UN, LKLVL0);
2129 return 0; /* no validation, but not an error */
2131 } else if ( fsize < (Woffset + Grow_incr)) {
2133 * The file was truncated between write and now.
2134 * Part of our last write has been truncated, adjust our Grow_incr
2139 Grow_incr=fsize-Woffset;
2143 printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of wrt(off:%d, sz:%d), adj=%d\n",
2144 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, tmp-Grow_incr, Woffset, tmp, Grow_incr);
2150 printf("%s: %d DEBUG3 %s/%d: about to do write validation, offset = %d, size = %d\n",
2151 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2153 if ( ! (mode & MODE_FIFO) ) {
2155 if ( lseek(fd, Woffset, 0) == -1 ) {
2156 fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, 0) failed: %s\n",
2157 Progname, TagName, Pid, __FILE__, __LINE__, Woffset, strerror(errno));
2160 printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%d\n",
2161 Progname, Pid, __FILE__, __LINE__, Woffset);
2165 * Read last writes data
2168 ret=lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,0);
2170 ret=read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
2174 * report the error and debug information before releasing
2177 if ( ret != Grow_incr ) {
2178 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2183 printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n",
2184 Progname, TagName, Pid, __FILE__, __LINE__, fd,
2185 (int)lseek(fd,SEEK_CUR,0), /* FIXME: 64bit/LFS ? */
2187 Fileinfo.openflags);
2190 lkfile(fd, LOCK_UN, LKLVL0);
2195 lkfile(fd, LOCK_UN, LKLVL0);
2197 if ( Mode & MODE_GROW_BY_LSEEK ) {
2198 /* check that all zeros upto last character */
2199 for(ptr=Buffer; ptr < (Buffer+Grow_incr-1); ptr++) {
2200 if ( *ptr != '\0' ) {
2202 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2203 Progname, TagName, Pid, __FILE__, __LINE__,
2204 (int)(Woffset+(Grow_incr-(Buffer-ptr))),
2210 /* check that the last char is a 'w' */
2211 if ( *ptr != 'w' ) {
2213 "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
2214 Progname, TagName, Pid, __FILE__, __LINE__,
2215 (int)(Woffset+(Grow_incr-(Buffer-ptr))), 'w',
2220 return 0; /* all is well */
2223 else if ( Pattern == PATTERN_OFFSET )
2224 ret=datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
2225 else if ( Pattern == PATTERN_PID )
2226 ret=datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
2227 else if ( Pattern == PATTERN_ASCII )
2228 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2229 else if ( Pattern == PATTERN_RANDOM )
2230 ; /* no check for random */
2231 else if ( Pattern == PATTERN_ALT )
2232 ret=databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
2233 else if ( Pattern == PATTERN_CHKER )
2234 ret=databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
2235 else if ( Pattern == PATTERN_CNTING )
2236 ret=databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
2237 else if ( Pattern == PATTERN_ZEROS )
2238 ret=databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
2239 else if ( Pattern == PATTERN_ONES )
2240 ret=databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
2242 ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
2245 fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
2246 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2249 printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, offset:%d, sz:%d open flags:%#o %s\n",
2250 Progname, TagName, Pid, __FILE__, __LINE__, fd, lockfile,
2251 Woffset, Grow_incr, Fileinfo.openflags, openflags2symbols(Fileinfo.openflags, ",", 0));
2258 printf("%s: %d DEBUG7 %s/%d: No corruption detected on write validation , offset = %d, size = %d\n",
2259 Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
2261 return 0; /* all is well */
2266 /***********************************************************************
2268 ***********************************************************************/
2270 check_file(fd, cf_inter, filename, no_file_check)
2272 int cf_inter; /* check file interval */
2273 char *filename; /* needed for error messages */
2274 int no_file_check; /* if set, do not do file content check */
2277 static int cf_count = 0;
2287 if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
2289 printf("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
2290 Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
2291 return 0; /* no check done */
2295 * if we can't determine file content, don't bother checking
2297 if ( no_file_check ) {
2299 printf("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
2300 Progname, Pid, __FILE__, __LINE__);
2305 * Lock the file. We need to have the file lock before
2306 * the stat and until after the last read to prevent
2307 * a trunc/truncate from "corrupting" our data.
2309 lkfile(fd, LOCK_SH, LKLVL0);
2311 if ((fsize=file_size(fd)) == -1 ) {
2312 lkfile(fd, LOCK_UN, LKLVL0);
2318 printf("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
2319 Progname, Pid, __FILE__, __LINE__);
2321 lkfile(fd, LOCK_UN, LKLVL0);
2326 printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
2327 Progname, Pid, __FILE__, __LINE__);
2329 if ( fsize > MAX_FC_READ ) {
2331 * read the file in MAX_FC_READ chuncks.
2334 if ((buf=(char *)malloc(MAX_FC_READ)) == NULL ) {
2335 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2336 __FILE__, __LINE__, MAX_FC_READ, strerror(errno));
2337 lkfile(fd, LOCK_UN, LKLVL0);
2341 lseek(fd, 0, SEEK_SET);
2343 lkfile(fd, LOCK_SH, LKLVL0); /* get lock on file before getting file size */
2346 while (rd_cnt < fsize ) {
2347 if ( fsize - rd_cnt > MAX_FC_READ )
2348 rd_size=MAX_FC_READ;
2350 rd_size=fsize - rd_cnt;
2353 ret=lio_read_buffer(fd, io_type, buf, rd_size,
2354 SIGUSR1, &errmsg,0);
2356 ret=read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
2359 if (ret != rd_size ) {
2360 fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n",
2361 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2363 lkfile(fd, LOCK_UN, LKLVL0);
2367 read(fd, buf, rd_size);
2370 if ( Pattern == PATTERN_OFFSET )
2371 ret=datapidchk(STATIC_NUM, buf, rd_size, rd_cnt, &errmsg);
2372 else if ( Pattern == PATTERN_PID )
2373 ret=datapidchk(Pid, buf, rd_size, rd_cnt, &errmsg);
2374 else if ( Pattern == PATTERN_ASCII )
2375 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2376 else if ( Pattern == PATTERN_RANDOM )
2377 ; /* no checks for random */
2378 else if ( Pattern == PATTERN_ALT )
2379 ret=databinchk('a', buf, rd_size, rd_cnt, &errmsg);
2380 else if ( Pattern == PATTERN_CHKER )
2381 ret=databinchk('c', buf, rd_size, rd_cnt, &errmsg);
2382 else if ( Pattern == PATTERN_CNTING )
2383 ret=databinchk('C', buf, rd_size, rd_cnt, &errmsg);
2384 else if ( Pattern == PATTERN_ZEROS )
2385 ret=databinchk('z', buf, rd_size, rd_cnt, &errmsg);
2386 else if ( Pattern == PATTERN_ONES )
2387 ret=databinchk('o', buf, rd_size, rd_cnt, &errmsg);
2389 ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
2394 "%s%s: %d %s/%d: %d CFp %s in file %s\n",
2395 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2398 lkfile(fd, LOCK_UN, LKLVL0);
2404 lkfile(fd, LOCK_UN, LKLVL0);
2411 * Read the whole file in a single read
2413 if((buf=(char *)malloc(fsize)) == NULL ) {
2414 fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
2415 __FILE__, __LINE__, fsize, strerror(errno));
2420 lseek(fd, 0, SEEK_SET);
2423 read(fd, buf, fsize);
2426 ret=lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,0);
2428 ret=read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
2431 /* unlock the file as soon as we can */
2432 lkfile(fd, LOCK_UN, LKLVL0);
2435 if ( ret != fsize ) {
2436 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n",
2437 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
2441 if ( Pattern == PATTERN_OFFSET )
2442 ret=datapidchk(STATIC_NUM, buf, fsize, 0, &errmsg);
2443 else if ( Pattern == PATTERN_PID )
2444 ret=datapidchk(Pid, buf, fsize, 0, &errmsg);
2445 else if ( Pattern == PATTERN_ASCII )
2446 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2447 else if ( Pattern == PATTERN_RANDOM )
2448 ; /* no check for random */
2449 else if ( Pattern == PATTERN_ALT )
2450 ret=databinchk('a', buf, fsize, 0, &errmsg);
2451 else if ( Pattern == PATTERN_CHKER )
2452 ret=databinchk('c', buf, fsize, 0, &errmsg);
2453 else if ( Pattern == PATTERN_CNTING )
2454 ret=databinchk('C', buf, fsize, 0, &errmsg);
2455 else if ( Pattern == PATTERN_ZEROS )
2456 ret=databinchk('z', buf, fsize, 0, &errmsg);
2457 else if ( Pattern == PATTERN_ONES )
2458 ret=databinchk('o', buf, fsize, 0, &errmsg);
2460 ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
2463 fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s in file %s\n",
2464 Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
2474 } /* end of check_file */
2476 /***********************************************************************
2478 ***********************************************************************/
2484 if (fstat(fd, &sb) < 0) {
2485 fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
2486 Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
2494 /***********************************************************************
2495 * do file lock/unlock action.
2496 ***********************************************************************/
2498 lkfile(int fd, int operation, int lklevel)
2503 if ( lockfile == lklevel) {
2506 switch (operation) {
2508 printf("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n",
2509 Progname, Pid, __FILE__, __LINE__, fd);
2513 printf("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n",
2514 Progname, Pid, __FILE__, __LINE__, fd);
2518 printf("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n",
2519 Progname, Pid, __FILE__, __LINE__, fd);
2525 * Attempt to get/release desired lock.
2526 * file_lock will attempt to do action over and over again until
2527 * either an unretryable error or the action is completed.
2530 if ( file_lock(fd, operation, &errmsg) != 0 ) {
2531 printf("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
2532 Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
2534 /* do we count this as an error? handle_error(); */
2539 switch (operation) {
2541 printf("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n",
2542 Progname, Pid, __FILE__, __LINE__, fd);
2546 printf("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n",
2547 Progname, Pid, __FILE__, __LINE__, fd);
2551 printf("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n",
2552 Progname, Pid, __FILE__, __LINE__, fd);
2556 printf("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n",
2557 Progname, Pid, __FILE__, __LINE__, operation, fd);
2566 /***********************************************************************
2568 ***********************************************************************/
2570 pre_alloc(file, fd, size)
2576 #ifdef XFS_IOC_RESVSP
2577 struct xfs_flock64 f;
2583 /* non-zeroing reservation */
2584 if( xfsctl( file, fd, XFS_IOC_RESVSP, &f ) == -1 ){
2585 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: xfsctl(XFS_IOC_RESVSP) failed: %d %s\n",
2587 __FILE__, __LINE__, errno, strerror(errno));
2597 /* non-zeroing reservation */
2598 if( fcntl( fd, F_RESVSP64, &f ) == -1 ){
2599 fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: fcntl(F_RESVSP) failed: %d %s\n",
2601 __FILE__, __LINE__, errno, strerror(errno));