Tape Testing Program: Here it is!
John Woods
john at x.UUCP
Thu May 9 03:47:25 AEST 1985
Due to a surprising number of requests for the CCC tape tester program, I
am submitting it for your amusement. It worked well for a number of years
at CCC, testing scavenged tapes on scavenged hardware...
-------------chop--slice--grate--and--cut--here----------------------------
echo extract with sh, not csh
echo x README
cat > README << '!Funky!Stuff!'
This is the tape testing program from the Concourse Computer Center at the
Massachussetts Institute of Technology. I believe it was originated by
Mark Plotnick, but most of the CCC crowd has had a hand in doing things to
it since then.
Arguments to it are:
-v Verbose, tells what's going on (quite chatty)
-n Nice, renices itself and does a lot of sleep(2)ing. This
flag may be repeated for increased effect.
-r Set the record size of testing.
-o Set the initial offset from beginning of tape (which is
achieved by doing a write that large).
-f Change the default drive from /dev/rmt0.
tptest writes a pattern out to the tape in uniform blocks until an error
occurs (which is assumed to be End of Tape). It then rewinds and tries to
verify the pattern. Then, a second pass writes a short block at the beginning
of the tape and then writes the pattern to end of tape; this verifies (or
tries to verify) that the tape in the inter-record-gaps of the first pass
is OK.
When it is all done, if the tape was OK, it gets a sequence number from
/usr/lib/tapeseq and tells it to you (so you can uniquely label tapes). We
generally ignored this after the first few dozen, but it seemed a keen idea
at first.
This program ran under V7 and 2.8BSD, on our IBM 729 tape drive (7 track,
200/556/800 bpi, well over a half-ton weight!) and on a slightly more modern
TU-10. The tapeopen() routine assumes that if it can't open the tape drive,
it must be rewinding. Those with different drivers may need to change that.
John Woods,
ihnp4!mit-eddie!jfw, decvax!frog!john
!Funky!Stuff!
echo x makefile
cat > makefile << '!Funky!Stuff!'
CFLAGS = -O
tptest: tptest.o
cc -o tptest tptest.o
install: tptest
cp tptest /usr/lbin
clean:
rm *.o tptest
!Funky!Stuff!
echo x tptest.c
cat > tptest.c << '!Funky!Stuff!'
#include <stdio.h>
#define DFLTRECSIZE 5120
#define DFLTOFFSET 2048
#define MAXRECSIZE (5120*4)
#define SLEEPEVERY 10
char buf[MAXRECSIZE];
char pattern[MAXRECSIZE];
int Recsize = DFLTRECSIZE;
struct flags {
int slow;
int verbose;
} Flags;
int Tapefd, Seed;
char *drivename = "/dev/rmt0"; /* default drive name */
genpat(seed)
{
register int i = Recsize;
register char *patp = pattern;
register char *p = buf;
seed += Seed;
while(--i) {
*patp++ = seed++ /* & 0377 */ ;
*p++ = 0;
}
patp = pattern;
strncpy(patp,"tptest",6);
}
check()
{
register int i = Recsize;
register char *patp = pattern;
register char *p = buf;
while(--i)
if (*patp++ != *p++)
return (-1);
return (0);
}
main(argc,argv)
int argc;
char **argv;
{
int nrecords;
int offset = DFLTOFFSET;
long time();
if (getuid()) nice(20);
close(2);
dup(1);
setbuf(stdout, NULL); /* both stdout and stderr go to same place
and are unbuffered */
printf("pid %d\n",getpid());
while (argc > 1 && argv[1][0]=='-') {
switch(argv[1][1]) {
case 'n':
Flags.slow++;
break;
case 'v':
Flags.verbose++;
break;
case 'r':
Recsize = atoi(&argv[1][2]);
if (Recsize <= 0 || Recsize > MAXRECSIZE) {
printf("recsize %d too large\n", Recsize);
exit(1);
}
break;
case 'o':
offset = atoi(&argv[1][2]);
if (offset <= 0 || offset > MAXRECSIZE) {
printf("offset %d too large\n", offset);
exit(1);
}
if (offset > DFLTRECSIZE)
printf("offset %d is rather large\n", offset);
break;
case 'f':
drivename = &argv[1][2];
break;
}
argv++, argc--;
}
printf("slow=%d, Recsize=%d, offset for pass2 = %d\n",
Flags.slow, Recsize, offset);
printf("Pass 1:\n");
Seed = (int)time((char *)0);
if (Flags.verbose)
printf("Seed=%d\n", Seed);
tapeopen(1, 0);
nrecords = tapewrite(0); /* test with an offset of 0 */
tapeopen(0, 10);
taperead(0, nrecords);
printf("Finished pass 1\n");
tapeopen(1, 10);
printf("Beginning pass 2\n");
Seed = (int)time((char *)0);
if (Flags.verbose)
printf("Seed=%d\n", Seed);
nrecords = tapewrite(offset);
tapeopen(0, 10);
taperead(offset, nrecords);
printf("finished pass 2\nDone, no errors\n");
newseqnumber();
exit(0);
}
tapewrite(offset)
{
int nrecords, n;
long tplength = 0;
printf("Writing...\n");
if (Flags.verbose) printf("offset=%d\n", offset);
if (offset)
write(Tapefd, buf, offset); /* who cares what buf contains? */
for(nrecords=0;;nrecords++) {
genpat(nrecords);
if ((n=write (Tapefd,pattern,Recsize))!=Recsize) {
if (n == -1)
perror("Tape write error (presumably EOT)");
/* this isn't fatal, really...*/
break;
}
if (Flags.verbose)
printf("w");
tplength += Recsize;
if (Flags.slow && ((nrecords%SLEEPEVERY) == 0)) {
sleep(Flags.slow);
if (Flags.verbose) printf("s");
}
}
printf ("%d records, unformatted tape length = %ld bytes\n",
nrecords, tplength);
printf("Finished writing; Rewinding...\n");
close (Tapefd);
return(nrecords);
}
taperead(offset, nrecords)
{
register int r2, n;
printf ("Reading ...\n");
if (Flags.verbose)
printf("offset=%d, nrecords=%d\n", offset, nrecords);
if (offset)
read(Tapefd, buf, offset);
for (r2=0;r2<nrecords;r2++) {
genpat(r2);
if ((n=read(Tapefd,buf,Recsize)) != Recsize) {
if (n == -1)
perror("Read error");
else
printf ("recsiz error, record %d;", r2),
printf ("actual=%d, expected=%d\n", n, Recsize);
exit(3);
}
if (Flags.verbose) printf("r");
if (check()<0) {
printf ("data error: record %d\n", r2);
exit(4);
}
if (Flags.slow && ((r2%SLEEPEVERY) == 0)) {
sleep(Flags.slow);
if(Flags.verbose) printf("s");
}
}
printf("Done reading; Rewinding...\n");
close(Tapefd);
}
newseqnumber()
{
FILE *seqfd;
int seqnum;
if ((seqfd=fopen ("/usr/lib/tapeseq","r+")) == NULL) {
printf ("warning: creating new sequence file\n");
umask(000);
close(creat ("/usr/lib/tapeseq",0666));
seqfd = fopen ("/usr/lib/tapeseq","r+");
fprintf(seqfd, "0");
rewind(seqfd);
}
fscanf (seqfd,"%d",&seqnum);
rewind(seqfd);
fprintf(seqfd,"%d\n",seqnum+1);
printf("Sequence number = %d\n", seqnum+1);
fclose (seqfd);
}
tapeopen(mode, sleeptime)
{
if (Flags.verbose)
printf("mode=%d, sleeptime=%d\n", mode, sleeptime);
if (sleeptime==0) { /* means die if can't open immediately */
Tapefd = open (drivename, mode);
if (Tapefd == -1) {
perror("Can't open tape drive");
exit(2);
} else
return;
}
while ((Tapefd=open(drivename, mode)) < 0) {
if(Flags.verbose) printf("s");
sleep(sleeptime);
}
return;
}
!Funky!Stuff!
exit 0
--
John Woods, Charles River Data Systems, Framingham MA, (617) 626-1101
...!decvax!frog!john, ...!mit-eddie!jfw, jfw%mit-ccc at MIT-XX.ARPA
"MU" said the Sacred Chao...
More information about the Comp.sources.unix
mailing list