+++ /dev/null
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2000 Silicon Graphics, Inc.
- * All Rights Reserved.
- */
-/*
- * This program will grow a list of files.
- * Each file will grow by grow_incr before the same
- * file grows twice. Each file is open and closed before next file is opened.
- *
- * To just verify file contents: growfiles -g 0 -c 1 filename
- *
- * See help and prt_examples functions below.
- *
- * Basic code layout
- * process cmdline
- * print debug message about options used
- * setup signal handlers
- * return control to user (if wanted - default action)
- * fork number of desired childern (if wanted)
- * re-exec self (if wanted)
- * Determine number of files
- * malloc space or i/o buffer
- * Loop until stop is set
- * Determine if hit iteration, time, max errors or num bytes reached
- * Loop through each file
- * open file
- * fstat file - to determine if file is a fifo
- * prealloc file space (if wanted)
- * growfile
- * check last write
- * check whole file
- * shrink file
- * close file
- * delay (if wanted)
- * End loop
- * End loop
- * remove all files (if wanted)
- *
- * Author: Richard Logan
- *
- */
-
-#include "global.h"
-
-#ifdef HAVE_SYS_FILE_H
-#include <sys/file.h>
-#endif
-
-#include "dataascii.h"
-#include "random_range.h"
-#include "databin.h"
-#include "open_flags.h"
-#include "forker.h"
-#include "file_lock.h"
-
-extern int datapidgen(int pid, unsigned char *buffer, int bsize, int offset);
-extern void databingen(int mode, unsigned char *buffer, int bsize, int offset);
-extern int datapidchk(int pid, char *buffer, int bsize, int offset, char **errmsg);
-extern int databinchk(int mode, char *buffer, int bsize, int offset, char **errmsg);
-
-int file_size(int fd);
-int check_write(int fd, int cf_inter, char *filename, int mode);
-int shrinkfile(int fd, char *filename, int trunc_incr, int trunc_inter, int just_trunc);
-int check_file(int fd, int cf_inter, char *filename, int no_file_check);
-int growfile(int fd, char *file, int grow_incr, unsigned char *buf);
-int cleanup();
-int handle_error();
-int lkfile(int fd, int operation, int lklevel);
-void usage();
-void help();
-void prt_examples(FILE *stream);
-int set_sig();
-void sig_handler();
-static void notify_others();
-int pre_alloc(char *file, int fd, int size);
-
-
-#define NEWIO 1 /* Use the tlibio.c functions */
-
-#ifndef NEWIO
-#define NEWIO 0 /* specifies to use original iowrite.c */
- /* functions instead of tlibio.c functions */
- /* Once it is proven tlibio.c functions work properly, */
- /* only tlibio.c functions will be used */
-#else
-#include "tlibio.h"
-#endif
-
-#ifndef PATH_MAX
-#define PATH_MAX 1023
-#endif
-
-
-#define DEF_DIR "."
-#define DEF_FILE "gf"
-
-char *Progname;
-int Debug = 1;
-
-int Pid=0;
-
-int io_type = 0; /* I/O type -sync */
-int open_flags = O_RDWR|O_CREAT; /* open flags */
-
-#define MAX_FC_READ 196608 /* 4096 * 48 - 48 blocks */
-
-#define PATTERN_ASCII 1 /* repeating alphabet letter pattern */
- /* allows multiple writers and to be checked */
-#define PATTERN_PID 2 /* <pid><words byte offset><pid> */
- /* Assumes 64 bit word. Only allows single */
- /* process to write and check */
-/*
- * 1234567890123456789012345678901234567890123456789012345678901234
- * ________________________________________________________________
- * < pid >< offset in file of this word >< pid >
- */
-
-#define PATTERN_OFFSET 3 /* Like PATTERN_PID but has a fixed number */
- /* (STATIC_NUM) instead of pid. */
- /* Allows multiple processes to write/read */
-#define PATTERN_ALT 4 /* alternating bit pattern (i.e. 0x5555555...) */
-#define PATTERN_CHKER 5 /* checkerboard pattern (i.e. 0xff00ff00ff00...) */
-#define PATTERN_CNTING 6 /* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
-#define PATTERN_ONES 7 /* all bits set (i.e. 0xffffffffffffff...) */
-#define PATTERN_ZEROS 8 /* all bits cleared (i.e. 0x000000000...) */
-#define PATTERN_RANDOM 9 /* random integers - can not be checked */
-#define STATIC_NUM 221849 /* used instead of pid when PATTERN_OFFSET */
-
-#define MODE_RAND_SIZE 1 /* random write and trunc */
-#define MODE_RAND_LSEEK 2 /* random lseek before write */
-#define MODE_GROW_BY_LSEEK 4 /* lseek beyond end of file then write a byte */
-#define RANDOM_OPEN 999876 /* if Open_flags set to this value, open flags */
- /* will be randomly choosen from Open_flags[] */
-#define MODE_FIFO S_IFIFO /* defined in stat.h 0010000 */
-
-int num_files = 0; /* num_auto_files + cmd line files */
-char *filenames; /* pointer to space containing filenames */
-int remove_files = 0; /* if set, cleanup default is not to cleanup */
-int bytes_consumed = 0; /* total bytes consumed, all files */
-int bytes_to_consume = 0; /* non-zero if -B was specified, total bytes */
-int Maxerrs = 100; /* Max number errors before forced exit */
-int Errors = 0; /* number of encountered errors */
-int Upanic_on_error = 0; /* call upanic if error and this variable set */
-
-/* The *_size variables are only used when random iosize option (-r) is used */
-int max_size=5000;
-int min_size=1; /* also set in option parsing */
-int mult_size=1; /* when random iosz, iosz must be mult of mult_size */
-/* the *_lseek variables are only used when radon lseek option (-R) is used */
-int min_lseek=0; /* also set in option parsing */
-int max_lseek=-1; /* -1 means size of file */
-int Pattern=PATTERN_ASCII;
-int Seed=-1; /* random number seed, < 0 == uninitialized */
-int Nseeds=0; /* Number of seed specified by the user */
-int *Seeds; /* malloc'ed arrary of ints holding user spec seeds */
-
-int using_random=0; /* flag indicating randomization is being used */
-float delaysecs=0.0; /* delay between iterations (in seconds) */
-int delaytime; /* delay between iterations in clocks/uses */
-int lockfile=0; /* if set, do file locking */
- /* 1 = do file locking around write, trunc */
- /* and reads. */
- /* 2 = write lock around all file operations */
-
-int Woffset=0; /* offset before last write */
-int Grow_incr=4096; /* sz of last write */
-int Mode=0; /* bitmask of write/trunc mode */
- /* also knows if dealing with fifo */
-char *Buffer = NULL; /* buffer used by write and write check */
-int Alignment=0; /* if non word multiple, io will not be word aligned */
-int Opid=0; /* original pid */
-
-int Sync_with_others = 0; /* Flag indicating to stop other if we stop before DONE */
-int Iter_cnt = 0; /* contains current iteration count value */
-char TagName[40]; /* name of this growfiles (see Monster) */
-
-struct fileinfo_t {
- char *filename;
- int fd;
- int openflags;
- int mode;
-} Fileinfo;
-
-/*
- * Define open flags that will be used when '-o random' option is used.
- * Note: If there is more than one growfiles doing its thing to the same
- * file, O_TRUNC will cause data mismatches. How you ask?
- * timing of events, example:
- * Process one Process two
- * --------------- -------------
- * get write lock
- * fstat file
- * lseek
- * generate pattern
- * open with O_TRUNC
- * write with wrong pattern
- * because offset is wrong
- *
- * The second process truncated the file after the pattern was
- * determined, thus the pattern is wrong for the file location.
- *
- * There can also be a timing problem with open flag O_APPEND if
- * file locks are not being used (-l option). Things could happen
- * between the fstat and the write. Thus, writing the wrong pattern.
- * If all processes observe the file locks, O_APPEND should be ok
- * to use.
- */
-int Open_flags[] = {
- O_RDWR|O_CREAT,
- O_RDWR|O_CREAT|O_APPEND,
- O_RDWR|O_CREAT|O_NDELAY,
- O_RDWR|O_CREAT|O_SYNC,
- O_RDWR|O_CREAT|O_SYNC|O_NDELAY,
- O_RDWR|O_CREAT|O_APPEND|O_NDELAY,
-
-};
-
-#define REXEC_INIT 0 /* don't do re-exec of childern */
-#define REXEC_DOIT 1 /* Do re-exec of childern */
-#define REXEC_DONE 2 /* We've already been re-exec'ed */
-
-#ifndef BSIZE
-#define BSIZE 512
-#endif /* BSIZE */
-
-#define USECS_PER_SEC 1000000 /* microseconds per second */
-
-/*
- * Define marcos used when dealing with file locks.
- */
-#define LKLVL0 1 /* file lock around write/read/trunc */
-#define LKLVL1 2 /* file lock after open to before close */
-
-/*
- * Define special max lseek values
- */
-#define LSK_EOF -1 /* set fptr up to EOF */
-#define LSK_EOFPLUSGROW -2 /* set fptr up to EOF + grow - leave whole */
-#define LSK_EOFMINUSGROW -3 /* set fptr up to EOF-grow - no grow */
-
-
-/***********************************************************************
- * MAIN
- ***********************************************************************/
-int
-main(argc, argv)
-int argc;
-char **argv;
-{
-extern char *optarg; /* used by getopt */
-extern int optind;
-extern int opterr;
-
-int ind;
-int first_file_ind = 0;
-int num_auto_files = 0; /* files created by tool */
-int seq_auto_files = 0; /* auto files created by tool created by tool */
-char *auto_dir = DEF_DIR;
-char *auto_file = DEF_FILE;
-int grow_incr = 4096;
-int trunc_incr = 4096;
-int trunc_inter = 0; /* 0 means none, */
-int unlink_inter = 0; /* 0 means none, 1 means always unlink */
-int unlink_inter_ran = -1; /* -1 -use unlink_inter, otherwise randomly choose */
- /* between unlink_inter and unlink_inter_ran */
-int file_check_inter = 0; /* 0 means never, 1 means always */
-int write_check_inter = 1; /* 0 means never, 1 means always */
-int iterations = 1; /* number of increments to be added */
-int no_file_check = 0; /* if set, no whole file checking will be done */
-int num;
-int fd; /* file descriptor */
-int stop = 0; /* loop stopper if set */
-int tmp;
-char chr;
-int ret;
-int pre_alloc_space = 0;
-int total_grow_value = 0; /* used in pre-allocations */
-int backgrnd = 1; /* return control to user */
-struct stat statbuf;
-int time_iterval = -1;
-time_t start_time = 0;
-char reason[40]; /* reason for loop termination */
-int num_procs=1;
-int forker_mode=0;
-int reexec=REXEC_INIT; /* reexec info */
-char *exec_path=NULL;
-
-char *strrchr();
-
-char *filename; /* name of file specified by user */
-char *cptr; /* temp char pointer */
-extern int Forker_npids; /* num of forked pid, defined in forker.c */
-
-
- if ( argv[0][0] == '-' )
- reexec=REXEC_DONE;
- /*
- * Determine name of file used to invoke this program
- */
- if ((Progname=strrchr(argv[0], '/')) != NULL)
- Progname++;
- else
- Progname=argv[0];
-
- TagName[0] = '\0';
-
- /*
- * Process options
- */
- while ((ind=getopt(argc, argv,
- "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) {
- switch(ind) {
-
- case 'h' :
- help();
- exit(0);
-
- case 'B':
- switch (sscanf(optarg, "%i%c",
- &bytes_to_consume, &chr)) {
- case 1: /* noop */
- break;
-
- case 2:
- if (chr == 'b') {
- bytes_to_consume *= BSIZE;
- } else {
- fprintf(stderr,
- "%s%s: --B option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- default:
- fprintf(stderr, "%s%s: --B option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- break;
- }
-
- break;
-
- case 'E' :
- prt_examples(stdout);
- exit(0);
-
- case 'b' : /* batch */
- backgrnd=0;
- break;
-
- case 'C':
- if (sscanf(optarg, "%i", &write_check_inter) != 1 ) {
- fprintf(stderr, "%s%s: --c option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'c':
- if (sscanf(optarg, "%i", &file_check_inter) != 1 ) {
- fprintf(stderr, "%s%s: --c option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
-
- case 'd':
- auto_dir=optarg;
- if ( stat(auto_dir, &statbuf) == -1 ) {
- if ( mkdir(auto_dir, 0777) == -1 ) {
- if ( errno != EEXIST ) {
- fprintf(stderr,
- "%s%s: Unable to make dir %s\n",
- Progname, TagName, auto_dir);
- exit(1);
- }
- }
- }
- else {
- if ( ! (statbuf.st_mode & S_IFDIR) ) {
- fprintf(stderr,
- "%s%s: %s already exists and is not a directory\n",
- Progname, TagName, auto_dir);
- exit(1);
- }
- }
- break;
-
- case 'D':
- if (sscanf(optarg, "%i", &Debug) != 1 ) {
- fprintf(stderr, "%s%s: --D option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'e':
- if (sscanf(optarg, "%i", &Maxerrs) != 1 ) {
- fprintf(stderr, "%s%s: --e option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'f':
- auto_file=optarg;
- break;
-
- case 'g':
- if ((ret=sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1 ||
- grow_incr < 0 ) {
-
- fprintf(stderr, "%s%s: --g option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- if ( ret == 2 ) {
- if ( chr == 'b' || chr == 'B' )
- grow_incr *= 4096;
- else {
- fprintf(stderr,
- "%s%s: --g option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- }
- break;
-
- case 'H':
- if (sscanf(optarg, "%f", &delaysecs) != 1 || delaysecs < 0 ) {
-
- fprintf(stderr, "%s%s: --H option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'i':
- if (sscanf(optarg, "%i", &iterations) != 1 ||
- iterations < 0 ) {
-
- fprintf(stderr, "%s%s: --i option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'I':
-#if NEWIO
- if((io_type=lio_parse_io_arg1(optarg)) == -1 ) {
- fprintf(stderr,
- "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
- Progname, TagName);
- exit(1);
- }
- if( io_type & LIO_RANDOM )
- using_random++;
-#else
- if((io_type=parse_io_arg(optarg)) == -1 ) {
- fprintf(stderr,
- "%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
- Progname, TagName);
- exit(1);
- }
- if( io_type == 99 ) /* hold-over until tlibio.h */
- using_random++;
-#endif
- break;
-
- case 'l':
- lockfile++;
- if ( lockfile > 2 )
- lockfile=2; /* lockfile can only be 1 or 2 */
- break;
-
- case 'L':
- if (sscanf(optarg, "%i", &time_iterval) != 1 ||
- time_iterval < 0 ) {
- fprintf(stderr, "%s%s: --L option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'n':
- if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) < 1 ||
- num_procs < 0 ) {
-
- fprintf(stderr, "%s%s: --n option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
-
- break;
-
- case 'N':
- if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
- num_auto_files < 0 ) {
-
- fprintf(stderr, "%s%s: --N option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'O':
- if (sscanf(optarg, "%i", &Alignment) != 1 ||
- num_auto_files < 0 ) {
-
- fprintf(stderr, "%s%s: --O option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'o':
- if ( strcmp(optarg, "random") == 0 ){
- open_flags=RANDOM_OPEN;
- using_random++;
-
- } else if ((open_flags=parse_open_flags(optarg, NULL)) == -1 ) {
- fprintf(stderr, "%s%s: --o arg contains invalid flag\n",
- Progname, TagName);
- exit(1);
- }
- break;
-
-
- case 'p' : /* pre allocate space */
- printf("%s%s: --p is illegal option on this system\n",
- Progname, TagName);
- exit(1);
- break;
-
- case 'P':
- printf("%s%s: --P is illegal option on non-cray system\n",
- Progname, TagName);
- exit(1);
- break;
-
- case 'q': /* file content or pattern */
- switch(optarg[0]) {
- case 'A':
- Pattern = PATTERN_ALT;
- break;
- case 'a':
- Pattern = PATTERN_ASCII;
- break;
- case 'p':
- Pattern = PATTERN_PID;
- break;
- case 'o':
- Pattern = PATTERN_OFFSET;
- break;
- case 'c':
- Pattern = PATTERN_CHKER;
- break;
- case 'C':
- Pattern = PATTERN_CNTING;
- break;
- case 'r':
- Pattern = PATTERN_RANDOM;
- using_random++;
- break;
- case 'z':
- Pattern = PATTERN_ZEROS;
- break;
- case 'O':
- Pattern = PATTERN_ONES;
- break;
- default:
- fprintf(stderr,
- "%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'R': /* random lseek before write arg: [min-]max*/
- if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) != 2 ) {
- min_lseek=1; /* same as default in define */
- if (sscanf(optarg, "%i%c", &max_lseek, &chr) != 1 ) {
- fprintf(stderr, "%s%s: --R option arg invalid: [min-]max\n",
- Progname, TagName);
- exit(1);
- }
- }
- if ( max_lseek < LSK_EOFMINUSGROW ) {
- fprintf(stderr, "%s%s: --R option, max_lseek is invalid\n",
- Progname, TagName);
- exit(1);
- }
- Mode |= MODE_RAND_LSEEK;
- using_random++;
- break;
-
- case 'r': /* random io size arg: [min-]max[:mult] */
-
- /* min-max:mult format */
- if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
- &mult_size, &chr) != 3 ) {
- min_size=1;
- /* max:mult format */
- if (sscanf(optarg, "%i:%i%c", &max_size,
- &mult_size, &chr) != 2 ) {
- /* min-max format */
- if (sscanf(optarg, "%i-%i%c", &min_size,
- &max_size, &chr) != 2 ) {
- min_size=1;
- if (sscanf(optarg, "%i%c", &max_size, &chr) != 1 ) {
- fprintf(stderr,
- "%s%s: --r option arg invalid: [min-]max[:mult]\n",
- Progname, TagName);
- exit(1);
- }
- }
- }
- }
-
- if ( max_size < 0 ) {
- fprintf(stderr, "%s%s: --r option, max_size is invalid\n",
- Progname, TagName);
- exit(1);
- }
- /*
- * If min and max are the same, no randomness
- */
- if ( min_size != max_size ) {
- Mode |= MODE_RAND_SIZE;
- using_random++;
- }
- break;
-
- case 'S':
- if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
- seq_auto_files < 0 ) {
-
- fprintf(stderr, "%s%s: --S option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 's': /* format: seed[,seed...] */
-
- /* count the number of seeds */
- cptr=optarg;
- for(Nseeds=1; *cptr ; Nseeds++) {
- if ( (filename=strchr(cptr, ',')) == NULL )
- break;
- cptr=filename;
- cptr++;
- }
- Seeds=(int *)malloc(Nseeds*sizeof(int));
-
- /*
- * check that each seed is valid and put them in
- * the newly malloc'ed Seeds arrary.
- */
- filename=cptr=optarg;
- for(Nseeds=0; *cptr; Nseeds++) {
- if ( (filename=strchr(cptr, ',')) == NULL ) {
- if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
- fprintf(stderr, "%s%s: --s option arg %s invalid\n",
- Progname, TagName, cptr);
- usage();
- exit(1);
- }
- Nseeds++;
- break;
- }
-
- *filename='\0';
- if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
- fprintf(stderr, "%s%s: --s option arg %s invalid\n",
- Progname, TagName, cptr);
- usage();
- exit(1);
- }
- *filename=','; /* restore string */
- cptr=filename;
- cptr++;
- }
- break;
-
- case 't':
- if ((ret=sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1 ||
- trunc_incr < 0 ) {
-
- fprintf(stderr, "%s%s: --t option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- if ( ret == 2 ) {
- if ( chr == 'b' || chr == 'B' )
- trunc_incr *= 4096;
- else {
- fprintf(stderr,
- "%s%s: --t option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- }
- break;
-
- case 'T': /* truncate interval */
- if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
- trunc_inter < 0 ) {
-
- fprintf(stderr, "%s%s: --T option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'u':
- remove_files++;
- break;
-
- case 'U': /* how often to unlink file */
- /*
- * formats:
- * A-B - randomly pick interval between A and B
- * X - unlink file every X iteration
- */
- if (sscanf(optarg, "%i-%i", &unlink_inter,
- &unlink_inter_ran) == 2 ) {
-
- if ( unlink_inter < 0 || unlink_inter_ran < 0 ) {
- fprintf(stderr, "%s%s: --U option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- /* ensure unlink_inter contains smaller value */
- if ( unlink_inter > unlink_inter_ran ) {
- tmp=unlink_inter_ran;
- unlink_inter_ran=unlink_inter;
- unlink_inter=tmp;
- }
- using_random++;
-
- } else if (sscanf(optarg, "%i%c", &unlink_inter, &chr) != 1 ||
- unlink_inter < 0 ) {
-
- fprintf(stderr, "%s%s: --U option arg invalid\n",
- Progname, TagName);
- usage();
- exit(1);
- }
- break;
-
- case 'x':
- if ( reexec != REXEC_DONE )
- reexec=REXEC_DOIT;
- break;
-
- case 'w':
- Mode |= MODE_GROW_BY_LSEEK;
- break;
-
- case 'W':
- sprintf( TagName, "(%.37s)", optarg );
- break;
-
- case 'y':
- Sync_with_others=1;
- break;
-
- case '?':
- usage();
- exit(1);
- break;
- }
- }
-
- if( Debug == 1 ){
- cptr = getenv("TOUTPUT");
- if( (cptr != NULL) && (strcmp( cptr, "NOPASS" ) == 0) ){
- Debug = 0;
- }
- }
-
- if ( Pattern == PATTERN_RANDOM ) {
- no_file_check=1;
- if ( write_check_inter || file_check_inter )
- printf("%s%s: %d Using random pattern - no data checking will be performed!\n",
- Progname, TagName, (int)getpid());
- }
- else if ( max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK ) {
- no_file_check=1;
-
- if ( file_check_inter )
- printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
-no whole file checking will be performed!\n", Progname, TagName, (int)getpid());
-
- }
-
- if ( Mode & MODE_RAND_SIZE )
- grow_incr=max_size;
-
- set_sig();
-
- Opid=getpid();
- Pid=Opid;
-
- if ( backgrnd ) {
- if ( Debug > 1 )
- printf("%s: %d DEBUG2 forking, returning control to the user\n",
- Progname, Opid);
- background(Progname); /* give user their prompt back */
- }
-
- if ( Debug > 3 ) {
-#if NEWIO
- lio_set_debug(Debug-3);
-#else
- set_iowrite_debug(Debug-3);
-#endif
- }
-
- /*
- * Print some program information here if debug is turned on to
- * level 3 or higher.
- */
-
- if ( Debug > 2 ) {
-
- if ( Mode & MODE_GROW_BY_LSEEK )
- printf("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_OFFSET )
- printf("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
- Progname, Pid, STATIC_NUM, STATIC_NUM);
- else if ( Pattern == PATTERN_PID )
- printf("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_ASCII )
- printf("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_ALT )
- printf("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_CHKER )
- printf("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_CNTING )
- printf("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_RANDOM )
- printf("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_ONES )
- printf("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
- Progname, Pid);
- else if ( Pattern == PATTERN_ZEROS )
- printf("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
- Progname, Pid);
-
- else
- printf("%s: %d DEBUG3 unknown pattern\n",
- Progname, Pid);
- if ( bytes_to_consume )
- printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
- Progname, Pid, bytes_to_consume);
- printf("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n",
- Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
-
- printf("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
- Progname, Pid, Debug, remove_files);
-
- printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
-
- if ( open_flags == RANDOM_OPEN )
- printf("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n", Progname,
- Pid, io_type);
- else
- printf("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n", Progname,
- Pid, open_flags, io_type);
-
- if ( Mode & MODE_RAND_SIZE ) {
- printf("%s: %d DEBUG3 random write/trunc: min=%d, max=%d, mult = %d\n",
- Progname, Pid, min_size, max_size, mult_size);
- }
- else {
- printf("%s: %d DEBUG3 grow_incr = %d\n",
- Progname, Pid, grow_incr);
- }
- if ( Mode & MODE_RAND_LSEEK ) {
- if ( max_lseek == LSK_EOF )
- printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile>\n",
- Progname, Pid, min_lseek);
- else if ( max_lseek == LSK_EOFPLUSGROW )
- printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile+iosize>\n",
- Progname, Pid, min_lseek);
- else if ( max_lseek == LSK_EOFMINUSGROW )
- printf("%s: %d DEBUG3 random lseek: min=%d, max=<endoffile-iosize>\n",
- Progname, Pid, min_lseek);
- else
- printf("%s: %d DEBUG3 random lseek: min=%d, max=%d\n",
- Progname, Pid, min_lseek, max_lseek);
- }
-
- printf("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
- Progname, Pid, write_check_inter, file_check_inter);
-
- printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
- Progname, Pid, trunc_inter, trunc_incr);
-
- if ( no_file_check )
- printf("%s: %d DEBUG3 no whole file checking will be done\n",
- Progname, Pid);
-
- if ( unlink_inter_ran == -1 ) {
- printf("%s: %d DEBUG3 unlink_inter = %d\n",
- Progname, Pid, unlink_inter);
- } else {
- printf("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n",
- Progname, Pid, unlink_inter, unlink_inter_ran);
- }
-
- if ( Debug > 8 ) {
- num=sizeof(Open_flags)/sizeof(int);
- printf("%s: %d DEBUG9 random open flags values:\n", Progname, Pid);
- for(ind=0; ind<num; ind++) {
- printf("\t%#o\n", Open_flags[ind]);
- }
- }
- } /* end of DEBUG > 2 */
-
- if ( Debug > 1 && num_procs > 1 ) {
- printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
- Opid, num_procs-1);
- }
-
- fflush(stdout); /* ensure pending i/o is flushed before forking */
- fflush(stderr);
-
- forker(num_procs, forker_mode, Progname);
-
- Pid=getpid(); /* reset after the forks */
- /*
- * If user specified random seed(s), get that random seed value.
- * get random seed if it was not specified by the user.
- * This is done after the forks, because pid is used to get the seed.
- */
- if ( Nseeds == 1 ) {
- /*
- * If only one seed specified, all processes will get that seed.
- */
- Seed=Seeds[0];
- } else if ( Nseeds > 1 ) {
- /*
- * More than one seed was specified.
- * The original process gets the first seed. Each
- * process will be get the next seed in the specified list.
- */
- if ( Opid == Pid ) {
- Seed=Seeds[0];
- } else {
- /*
- * If user didn't specify enough seeds, use default method.
- */
- if ( Forker_npids >= Nseeds )
- Seed=time(0) + Pid; /* default random seed */
- else {
- Seed=Seeds[Forker_npids];
- }
- }
- } else {
- /*
- * Generate a random seed based on time and pid.
- * It has a good chance of being unique for each pid.
- */
- Seed=time(0) + Pid; /* default random seed */
- }
-
- random_range_seed(Seed);
-
- if ( using_random && Debug > 0 )
- printf("%s%s: %d DEBUG1 Using random seed of %d\n",
- Progname, TagName, Pid, Seed);
-
- if ( unlink_inter_ran > 0 ) {
- /*
- * Find unlinking file interval. This must be done after
- * the seed was set. This allows multiple copies to
- * get different intervals.
- */
- tmp=unlink_inter;
- unlink_inter=random_range(tmp, unlink_inter_ran, 1, NULL);
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
- Progname, Pid, unlink_inter, tmp, unlink_inter_ran);
- }
-
- /*
- * re-exec all childern if reexec is set to REXEC_DOIT.
- * This is useful on MPP systems to get the
- * child process on another PE.
- */
- if ( reexec == REXEC_DOIT && Opid != Pid ) {
- if ( exec_path == NULL ) {
- exec_path = argv[0];
- /* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
- argv[0] = (char *)malloc(strlen(exec_path) + 2);
- sprintf(argv[0], "-%s", exec_path);
- }
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
- Progname, Pid, __FILE__, __LINE__, argv[0]);
-
- execvp(argv[0], argv);
- }
-
- /*** begin filename stuff here *****/
- /*
- * Determine the number of files to be dealt with
- */
- if ( optind == argc ) {
- /*
- * no cmd line files, therfore, set
- * the default number of auto created files
- */
- if ( ! num_auto_files && ! seq_auto_files )
- num_auto_files=1;
- }
- else {
- first_file_ind=optind;
- num_files += argc-optind;
- }
-
- if ( num_auto_files ) {
- num_files += num_auto_files;
- }
-
- if ( seq_auto_files ) {
- num_files += seq_auto_files;
- }
-
- /*
- * get space for file names
- */
- if ((filenames=(char *)malloc(num_files*PATH_MAX)) == NULL) {
- fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, num_files*PATH_MAX,
- strerror(errno));
- exit(1);
- }
-
- /*
- * fill in filename cmd files then auto files.
- */
-
- num=0;
- if ( first_file_ind ) {
- for(ind=first_file_ind; ind<argc; ind++, num++) {
- strcpy((char *)filenames+(num*PATH_MAX), argv[ind]);
- }
- }
-
- /*
- * construct auto filename and insert them into filenames space
- */
- for(ind=0;ind<num_auto_files; ind++, num++) {
- sprintf((char *)filenames+(num*PATH_MAX), "%s/%s.%d",
- auto_dir, auto_file, ind);
- }
-
- /*
- * construct auto seq filenames
- */
- for(ind=1; ind<=seq_auto_files; ind++, num++) {
- sprintf((char *)filenames+(num*PATH_MAX), "%s/%s%d",
- auto_dir, auto_file, ind);
- }
-
-/**** end filename stuff ****/
-
- if ( time_iterval > 0 )
- start_time=time(0);
-
- /*
- * get space for I/O buffer
- */
- if ( grow_incr ) {
- if ((Buffer=(char *)malloc(grow_incr+Alignment)) == NULL) {
- fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, grow_incr, strerror(errno));
- exit(1);
- }
- if ( Alignment )
- Buffer = Buffer + Alignment;
-
- }
-
- if ( Debug > 2 ) {
- printf("%s: %d DEBUG3 num_files = %d\n",
- Progname, Pid, num_files);
- }
-
- if ( pre_alloc_space ) {
- if ( iterations == 0 ) {
- fprintf(stderr, "%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
- Progname, TagName, Pid, __FILE__, __LINE__);
- exit(1);
- }
- if ( Mode & MODE_RAND_SIZE ) {
- fprintf(stderr,
- "%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
- Progname, TagName, Pid, __FILE__, __LINE__);
- exit(1);
- }
-
- total_grow_value=grow_incr * iterations;
-
- /*
- * attempt to limit
- */
- if ( bytes_to_consume && bytes_to_consume < total_grow_value ) {
- total_grow_value=bytes_to_consume;
- }
- }
-
- /*
- * If delaying between iterations, get amount time to
- * delaysecs in clocks or usecs.
- */
- if ( delaysecs ) {
- delaytime=(int)((float)USECS_PER_SEC * delaysecs);
- }
-
- /*
- * This is the main iteration loop.
- * Each iteration, all files can be opened, written to,
- * read to check the write, check the whole file,
- * truncated, and closed.
- */
- for(Iter_cnt=1; ! stop ; Iter_cnt++) {
-
- if ( iterations && Iter_cnt >= iterations+1 ) {
- strcpy(reason, "Hit iteration value");
- stop=1;
- continue;
- }
-
- if ( (time_iterval > 0) && (start_time + time_iterval < time(0)) ) {
- sprintf(reason, "Hit time value of %d", time_iterval);
- stop=1;
- continue;
- }
-
- if ( bytes_to_consume && bytes_consumed >= bytes_to_consume) {
- sprintf(reason, "Hit bytes consumed value of %d", bytes_to_consume);
- stop=1;
- continue;
- }
-
- /*
- * This loop will loop through all files.
- * Each iteration, a single file can be opened, written to,
- * read to check the write, check the whole file,
- * truncated, and closed.
- */
- for(ind=0; ind<num_files; ind++) {
-
- fflush(stdout);
- fflush(stderr);
-
- filename=(char *)filenames+(ind*PATH_MAX);
- Fileinfo.filename=(char *)filenames+(ind*PATH_MAX);
-
-
- if ( open_flags == RANDOM_OPEN ) {
- ret=Open_flags[random_range(0, sizeof(Open_flags)/sizeof(int)-1, 1, NULL)];
- }
-
- else
- ret=open_flags;
-
- Fileinfo.openflags=ret;
-
- if ( Debug > 3 ) {
- printf("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret,
- openflags2symbols(ret, ",", 0));
- } else if ( Debug > 2 ) {
- printf("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret);
- }
-
- /*
- * open file with desired flags.
- */
- if ( (fd=open(filename, ret, 0777)) == -1 ) {
- fprintf(stderr,
- "%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, filename, ret, errno, strerror(errno));
- handle_error();
- continue;
- }
-
- Fileinfo.fd=fd;
-
- lkfile(fd, LOCK_EX, LKLVL1); /* lock if lockfile is LKLVL1 */
-
- /*
- * preallocation is only done once, if specified.
- */
- if ( pre_alloc_space ) {
- if (pre_alloc(filename, fd, total_grow_value) != 0 ) {
- cleanup();
- exit(2);
- }
- if ( Debug > 1 ) {
- printf("%s: %d DEBUG2 %s/%d: pre_allocated %d for file %s\n",
- Progname, Pid, __FILE__, __LINE__, total_grow_value, filename);
- }
- lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
- close(fd);
- Iter_cnt=0; /* reset outside loop to restart from one */
- continue;
- }
-
- /*
- * grow file by desired amount.
- * growfile() will set the Grow_incr variable and
- * possiblly update the Mode variable indicating
- * if we are dealing with a FIFO file.
- */
-
- if (growfile(fd, filename, grow_incr, (unsigned char *)Buffer) != 0 ) {
- handle_error();
- lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
- close(fd);
- continue;
- }
-
- /*
- * check if last write is not corrupted
- */
- if ( check_write(fd, write_check_inter, filename,
- Mode) != 0 ) {
- handle_error();
- }
-
- /*
- * Check that whole file is not corrupted.
- */
- if ( check_file(fd, file_check_inter, filename,
- no_file_check) != 0 ) {
- handle_error();
- }
-
- /*
- * shrink file by desired amount if it is time
- */
-
- if ( shrinkfile(fd, filename, trunc_incr, trunc_inter, Mode) != 0 ) {
- handle_error();
- }
-
- lkfile(fd, LOCK_UN, LKLVL1); /* release lock */
-
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, fd);
- close(fd);
-
- /*
- * Unlink the file if that is desired
- */
- if ( unlink_inter && (Iter_cnt % unlink_inter == 0) ) {
-
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename);
-
- unlink(filename);
- }
-
- /*
- * delay while staying active for "delaysecs" seconds.
- */
- if ( delaytime ) {
-
- int ct, end;
- struct timeval curtime;
- gettimeofday(&curtime, NULL);
- ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
- end=ct+delaytime;
- while ( ct < end ) {
-
- gettimeofday(&curtime, NULL);
- ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
- }
- }
- }
- /*
- * if Iter_cnt == 0, then we pre allocated space to all files
- * and we are starting outside loop over. Set pre_alloc_space
- * to zero otherwise we get in infinite loop
- */
- if ( Iter_cnt == 0 ) {
- pre_alloc_space=0;
- }
- } /* end iteration for loop */
-
-
- if ( Debug ) {
- printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, num_files, reason);
- }
- fflush(stdout);
- fflush(stderr);
-
- cleanup();
-
- if ( Errors ) {
- if ( Debug > 2 ) {
- printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
- Progname, TagName, Pid, Errors);
- printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
- }
- exit(1);
- }
- if ( Debug > 2 )
- printf("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n", Progname, TagName, Pid, __FILE__, __LINE__);
- exit(0);
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-set_sig()
-{
- int sig;
-
-
- /*
- * now loop through all signals and set the handlers
- */
-
- for (sig = 1; sig < NSIG; sig++) {
- switch (sig) {
- case SIGKILL:
- case SIGSTOP:
- case SIGCONT:
-#ifdef SIGCKPT
- case SIGCKPT:
-#endif /* SIGCKPT */
-#ifdef SIGRESTART
- case SIGRESTART:
-#endif /* SIGRESTART */
- case SIGCHLD:
- break;
-
- default:
- signal(sig, sig_handler);
- break;
- }
- } /* endfor */
-
-
- return 0;
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-void
-sig_handler(sig)
-int sig;
-{
- int exit_stat = 2;
-
- if ( sig == SIGUSR2 ) {
- fprintf(stdout, "%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
- Progname, TagName, Pid, __FILE__, __LINE__, sig);
- signal(sig, sig_handler); /* allow us to get this signal more than once */
-
- } else if( sig == SIGINT ){
- /* The user has told us to cleanup, don't pretend it's an error. */
- exit_stat=0;
- if ( Debug != 0 ){
- fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
- Pid, __FILE__, __LINE__, sig);
- }
- } else {
- fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
- Pid, __FILE__, __LINE__, sig);
- }
-
- notify_others();
- cleanup();
- if ( Debug > 2 ){
- printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
- Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
- }
- exit(exit_stat);
-}
-
-/***********************************************************************
- * this function attempts to send SIGUSR2 to other growfiles processes
- * telling them to stop.
- *
- ***********************************************************************/
-static void
-notify_others()
-{
- static int send_signals = 0;
- int ind;
- extern int Forker_pids[];
- extern int Forker_npids;
-
- if ( Sync_with_others && send_signals == 0 ) {
-
- send_signals=1; /* only send signals once */
-
- for (ind=0; ind< Forker_npids; ind++) {
- if ( Forker_pids[ind] != Pid ) {
- if ( Debug > 1 )
- printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Forker_pids[ind]);
- kill(Forker_pids[ind], SIGUSR2);
- }
- }
- }
-
-}
-
-/***********************************************************************
- * this function will count the number of errors encountered.
- * This function will call upanic if wanted or cleanup and
- * and exit is Maxerrs were encountered.
- ***********************************************************************/
-int
-handle_error()
-{
- Errors++;
-
- if ( Maxerrs && Errors >= Maxerrs ) {
- printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, Maxerrs);
- notify_others();
- cleanup();
-
- if ( Debug > 2 ) {
- printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
- Progname, TagName, Pid, Errors);
- printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
- }
-
- exit(1);
- }
-
- return 0;
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-cleanup()
-{
- int ind;
-
- if ( remove_files ) {
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 Removing all %d files\n",
- Progname, Pid, num_files);
- for(ind=0; ind<=num_files; ind++) {
- unlink(filenames+(ind*PATH_MAX));
- }
- }
- if ( using_random && Debug > 1 )
- printf("%s%s: %d DEBUG2 Used random seed: %d\n",
- Progname, TagName, Pid, Seed);
- return 0;
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-void
-usage()
-{
- fprintf(stderr,
- "Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
- Progname, TagName );
- fprintf(stderr,
- "[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
- fprintf(stderr,
- "[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
- fprintf(stderr,
- "[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
-
- return;
-
-} /* end of usage */
-
-/***********************************************************************
- *
- ***********************************************************************/
-void
-help()
-{
- usage();
-
-fprintf(stdout, "\
- -h Specfied to print this help and exit.\n\
- -b Specfied to execute in sync mode.(def async mode)\n\
- -B maxbytes Max bytes to consume by all files. growfiles exits when more\n\
- than maxbytes have been consumed. (def no chk) If maxbytes ends\n\
- with the letter 'b', maxbytes is multiplied by BSIZE\n\
- -C write_chk Specifies how often to check the last write (default 1)\n\
- -c file_chk Specifies how often to check whole file (default 0)\n\
- -d auto_dir Specifies the directory to auto created files. (default .)\n\
- -D debug_lvl Specifies the debug level (default 1)\n\
- -E Print examples and exit\n\
- -e errs The number errors that will terminate this program (def 100)\n\
- -f auto_file Specifies the base filename files created. (default \"gf\")\n\
- -g grow_incr Specfied to grow by incr for each num. (default 4096)\n\
- grow_incr may end in b for blocks\n\
- If -r option is used, this option is ignored and size is random\n\
- -H delay Amount of time to delay between each file (default 0.0)\n\
- -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
- l - listio sync, L - listio async, r - random\n\
- -i iteration Specfied to grow each file num times. 0 means forever (default 1)\n\
- -l Specfied to do file locking around write/read/trunc\n\
- If specified twice, file locking after open to just before close\n\
- -L time Specfied to exit after time secs, must be used with -i.\n\
- -N num_files Specifies the number of files to be created.\n\
- The default is zero if cmd line files.\n\
- The default is one if no cmd line files.\n\
- -n num_procs Specifies the number of copies of this cmd.\n\
- -o op_type Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
- -O offset adjust i/o buffer alignment by offset bytes\n\
- -P PANIC Specifies to call upanic on error.\n\
- -p Specifies to pre-allocate space\n\
- -q pattern pattern can be a - ascii, p - pid with boff, o boff (def)\n\
- A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
- c - checkboard, C - counting\n\
- -R [min-]max random lseek before write and trunc, max of -1 means filesz,\n\
- -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
- -r [min-]max random io write size (min def is 1)\n\
- -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
- -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
- -t trunc_incr Specfied the amount to shrink file. (default 4096)\n\
- trunc_inter may end in b for blocks\n\
- If -R option is used, this option is ignored and trunc is random\n\
- -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
- -u unlink files before exit\n\
- -U ui[-ui2] Unlink files each ui iteration (def 0)\n\
- -w Specfied to grow via lseek instead of writes.\n\
- -W tag-name Who-am-i. My Monster tag name. (used by Monster).\n\
- -x Re-exec children before continuing - useful on MPP systems\n\
- -y Attempt to sync copies - if one fails it will send sigusr2 to others\n\
- Action to each file every iteration is open, write, write check\n\
- file check, trunc and closed.\n");
-
- return;
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-void
-prt_examples(FILE *stream)
-{
- /* This example creates 200 files in directory dir1. It writes */
- /* 4090 bytes 100 times then truncates 408990 bytes off the file */
- /* The file contents are checked every 1000 grow. */
- fprintf(stream,
- "# run forever: writes of 4090 bytes then on every 100 iterval\n\
-# truncate file by 408990 bytes. Done to 200 files in dir1.\n\
-%s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n", Progname);
-
- /* same as above with 5000 byte grow and a 499990 byte tuncate */
- fprintf(stream,
- "# same as above with writes of 5000 bytes and truncs of 499990\n\
-%s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n", Progname);
-
- /* This example beats on opens and closes */
- fprintf(stream,
- "# runs forever: beats on opens and closes of file ocfile - no io\n\
-%s -i 0 -g 0 -c 0 -C 0 ocfile\n\n", Progname);
-
- fprintf(stream,
- "# writes 4096 to files until 50 blocks are written\n\
-%s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
-
- fprintf(stream,
- "# write one byte to 750 files in gdir then unlinks them\n\
-%s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
-
- fprintf(stream,
- "# run 30 secs: random iosize, random lseek up to eof\n\
-%s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
-
- fprintf(stream,
- "# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
-%s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10 g_sleek1 g_lseek2\n\n", Progname);
-
- fprintf(stream,
- "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
-# rand io types doing a trunc every 5 iterations, with unlinks.\n\
-%s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n",
- Progname);
-
- fprintf(stream,
- "# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
-# random open flags, rand io types doing a trunc every 10 iterations.\n\
-%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",
- Progname);
-
-
- return;
-}
-
-/***********************************************************************
- *
- * The file descriptor current offset is assumed to be the end of the
- * file.
- * Woffset will be set to the offset before the write.
- * Grow_incr will be set to the size of the write or lseek write.
- ***********************************************************************/
-int
-growfile(fd, file, grow_incr, buf)
-int fd;
-char *file;
-int grow_incr;
-unsigned char *buf;
-{
- int noffset;
- int ret;
- /* REFERENCED */
- int cur_offset;
- char *errmsg;
- int fsize; /* current size of file */
- int size_grew; /* size the file grew */
- struct stat stbuf;
- int tmp = 0;
-
- /*
- * Do a stat on the open file.
- * If the file is a fifo, set the bit in Mode variable.
- * This fifo check must be done prior to growfile() returning.
- * Also get the current size of the file.
- */
- if ( fstat(fd, &stbuf) != -1 ) {
- if ( S_ISFIFO(stbuf.st_mode) ) {
- Fileinfo.mode |= MODE_FIFO;
- Mode |= MODE_FIFO;
- if ( Debug > 3 )
- printf("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
- Progname, Pid, __FILE__, __LINE__);
- }
- fsize = stbuf.st_size;
-
- } else {
- fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
-
- return -1;
- }
-
-
- if ( grow_incr <= 0 ) { /* don't attempt i/o if grow_incr <= 0 */
-
- Grow_incr=grow_incr;
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
- Progname, Pid, __FILE__, __LINE__, grow_incr);
- return grow_incr;
- }
-
- if ( Mode & MODE_RAND_SIZE ) {
- grow_incr=random_range(min_size, max_size, mult_size, &errmsg);
- if (errmsg != NULL) {
- fprintf(stderr, "%s%s: %d %s/%d: random_range() failed - %s\n", Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
- return -1;
- }
- Grow_incr=grow_incr;
- }
- else
- Grow_incr=grow_incr;
-
- if ( ! (Mode & MODE_FIFO) ) {
- if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
- return -1;
- }
- }
-
- if ( Mode & MODE_GROW_BY_LSEEK ) {
- Woffset=fsize;
- if ( Debug > 2 ) {
- printf("%s: %d DEBUG3 %s/%d: Current size of file is %d\n", Progname,
- Pid, __FILE__, __LINE__, Woffset);
- printf("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n", Progname,
- Pid, __FILE__, __LINE__, grow_incr-1);
- }
-
- if ((noffset=lseek(fd, grow_incr-1, SEEK_END)) == -1 ) {
- fprintf(stderr, "%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
- Progname, TagName, __FILE__, __LINE__, grow_incr-1, strerror(errno));
- return -1;
- }
-
- lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
-
-#if NEWIO
- ret=lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg,0);
-#else
- ret=write_buffer(fd, io_type, "w", 1, 0, &errmsg);
-#endif
-
- if ( ret != 1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
- if ( ret == -ENOSPC ) {
- cleanup();
- exit(2);
- }
- }
-/***
- write(fd, "w", 1);
-****/
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt);
-
- } else { /* end of grow by lseek */
-
- if ( Fileinfo.openflags & O_APPEND ) {
- /*
- * Deal with special case of the open flag containing O_APPEND.
- * If it does, the current offset does not matter since the write
- * will be done end of the file.
- */
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
- Progname, Pid, __FILE__, __LINE__ );
- lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
-
- /*
- * do fstat again to get size of the file.
- * This is done inside a file lock (if locks are being used).
- */
- if ( fstat(fd, &stbuf) != -1 ) {
- Woffset = stbuf.st_size;
- } else {
- fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
-
- lkfile(fd, LOCK_UN, LKLVL0); /* release lock */
- return -1;
- }
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
- Progname, Pid, __FILE__, __LINE__, (int)stbuf.st_size);
-
-
- } else if ( Mode & MODE_RAND_LSEEK ) {
- if ( max_lseek == LSK_EOF ) { /* within file size */
- noffset=random_range(min_lseek, fsize, 1, NULL);
- }
- else if ( max_lseek == LSK_EOFPLUSGROW ) {
- /* max to beyond file size */
- noffset=random_range(min_lseek, fsize+grow_incr, 1, NULL);
- }
- else if ( max_lseek == LSK_EOFMINUSGROW ) {
- /*
- * Attempt to not grow the file.
- * If the i/o will fit from min_lseek to EOF,
- * pick offset to allow it to fit.
- * Otherwise, pick the min_lseek offset and grow
- * file by smallest amount.
- * If min_lseek is != 0, there will be a problem
- * with whole file checking if file is ever smaller
- * than min_lseek.
- */
- if ( fsize <= min_lseek + grow_incr )
- noffset=min_lseek; /* file will still grow */
- else
- noffset=random_range(min_lseek, fsize-grow_incr, 1, NULL);
- }
- else {
- noffset=random_range(min_lseek, max_lseek, 1, NULL);
- }
-
- if ((Woffset=lseek(fd, noffset, SEEK_SET)) == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l2 failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, noffset, strerror(errno));
- return -1;
- }
- else if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: lseeked to random offset %d (fsz:%d)\n",
- Progname, Pid, __FILE__, __LINE__, Woffset,
- (int)stbuf.st_size);
-
- }
-
- /*
- * lseek to end of file only if not fifo
- */
- else if ( ! (Mode & MODE_FIFO) ) {
- if ((Woffset=lseek(fd, 0, SEEK_END)) == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
- return -1;
- }
- else if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: lseeked to end of file, offset %d\n",
- Progname, Pid, __FILE__, __LINE__, Woffset);
- }
-
- if ( Pattern == PATTERN_OFFSET )
- datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_PID )
- datapidgen(Pid, buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_ASCII )
- dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_RANDOM )
- databingen('r', buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_ALT )
- databingen('a', buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_CHKER )
- databingen('c', buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_CNTING )
- databingen('C', buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_ZEROS )
- databingen('z', buf, grow_incr, Woffset);
- else if ( Pattern == PATTERN_ONES )
- databingen('o', buf, grow_incr, Woffset);
- else
- dataasciigen(NULL, (char *)buf, grow_incr, Woffset);
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
- Progname, Pid, __FILE__, __LINE__, grow_incr);
-
- lkfile(fd, LOCK_EX, LKLVL0); /* get exclusive lock */
-
-/*****
- ret=write(fd, buf, grow_incr);
-
- tmp=tell(fd);
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- if ( ret != grow_incr) {
- fprintf(stderr, "%s: %s/%d: write failed: %s\n",
- Progname, __FILE__, __LINE__, strerror(errno));
- return -1;
- }
-*****/
-
-#if NEWIO
- ret=lio_write_buffer(fd, io_type, (char *)buf, grow_incr,
- SIGUSR1, &errmsg,0);
-#else
- ret=write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
-#endif
-
- if( Mode & MODE_FIFO ){
- /* If it is a fifo then just pretend the file
- * offset is where we think it should be.
- */
- tmp = Woffset + grow_incr;
- }
- else{
- if( (tmp=lseek(fd,0,SEEK_CUR)) < 0 ){ /* get offset after the write */
- fprintf(stderr, "%s%s: %s/%d: tell(2) failed: %d %s\n",
- Progname, TagName, __FILE__, __LINE__, errno, strerror(errno) );
- return -1;
- }
- }
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- if ( ret != grow_incr ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
- if ( ret == -ENOSPC ) {
- cleanup();
- exit(2);
- }
- return -1;
- }
-
- /*
- * Check for a condition where the file was truncated just before
- * the write.
- */
- if ( tmp != Woffset + grow_incr) {
- /*
- * The offset after the write was not as expected.
- * This could be caused by the following:
- * - file truncated after the lseek and before the write.
- * - the file was written to after fstat and before the write
- * and the file was opened with O_APPEND.
- *
- * The pattern written to the file will be considered corrupted.
- */
- if ( Debug > 0 && lockfile ) {
- printf("%s%s: %d DEBUG1 %s/%d: offset after write(%d) not as exp(%d+%d=%d)\n",
- Progname, TagName, Pid, __FILE__, __LINE__, tmp, Woffset, grow_incr, Woffset+grow_incr);
- printf("%s%s: %d DEBUG1 %s/%d: %d Assuming file changed by another process, resetting offset:%d (expect pattern mismatch)\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, tmp-grow_incr);
- }
- if( Debug > 4 ){
- printf("%s: %d DEBUG5 %s/%d: about to chop Woffset. tmp=%d, grow_incr=%d, Woffset was %d\n",
- Progname, Pid, __FILE__, __LINE__, tmp, grow_incr, Woffset);
- }
- Woffset=tmp-grow_incr;
- if( Woffset < 0 )
- Woffset = 0;
- }
-
- } /* end of grow by write */
-
-
- /*
- * Woffset - holds start of grow (start of write expect in grow by lseek)
- * Grow_incr - holds size of grow (write).
- * fsize - holds size of file before write
- */
- size_grew=(Woffset + Grow_incr) - fsize;
- if ( Debug > 1) {
- if ( Mode & MODE_FIFO ) {
- printf("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
- Progname, Pid, __FILE__, __LINE__, Grow_incr, Iter_cnt);
- }
-
- else if ( size_grew > 0 )
- printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), grew file by %d bytes\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset, size_grew);
- else
- printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), did not grow file\n",
- Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset);
- }
-
- bytes_consumed += size_grew;
- return 0;
-
-} /* end of growfile */
-
-/***********************************************************************
- * shrinkfile file by trunc_incr. file can not be made smaller than
- * size zero. Therefore, if trunc_incr is larger than file size,
- * file will be truncated to zero.
- * The file descriptor current offset is assumed to be the end of the
- * file.
- *
- ***********************************************************************/
-int
-shrinkfile(fd, filename, trunc_incr, trunc_inter, just_trunc)
-int fd;
-char *filename;
-int trunc_incr;
-int trunc_inter; /* interval */
-int just_trunc; /* lseek has already been done for you */
-{
- static int shrink_cnt = 0;
- int cur_offset;
- int new_offset;
- int ret;
-
- shrink_cnt++;
-
- if ( trunc_inter == 0 || (shrink_cnt % trunc_inter != 0)) {
- if ( Debug > 3 )
- printf("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
- Progname, Pid, __FILE__, __LINE__, trunc_inter, shrink_cnt);
- return 0; /* not this time */
- }
-
- if ( Mode & MODE_FIFO ) {
- if ( Debug > 5 )
- printf("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
- Progname, Pid, __FILE__, __LINE__);
- return 0; /* can not truncate fifo */
- }
-
- lkfile(fd, LOCK_EX, LKLVL0);
-
- if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, strerror(errno));
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
- }
-
- if ( Mode & MODE_RAND_LSEEK ) {
- if ( max_lseek <= -1 ) {
- if ( (new_offset=file_size(fd)) == -1 ) {
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
- }
-
- if ( new_offset < min_lseek )
- new_offset=min_lseek;
- else
- new_offset=random_range(min_lseek, new_offset, 1, NULL);
- }
- else {
- new_offset=random_range(min_lseek, max_lseek, 1, NULL);
- }
- }
-
- else { /* remove trunc_incr from file */
-
- new_offset = cur_offset-trunc_incr;
-
- if ( new_offset < 0 )
- new_offset=0;
- }
-
- ret=ftruncate(fd, new_offset );
- if( (ret == 0) && (Debug > 3) ){
- printf("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
- Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
- }
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- if ( ret == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
- return -1;
- }
-
- if ( Debug > 2 ) {
- printf("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
- Progname, Pid, __FILE__, __LINE__, cur_offset-new_offset, new_offset);
- }
-
-
- bytes_consumed -= (cur_offset - new_offset);
- return 0;
-
-} /* end of shrinkfile */
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-check_write(fd, cf_inter, filename, mode)
-int fd;
-int cf_inter; /* check file interval */
-char *filename; /* needed for error messages */
-int mode; /* write mode */
-{
- int fsize;
- static int cf_count = 0;
- int ret = 0;
- int tmp;
- char *errmsg;
- char *ptr;
-
- cf_count++;
-
- if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
- Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
- return 0; /* no check done */
- }
-
- if ( Grow_incr <= 0 ) {
- if ( Debug > 3 )
- printf("%s: %d DEBUG4 %s/%d: No write validation, Grow_incr = %d, offset = %d\n",
- Progname, Pid, __FILE__, __LINE__, Grow_incr, Woffset);
- return 0; /* no check */
- }
-
-
-
- /*
- * Get the shared file lock. We need to hold the lock from before
- * we do the stat until after the read.
- */
- lkfile(fd, LOCK_SH, LKLVL0);
-
- if ((fsize=file_size(fd)) == -1 ) {
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
-
- } else if ( fsize <= Woffset ) {
- /*
- * The file was truncated between write and now.
- * The contents of our last write is totally gone, no check.
- */
- if ( Debug > 1 )
- printf("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than where last wrote (%d)- no write validation\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, Woffset);
- lkfile(fd, LOCK_UN, LKLVL0);
- return 0; /* no validation, but not an error */
-
- } else if ( fsize < (Woffset + Grow_incr)) {
- /*
- * The file was truncated between write and now.
- * Part of our last write has been truncated, adjust our Grow_incr
- * to reflect this.
- */
-
- tmp=Grow_incr;
- Grow_incr=fsize-Woffset;
-
- if ( Debug > 1 ) {
-
- printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of wrt(off:%d, sz:%d), adj=%d\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, tmp-Grow_incr, Woffset, tmp, Grow_incr);
- }
-
- }
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: about to do write validation, offset = %d, size = %d\n",
- Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
-
- if ( ! (mode & MODE_FIFO) ) {
-
- if ( lseek(fd, Woffset, 0) == -1 ) {
- fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, 0) failed: %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Woffset, strerror(errno));
- }
- if ( Debug > 3 )
- printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%d\n",
- Progname, Pid, __FILE__, __LINE__, Woffset);
- }
-
- /*
- * Read last writes data
- */
-#if NEWIO
- ret=lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,0);
-#else
- ret=read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
-#endif
-
- /*
- * report the error and debug information before releasing
- * the file lock
- */
- if ( ret != Grow_incr ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
- {
- struct stat stbuf;
- fstat(fd, &stbuf);
- if ( Debug > 2 )
- printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd,
- (int)lseek(fd,SEEK_CUR,0), /* FIXME: 64bit/LFS ? */
- (int)stbuf.st_size,
- Fileinfo.openflags);
- }
-
- lkfile(fd, LOCK_UN, LKLVL0);
- return 1;
- }
-
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- if ( Mode & MODE_GROW_BY_LSEEK ) {
- /* check that all zeros upto last character */
- for(ptr=Buffer; ptr < (Buffer+Grow_incr-1); ptr++) {
- if ( *ptr != '\0' ) {
- fprintf(stderr,
- "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__,
- (int)(Woffset+(Grow_incr-(Buffer-ptr))),
- 0, *ptr, filename);
- fflush(stderr);
- return 1;
- }
- }
- /* check that the last char is a 'w' */
- if ( *ptr != 'w' ) {
- fprintf(stderr,
- "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__,
- (int)(Woffset+(Grow_incr-(Buffer-ptr))), 'w',
- *ptr, filename);
- fflush(stderr);
- return 1;
- }
- return 0; /* all is well */
-
- }
- else if ( Pattern == PATTERN_OFFSET )
- ret=datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_PID )
- ret=datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_ASCII )
- ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_RANDOM )
- ; /* no check for random */
- else if ( Pattern == PATTERN_ALT )
- ret=databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_CHKER )
- ret=databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_CNTING )
- ret=databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_ZEROS )
- ret=databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
- else if ( Pattern == PATTERN_ONES )
- ret=databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
- else
- ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
-
- if ( ret >= 0 ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
-
- if ( Debug > 0 )
- printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, offset:%d, sz:%d open flags:%#o %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, lockfile,
- Woffset, Grow_incr, Fileinfo.openflags, openflags2symbols(Fileinfo.openflags, ",", 0));
-
- fflush(stderr);
- return 1;
- }
-
- if ( Debug > 6 )
- printf("%s: %d DEBUG7 %s/%d: No corruption detected on write validation , offset = %d, size = %d\n",
- Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
-
- return 0; /* all is well */
-}
-
-
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-check_file(fd, cf_inter, filename, no_file_check)
-int fd;
-int cf_inter; /* check file interval */
-char *filename; /* needed for error messages */
-int no_file_check; /* if set, do not do file content check */
-{
- int fsize;
- static int cf_count = 0;
- char *buf;
- int ret;
- int ret_val = 0;
- int rd_cnt;
- int rd_size;
- char *errmsg;
-
- cf_count++;
-
- if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
- Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
- return 0; /* no check done */
- }
-
- /*
- * if we can't determine file content, don't bother checking
- */
- if ( no_file_check ) {
- if ( Debug > 4 )
- printf("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
- Progname, Pid, __FILE__, __LINE__);
- return 0;
- }
-
- /*
- * Lock the file. We need to have the file lock before
- * the stat and until after the last read to prevent
- * a trunc/truncate from "corrupting" our data.
- */
- lkfile(fd, LOCK_SH, LKLVL0);
-
- if ((fsize=file_size(fd)) == -1 ) {
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
- }
-
- if ( fsize == 0 ) {
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
- Progname, Pid, __FILE__, __LINE__);
-
- lkfile(fd, LOCK_UN, LKLVL0);
- return 0;
- }
-
- if ( Debug > 2 )
- printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
- Progname, Pid, __FILE__, __LINE__);
-
- if ( fsize > MAX_FC_READ ) {
- /*
- * read the file in MAX_FC_READ chuncks.
- */
-
- if ((buf=(char *)malloc(MAX_FC_READ)) == NULL ) {
- fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
- __FILE__, __LINE__, MAX_FC_READ, strerror(errno));
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
- }
-
- lseek(fd, 0, SEEK_SET);
-
- lkfile(fd, LOCK_SH, LKLVL0); /* get lock on file before getting file size */
-
- rd_cnt=0;
- while (rd_cnt < fsize ) {
- if ( fsize - rd_cnt > MAX_FC_READ )
- rd_size=MAX_FC_READ;
- else
- rd_size=fsize - rd_cnt;
-
-#if NEWIO
- ret=lio_read_buffer(fd, io_type, buf, rd_size,
- SIGUSR1, &errmsg,0);
-#else
- ret=read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
-#endif
-
- if (ret != rd_size ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
- free(buf);
- lkfile(fd, LOCK_UN, LKLVL0);
- return -1;
- }
-/**
- read(fd, buf, rd_size);
-***/
-
- if ( Pattern == PATTERN_OFFSET )
- ret=datapidchk(STATIC_NUM, buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_PID )
- ret=datapidchk(Pid, buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_ASCII )
- ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_RANDOM )
- ; /* no checks for random */
- else if ( Pattern == PATTERN_ALT )
- ret=databinchk('a', buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_CHKER )
- ret=databinchk('c', buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_CNTING )
- ret=databinchk('C', buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_ZEROS )
- ret=databinchk('z', buf, rd_size, rd_cnt, &errmsg);
- else if ( Pattern == PATTERN_ONES )
- ret=databinchk('o', buf, rd_size, rd_cnt, &errmsg);
- else
- ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
-
-
- if ( ret >= 0 ) {
- fprintf(stderr,
- "%s%s: %d %s/%d: %d CFp %s in file %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
- fflush(stderr);
- ret_val=1;
- lkfile(fd, LOCK_UN, LKLVL0);
- break;
- }
- rd_cnt += rd_size;
- }
-
- lkfile(fd, LOCK_UN, LKLVL0);
-
- free(buf);
-
- }
- else {
- /*
- * Read the whole file in a single read
- */
- if((buf=(char *)malloc(fsize)) == NULL ) {
- fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
- __FILE__, __LINE__, fsize, strerror(errno));
- fflush(stderr);
- return -1;
- }
-
- lseek(fd, 0, SEEK_SET);
-
-/****
- read(fd, buf, fsize);
-****/
-#if NEWIO
- ret=lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,0);
-#else
- ret=read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
-#endif
-
- /* unlock the file as soon as we can */
- lkfile(fd, LOCK_UN, LKLVL0);
-
-
- if ( ret != fsize ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
- ret_val=1;
- }
- else {
- if ( Pattern == PATTERN_OFFSET )
- ret=datapidchk(STATIC_NUM, buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_PID )
- ret=datapidchk(Pid, buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_ASCII )
- ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_RANDOM )
- ; /* no check for random */
- else if ( Pattern == PATTERN_ALT )
- ret=databinchk('a', buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_CHKER )
- ret=databinchk('c', buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_CNTING )
- ret=databinchk('C', buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_ZEROS )
- ret=databinchk('z', buf, fsize, 0, &errmsg);
- else if ( Pattern == PATTERN_ONES )
- ret=databinchk('o', buf, fsize, 0, &errmsg);
- else
- ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
-
- if ( ret >= 0 ) {
- fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s in file %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
- fflush(stderr);
- ret_val=1;
- }
- }
- free(buf);
- }
-
- return ret_val;
-
-} /* end of check_file */
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-file_size(int fd)
-{
- struct stat sb;
-
- if (fstat(fd, &sb) < 0) {
- fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
- return -1;
-
- }
-
- return sb.st_size;
-}
-
-/***********************************************************************
- * do file lock/unlock action.
- ***********************************************************************/
-int
-lkfile(int fd, int operation, int lklevel)
-{
- char *errmsg;
-
-
- if ( lockfile == lklevel) {
-
- if ( Debug > 5 ) {
- switch (operation) {
- case LOCK_UN:
- printf("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
-
- case LOCK_SH:
- printf("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
-
- case LOCK_EX:
- printf("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
- }
- }
-
- /*
- * Attempt to get/release desired lock.
- * file_lock will attempt to do action over and over again until
- * either an unretryable error or the action is completed.
- */
-
- if ( file_lock(fd, operation, &errmsg) != 0 ) {
- printf("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
- Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
-
- /* do we count this as an error? handle_error(); */
- return -1;
- }
-
- if ( Debug > 2 ) {
- switch (operation) {
- case LOCK_UN:
- printf("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
-
- case LOCK_SH:
- printf("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
-
- case LOCK_EX:
- printf("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, fd);
- break;
-
- default:
- printf("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n",
- Progname, Pid, __FILE__, __LINE__, operation, fd);
- break;
- }
- }
- }
-
- return 0;
-}
-
-/***********************************************************************
- *
- ***********************************************************************/
-int
-pre_alloc(file, fd, size)
-char *file;
-int fd;
-int size;
-{
-
-#ifdef XFS_IOC_RESVSP
- struct xfs_flock64 f;
-
- f.l_whence = 0;
- f.l_start = 0;
- f.l_len = size;
-
- /* non-zeroing reservation */
- if( xfsctl( file, fd, XFS_IOC_RESVSP, &f ) == -1 ){
- fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: xfsctl(XFS_IOC_RESVSP) failed: %d %s\n",
- Progname, TagName,
- __FILE__, __LINE__, errno, strerror(errno));
- return -1;
- }
-#else
- struct flock64 f;
-
- f.l_whence = 0;
- f.l_start = 0;
- f.l_len = size;
-
- /* non-zeroing reservation */
- if( fcntl( fd, F_RESVSP64, &f ) == -1 ){
- fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: fcntl(F_RESVSP) failed: %d %s\n",
- Progname, TagName,
- __FILE__, __LINE__, errno, strerror(errno));
- return -1;
- }
-#endif
-
- return 0;
-}