From patchwork Wed Feb 19 21:52:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Sterba X-Patchwork-Id: 13983053 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC51F216389 for ; Wed, 19 Feb 2025 21:52:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.135.223.130 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740001962; cv=none; b=m59z8eU5mXjuboyClqMP8Y4ki/ArJzrtyoH0+B4Sym2Y0JqPWs1BzV99bEuIWJpKvRAKY9Pkv378AeqjvGpN/gT7TxLhgn9tdkt796cluMYLdWdYfSTYFasFq453/CFAwdFeBdfi/Z7CqZ0y63iM85377QyOfgNS/sSPd2hqI9g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1740001962; c=relaxed/simple; bh=H305kc5DUkAh2evk6SgWjhtLXToYKBKUdb1nMzaqhHY=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=Z/TZKo1vIV403Y2YmUz5/MsHHgmQd1+wC4x2unFEniA4GmU89AlaTgS6/VFuL/h9Fs7uUVFMxPrp06id26s/BsSgT4oUA4Jnwfuw7H9fidoj7G201xhjdPkbHlX0NL4YVRtyz3M0HvAtQrNtbPe3bsAcja09l3OsFkISMKbBjfM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (1024-bit key) header.d=suse.com header.i=@suse.com header.b=fkAn7Cyp; dkim=pass (1024-bit key) header.d=suse.com header.i=@suse.com header.b=ERMapSD+; arc=none smtp.client-ip=195.135.223.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=suse.com header.i=@suse.com header.b="fkAn7Cyp"; dkim=pass (1024-bit key) header.d=suse.com header.i=@suse.com header.b="ERMapSD+" Received: from imap1.dmz-prg2.suse.org (unknown [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id D274A2122E; Wed, 19 Feb 2025 21:52:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1740001955; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7zdmb8qCfeLfEHGVOnIVvLHdW1Lv+jMJhmjaiQiaYh4=; b=fkAn7Cypx+GwRzfrYzsLYdq4+siXwLWV6aTstnRyg6Ftq6eK838fYX45gbUI0c6s7ze5e0 vnZw5eT+DSzWZg2e2z6MVQWZeM6N3jwsA4tShmHxic0yFN+WQ66RAdSTMe72Iw2Y/lbPm6 BebyTa/n+3E4CBZmui1AaFEhwm0PA/c= Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1740001954; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=7zdmb8qCfeLfEHGVOnIVvLHdW1Lv+jMJhmjaiQiaYh4=; b=ERMapSD+W167Vs5q+UWQdRIIVgY97owogES1GsPjGXPlhT5IPi9XfyIaI4u8XdqvXQH8Ln dY3jjx3DDOIkmK/WqYPiMLkR2PBgW/coZ1E85dEUqtT014Wx80RQtBzNWhBWlPkt5BEgI5 vCpsf1Q6gEbwxdmVGEY8Vgh+mRnVfic= Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id C618413715; Wed, 19 Feb 2025 21:52:34 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id 0CMWMKJStmeALAAAD6G6ig (envelope-from ); Wed, 19 Feb 2025 21:52:34 +0000 From: David Sterba To: fstests@vger.kernel.org Cc: David Sterba Subject: [PATCH] Remove ltp/growfiles Date: Wed, 19 Feb 2025 22:52:28 +0100 Message-ID: <20250219215229.15045-1-dsterba@suse.com> X-Mailer: git-send-email 2.47.1 Precedence: bulk X-Mailing-List: fstests@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Level: X-Spamd-Result: default: False [-2.80 / 50.00]; BAYES_HAM(-3.00)[100.00%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.20)[-1.000]; MIME_GOOD(-0.10)[text/plain]; RCPT_COUNT_TWO(0.00)[2]; RCVD_VIA_SMTP_AUTH(0.00)[]; MIME_TRACE(0.00)[0:+]; ARC_NA(0.00)[]; DKIM_SIGNED(0.00)[suse.com:s=susede1]; FUZZY_BLOCKED(0.00)[rspamd.com]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; TO_MATCH_ENVRCPT_ALL(0.00)[]; DBL_BLOCKED_OPENRESOLVER(0.00)[imap1.dmz-prg2.suse.org:helo,suse.com:email,suse.com:mid]; RCVD_TLS_ALL(0.00)[] X-Spam-Score: -2.80 X-Spam-Flag: NO This utility is not used by any current test and seems that it's never been used in xfstests, so remove it. Appending files can be simply done by 'xfs_io' command too. Signed-off-by: David Sterba Reviewed-by: "Darrick J. Wong" Reviewed-by: Zorro Lang --- .gitignore | 1 - lib/tlibio.c | 2 +- ltp/Makefile | 2 +- ltp/growfiles.c | 2607 ----------------------------------------------- 4 files changed, 2 insertions(+), 2610 deletions(-) delete mode 100644 ltp/growfiles.c diff --git a/.gitignore b/.gitignore index 7060f52cf6b87e..4fd817243dca37 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,6 @@ tags /ltp/doio /ltp/fsstress /ltp/fsx -/ltp/growfiles /ltp/iogen # src/ binaries diff --git a/lib/tlibio.c b/lib/tlibio.c index f7259734af97c7..5b81005952119d 100644 --- a/lib/tlibio.c +++ b/lib/tlibio.c @@ -211,7 +211,7 @@ lio_set_debug(int level) * Only the first character of the string is used. * * This function does not provide for meaningful option arguments, - * but it supports current growfiles/btlk interface. + * but it supports current btlk interface. * * (rrl 04/96) ***********************************************************************/ diff --git a/ltp/Makefile b/ltp/Makefile index 0611c5efe96b14..b707924c808042 100644 --- a/ltp/Makefile +++ b/ltp/Makefile @@ -5,7 +5,7 @@ TOPDIR = .. include $(TOPDIR)/include/builddefs -TARGETS = doio fsstress fsx growfiles iogen +TARGETS = doio fsstress fsx iogen SCRIPTS = rwtest.sh CFILES = $(TARGETS:=.c) HFILES = doio.h diff --git a/ltp/growfiles.c b/ltp/growfiles.c deleted file mode 100644 index 7ac44aba0bede0..00000000000000 --- a/ltp/growfiles.c +++ /dev/null @@ -1,2607 +0,0 @@ -// 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 -#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 /* */ - /* 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%d per word pattern multi-writers.\n", - Progname, Pid, STATIC_NUM, STATIC_NUM); - else if ( Pattern == PATTERN_PID ) - printf("%s: %d DEBUG3 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=\n", - Progname, Pid, min_lseek); - else if ( max_lseek == LSK_EOFPLUSGROW ) - printf("%s: %d DEBUG3 random lseek: min=%d, max=\n", - Progname, Pid, min_lseek); - else if ( max_lseek == LSK_EOFMINUSGROW ) - printf("%s: %d DEBUG3 random lseek: min=%d, max=\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 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 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 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; -}