Skip site navigation (1)Skip section navigation (2)
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>