Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site x.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!cybvax0!frog!x!john From: john@x.UUCP (John Woods) Newsgroups: net.sources Subject: Tape Testing Program: Here it is! Message-ID: <493@x.UUCP> Date: Wed, 8-May-85 13:47:25 EDT Article-I.D.: x.493 Posted: Wed May 8 13:47:25 1985 Date-Received: Fri, 10-May-85 02:52:44 EDT Distribution: net Organization: Charles River Data Systems, Framingham MA Lines: 297 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 #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