summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2002-02-18 02:29:47 +0000
committeriedowse <iedowse@FreeBSD.org>2002-02-18 02:29:47 +0000
commitd533053fe68906076e15c9a57531ef155a7d4283 (patch)
tree2da5228d4449565976adb2ac632119a9976668b1
parentcc757467188b1933c356a3895eb1032d3f428a83 (diff)
downloadFreeBSD-src-d533053fe68906076e15c9a57531ef155a7d4283.zip
FreeBSD-src-d533053fe68906076e15c9a57531ef155a7d4283.tar.gz
Use a more robust scheme for determining how many blocks to skip
after an EOT-terminated volume. We keep track of the current record number, and synchronise it with the c_tapea field each time we read a header. Avoid the use of c_firstrec because some bugs in dump can cause it to be set incorrectly. Move the initialisation of some variables to avoid compiler warnings.
-rw-r--r--sbin/restore/tape.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c
index 62c5fbf..4bfa5fa 100644
--- a/sbin/restore/tape.c
+++ b/sbin/restore/tape.c
@@ -74,7 +74,7 @@ static int numtrec;
static char *tapebuf;
static union u_spcl endoftapemark;
static long blksread; /* blocks read since last header */
-static long tpblksread = 0; /* TP_BSIZE blocks read */
+static long tapeaddr = 0; /* current TP_BSIZE tape record */
static long tapesread;
static jmp_buf restart;
static int gettingfile = 0; /* restart has a valid frame */
@@ -211,7 +211,6 @@ setup()
if (gethead(&spcl) == FAIL) {
blkcnt--; /* push back this block */
blksread--;
- tpblksread--;
cvtflag++;
if (gethead(&spcl) == FAIL) {
fprintf(stderr, "Tape is not a dump tape\n");
@@ -300,7 +299,7 @@ void
getvol(nextvol)
long nextvol;
{
- long newvol, savecnt, savetpcnt, i;
+ long newvol, prevtapea, savecnt, i;
union u_spcl tmpspcl;
# define tmpbuf tmpspcl.s_spcl
char buf[TP_BSIZE];
@@ -309,6 +308,8 @@ getvol(nextvol)
tapesread = 0;
gettingfile = 0;
}
+ prevtapea = tapeaddr;
+ savecnt = blksread;
if (pipein) {
if (nextvol != 1) {
panic("Changing volumes on pipe input?\n");
@@ -320,10 +321,7 @@ getvol(nextvol)
return;
goto gethdr;
}
- savecnt = blksread;
- savetpcnt = tpblksread;
again:
- tpblksread = savetpcnt;
if (pipein)
done(1); /* pipes do not get a second chance */
if (command == 'R' || command == 'r' || curfile.action != SKIP)
@@ -425,11 +423,10 @@ gethdr:
* If coming to this volume at random, skip to the beginning
* of the next record.
*/
- dprintf(stdout, "read %ld recs, tape starts with %ld\n",
- tpblksread, tmpbuf.c_firstrec);
+ dprintf(stdout, "last rec %ld, tape starts with %ld\n", prevtapea,
+ tmpbuf.c_tapea);
if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) {
if (curfile.action != USING) {
- tpblksread = tmpbuf.c_firstrec;
/*
* XXX Dump incorrectly sets c_count to 1 in the
* volume header of the first tape, so ignore
@@ -438,12 +435,17 @@ gethdr:
if (volno != 1)
for (i = tmpbuf.c_count; i > 0; i--)
readtape(buf);
- } else if (tmpbuf.c_firstrec > 0 &&
- tmpbuf.c_firstrec < tpblksread - 1) {
+ } else if (tmpbuf.c_tapea <= prevtapea) {
/*
- * -1 since we've read the volume header
+ * Normally the value of c_tapea in the volume
+ * header is the record number of the header itself.
+ * However in the volume header following an EOT-
+ * terminated tape, it is the record number of the
+ * first continuation data block (dump bug?).
+ *
+ * The next record we want is `prevtapea + 1'.
*/
- i = tpblksread - tmpbuf.c_firstrec - 1;
+ i = prevtapea + 1 - tmpbuf.c_tapea;
dprintf(stderr, "Skipping %ld duplicate record%s.\n",
i, i > 1 ? "s" : "");
while (--i >= 0)
@@ -855,7 +857,7 @@ readtape(buf)
if (blkcnt < numtrec) {
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
blksread++;
- tpblksread++;
+ tapeaddr++;
return;
}
for (i = 0; i < ntrec; i++)
@@ -961,7 +963,7 @@ getmore:
blkcnt = 0;
memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE);
blksread++;
- tpblksread++;
+ tapeaddr++;
}
static void
@@ -1153,6 +1155,7 @@ good:
buf->c_dinode.di_uid = buf->c_dinode.di_ouid;
buf->c_dinode.di_gid = buf->c_dinode.di_ogid;
}
+ tapeaddr = buf->c_tapea;
if (dflag)
accthdr(buf);
return(GOOD);
OpenPOWER on IntegriCloud