Date: Thu, 29 Apr 1999 11:08:24 -0500 (CDT) From: dkelly@hiwaay.net To: FreeBSD-gnats-submit@freebsd.org Subject: bin/11386: some small tcopy enhancements Message-ID: <199904291608.LAA53852@nospam.hiwaay.net>
next in thread | raw e-mail | index | archive | help
>Number: 11386 >Category: bin >Synopsis: counter sizes and file rewind >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Thu Apr 29 09:10:01 PDT 1999 >Closed-Date: >Last-Modified: >Originator: David Kelly >Release: FreeBSD 3.1-STABLE i386 >Organization: n/a >Environment: FreeBSD nospam.hiwaay.net 3.1-STABLE FreeBSD 3.1-STABLE #8: Wed Apr 14 20:36:28 CDT 1999 dkelly@nospam.hiwaay.net:/usr/src/sys/compile/REEBOK i386 >Description: Tcopy uses 32 bit unsigned to accumulate a count of bytes read/written. That doesn't work well for tapes over 4G. I use tcopy a lot to write images of a tape to tape as tape to tape copying is terribly slow. Slower than it should be. Quickly found out tcopy can not rewind a file when doing copy/verify. >How-To-Repeat: Tcopy a tape larger than 4g. tcopy -c file1 file2 --> this will produce an ioctl() error on rewind. >Fix: The following diffs correct the source and manpage: % diff -ruN tcopy.c.orig tcopy.c --- tcopy.c.orig Sun Mar 8 07:36:24 1998 +++ tcopy.c Mon Apr 5 16:37:45 1999 @@ -65,7 +65,7 @@ #define NOCOUNT (-2) int filen, guesslen, maxblk = MAXREC; -u_long lastrec, record, size, tsize; +u_int64_t lastrec, record, size, tsize; FILE *msg = stdout; void *getspace __P((int)); @@ -73,6 +73,7 @@ static void usage __P((void)); void verify __P((int, int, char *)); void writeop __P((int, int)); +void rewind_tape(int); int main(argc, argv) @@ -156,16 +157,16 @@ if (nread >= 0) goto r1; } - err(1, "read error, file %d, record %ld", filen, record); + err(1, "read error, file %d, record %qu", filen, record); } else if (nread != lastnread) { if (lastnread != 0 && lastnread != NOCOUNT) { if (lastrec == 0 && nread == 0) - fprintf(msg, "%ld records\n", record); + fprintf(msg, "%qu records\n", record); else if (record - lastrec > 1) - fprintf(msg, "records %ld to %ld\n", + fprintf(msg, "records %qu to %qu\n", lastrec, record); else - fprintf(msg, "record %ld\n", lastrec); + fprintf(msg, "record %qu\n", lastrec); } if (nread != 0) fprintf(msg, "file %d: block size %d: ", @@ -183,9 +184,9 @@ nw = write(outp, buff, nread); if (nw != nread) { if (nw == -1) { - warn("write error, file %d, record %ld", filen, record); + warn("write error, file %d, record %qu", filen, record); } else { - warnx("write error, file %d, record %ld", filen, record); + warnx("write error, file %d, record %qu", filen, record); warnx("write (%d) != read (%d)", nw, nread); } errx(5, "copy aborted"); @@ -199,7 +200,7 @@ break; } fprintf(msg, - "file %d: eof after %lu records: %lu bytes\n", + "file %d: eof after %qu records: %qu bytes\n", filen, record, size); needeof = 1; filen++; @@ -209,14 +210,14 @@ } lastnread = nread; } - fprintf(msg, "total length: %lu bytes\n", tsize); + fprintf(msg, "total length: %qu bytes\n", tsize); (void)signal(SIGINT, oldsig); if (op == COPY || op == COPYVERIFY) { writeop(outp, MTWEOF); writeop(outp, MTWEOF); if (op == COPYVERIFY) { - writeop(outp, MTREW); - writeop(inp, MTREW); + rewind_tape(outp); + rewind_tape(inp); verify(inp, outp, buff); } } @@ -283,10 +284,10 @@ { if (record) if (record - lastrec > 1) - fprintf(msg, "records %ld to %ld\n", lastrec, record); + fprintf(msg, "records %qu to %qu\n", lastrec, record); else - fprintf(msg, "record %ld\n", lastrec); - fprintf(msg, "interrupt at file %d: record %ld\n", filen, record); + fprintf(msg, "record %qu\n", lastrec); + fprintf(msg, "interrupt at file %d: record %qu\n", filen, record); fprintf(msg, "total length: %ld bytes\n", tsize + size); exit(1); } @@ -319,4 +320,23 @@ { fprintf(stderr, "usage: tcopy [-cvx] [-s maxblk] [src [dest]]\n"); exit(1); +} + +void +rewind_tape(int fd) +{ + struct stat sp; + + if(fstat(fd, &sp)) + errx(12, "fstat in rewind"); + + /* + * don't want to do tape ioctl on regular files: + */ + if( S_ISREG(sp.st_mode) ) { + if( lseek(fd, 0, SEEK_SET) == -1 ) + errx(13, "lseek"); + } else + /* assume its a tape */ + writeop(fd, MTREW); } % diff -ruN tcopy.1.orig tcopy.1 --- tcopy.1.orig Fri Feb 12 15:26:42 1999 +++ tcopy.1 Thu Apr 29 09:54:17 1999 @@ -87,3 +87,19 @@ .Nm command appeared in .Bx 4.3 . +.Sh BUGS +Writting an image of a tape to a file does not preserve much more than +the raw data. Block size(s) and tape EOF marks are lost which would +otherwise be preserved in a tape-to-tape copy. + +EOD is determined by two sequential EOF marks with no data between. +There are old systems which typically wrote three EOF's between tape +files. +.Xr tcopy 1 +will erroneously stop copying early in this case. + +When using the copy/verify option \-c +.Xr tcopy 1 +does not rewind the tapes prior to start. A rewind is performed +after writing prior to the verification stage. If one doesn't start +at BOT then the comparison may not be of the intended data. >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199904291608.LAA53852>