bukys@rochester.UUCP (07/06/83)
Here's a copy of a bug report I just sent in to 4bsd-bugs@Berkeley. In summary: for some reason I haven't guessed, one of the dumped directories in my 4.1->4.1c conversion dump tape was a little strange, with the result that restor ignored most of the directory structure, hence skipped most of the files on tape. A two-line fix got my files back for me. Hope I've saved somebody some work. >From: bukys@rochester.ARPA >To: 4bsd-bugs@Berkeley >Subject: 4.1c restor bug >Index: etc/restor 4.1c Fix Description: It is possible for a dump(8) tape to have an inconsistent idea of the length of a file. (It happened to me!) Then restor(8) may find a data block when it is expecting a header block. As the header parsing routine does a consistency check, this should not be much of a problem. However, in one case the code does not check the value returned by the header parsing routine, and treats the data block as a very strange header block. If this happens while reading directory files from the tape, it will think it has reached the end of the directory dump, but will not have built up the entire directory structure. (This is what happened to me.) The subsequent restoration will skip the files without corresponding directory information. Repeat-By: I suppose I could send you the tape. The problem was that the inode said that the file was 1056 bytes (2 blocks) long, but the c_addr array said there were 3 data blocks (there were). Furthermore, this file (a directory!) had a hole. The most obvious warning was 150 "missing directory entry" messages. The second most obvious warning was that very few files were getting restored. Fix: (version is "@(#)restor.c 2.17 1/8/83") (line 769) (fix in #ifdef UR) if ((size -= TP_BSIZE) <= 0) { #ifdef UR while (gethead(&spcl) == 0) fprintf(stderr, "warning: discrepancy between c_addr array and inode's di_size: data block ignored\n"); #else gethead(&spcl); #endif goto out; } Comments: A more general fix might trust the c_addr array more than the size stated in the inode. That's more complicated than this one-line fix, though. And this is, after all, a problem that "should never happen", as they say. While you're there, it should check all results from calloc() and malloc() for NULL, especially since getleaves() can build up quite a structure. And, whenever you get around to re-implementing the 'r' flag, it should *say something* if it skips a file on the tape (this should never happen on a full restore). --------------- Liudvikas Bukys rochester!bukys bukys@rochester
bukys@rochester.UUCP (07/06/83)
Relay-Version:version B 2.10 5/3/83; site wjh12.UUCP Posting-Version:version B 2.10 5/3/83; site rochester.UUCP Path:wjh12!genrad!linus!philabs!seismo!rochester!bukys Message-ID:<2150@rochester.UUCP> Date:Tue, 5-Jul-83 21:06:35 EDT Organization:University of Rochester Here's a copy of a bug report I just sent in to 4bsd-bugs@Berkeley. In summary: for some reason I haven't guessed, one of the dumped directories in my 4.1->4.1c conversion dump tape was a little strange, with the result that restor ignored most of the directory structure, hence skipped most of the files on tape. A two-line fix got my files back for me. Hope I've saved somebody some work. >From: bukys@rochester.ARPA >To: 4bsd-bugs@Berkeley >Subject: 4.1c restor bug >Index: etc/restor 4.1c Fix Description: It is possible for a dump(8) tape to have an inconsistent idea of the length of a file. (It happened to me!) Then restor(8) may find a data block when it is expecting a header block. As the header parsing routine does a consistency check, this should not be much of a problem. However, in one case the code does not check the value returned by the header parsing routine, and treats the data block as a very strange header block. If this happens while reading directory files from the tape, it will think it has reached the end of the directory dump, but will not have built up the entire directory structure. (This is what happened to me.) The subsequent restoration will skip the files without corresponding directory information. Repeat-By: I suppose I could send you the tape. The problem was that the inode said that the file was 1056 bytes (2 blocks) long, but the c_addr array said there were 3 data blocks (there were). Furthermore, this file (a directory!) had a hole. The most obvious warning was 150 "missing directory entry" messages. The second most obvious warning was that very few files were getting restored. Fix: (version is "@(#)restor.c 2.17 1/8/83") (line 769) (fix in #ifdef UR) if ((size -= TP_BSIZE) <= 0) { #ifdef UR while (gethead(&spcl) == 0) fprintf(stderr, "warning: discrepancy between c_addr array and inode's di_size: data block ignored\n"); #else gethead(&spcl); #endif goto out; } Comments: A more general fix might trust the c_addr array more than the size stated in the inode. That's more complicated than this one-line fix, though. And this is, after all, a problem that "should never happen", as they say. While you're there, it should check all results from calloc() and malloc() for NULL, especially since getleaves() can build up quite a structure. And, whenever you get around to re-implementing the 'r' flag, it should *say something* if it skips a file on the tape (this should never happen on a full restore). --------------- Liudvikas Bukys rochester!bukys bukys@rochester