Subject: bin/15545: restore -i bails when later tape begins with continuation blocks
To: None <gnats-bugs@gnats.netbsd.org>
From: None <perseant@hhhh.org>
List: netbsd-bugs
Date: 02/08/2002 16:41:56
>Number:         15545
>Category:       bin
>Synopsis:       restore -i gives up if any tape begins with continuation blocks
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Feb 08 16:42:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Konrad Schroder
>Release:        NetBSD-current 2002-02-08
>Organization:
------------------------------------------------------------------------
Konrad Schroder          http://www.hitl.washington.edu/people/perseant/
Information Tech & Services   Box 352142 -or- 215 Fluke Hall, Mason Road
Human Interface Technology Lab                  University of Washington
Voice: 206.616.1478   FAX: 206.543.5380     Seattle, WA, 98195-2142, USA
>Environment:
	
System: NetBSD cask 1.5.3_ALPHA NetBSD 1.5.3_ALPHA (CASK) #21: Wed Jan 16 17:53:09 PST 2002 perseant@cask:/usr/src/sys/arch/i386/compile/CASK i386


>Description:
	When restore(8) is called with -i or -x, it advises the user to
	supply tapes in reverse order, and reads the first inode number
	off of the tape to tell whether any of the requested inodes
	might be on that tape or not.  If the last tape (the first one
	read by restore) begins with a continuation of an inode, however,
	files that exist only on earlier tapes are never found, because
	the last tape looks like it must contain all inodes 0..maxino.
>How-To-Repeat:
	I tested with a set of tapes that accidentally exhibited this problem;
	but this should do it:

	Make a filesystem containing several large files (say a quarter of
	a tape in size) and dump it to several tapes.  Then try to restore
	the file with the lowest inum, using restore -i.  If you try the
	lowest numbered tape first it will probably work, but if you try
	the last tape first, probably not.
>Fix:

This fix works for me.  I'd like to get another pair of eyes on this,
however, since I could easily be missing a side-effect somewhere....

Index: tape.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/restore/tape.c,v
retrieving revision 1.44
diff -u -r1.44 tape.c
--- tape.c	2001/12/23 14:40:42	1.44
+++ tape.c	2002/02/09 00:14:45
@@ -1258,6 +1258,7 @@
 	curfile.action = UNKNOWN;
 	curfile.dip = NULL;
 	curfile.ino = 0;
+    top:
 	do {
 		if (header->c_magic != NFS_MAGIC) {
 			skipcnt++;
@@ -1277,7 +1278,8 @@
 			while (gethead(header) == FAIL ||
 			    header->c_date != dumpdate)
 				skipcnt++;
-			break;
+			/* We've read a header; don't drop it. */
+			goto top;
 
 		case TS_INODE:
 			curfile.dip = &header->c_dinode;
>Release-Note:
>Audit-Trail:
>Unformatted: