fix debugging across tapes; account for dumpmap at start of every tape
authorKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Sun, 6 Mar 1983 08:18:42 +0000 (00:18 -0800)
committerKirk McKusick <mckusick@ucbvax.Berkeley.EDU>
Sun, 6 Mar 1983 08:18:42 +0000 (00:18 -0800)
SCCS-vsn: sbin/restore/main.c 3.5
SCCS-vsn: sbin/restore/tape.c 3.6
SCCS-vsn: sbin/restore/restore.c 3.5

usr/src/sbin/restore/main.c
usr/src/sbin/restore/restore.c
usr/src/sbin/restore/tape.c

index 9ef5111..0b551fc 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
-static char sccsid[] = "@(#)main.c     3.4     (Berkeley)      83/02/28";
+static char sccsid[] = "@(#)main.c     3.5     (Berkeley)      83/03/05";
 #endif
 
 /*
 #endif
 
 /*
@@ -85,6 +85,10 @@ usage:
                        yflag++;
                        break;
                case 'f':
                        yflag++;
                        break;
                case 'f':
+                       if (argc < 1) {
+                               fprintf(stderr, "missing device specifier\n");
+                               done(1);
+                       }
                        inputdev = *argv++;
                        argc--;
                        break;
                        inputdev = *argv++;
                        argc--;
                        break;
@@ -92,6 +96,10 @@ usage:
                        /*
                         * dumpnum (skip to) for multifile dump tapes
                         */
                        /*
                         * dumpnum (skip to) for multifile dump tapes
                         */
+                       if (argc < 1) {
+                               fprintf(stderr, "missing dump number\n");
+                               done(1);
+                       }
                        dumpnum = atoi(*argv++);
                        if (dumpnum <= 0) {
                                fprintf(stderr, "Dump number must be a positive integer\n");
                        dumpnum = atoi(*argv++);
                        if (dumpnum <= 0) {
                                fprintf(stderr, "Dump number must be a positive integer\n");
@@ -100,40 +108,16 @@ usage:
                        argc--;
                        break;
                case 't':
                        argc--;
                        break;
                case 't':
-                       if (command != '\0') {
-                               fprintf(stderr,
-                                       "t and %c are mutually exclusive\n",
-                                       command);
-                               goto usage;
-                       }
-                       command = 't';
-                       break;
                case 'R':
                case 'R':
-                       if (command != '\0') {
-                               fprintf(stderr,
-                                       "R and %c are mutually exclusive\n",
-                                       command);
-                               goto usage;
-                       }
-                       command = 'R';
-                       break;
                case 'r':
                case 'r':
-                       if (command != '\0') {
-                               fprintf(stderr,
-                                       "r and %c are mutually exclusive\n",
-                                       command);
-                               goto usage;
-                       }
-                       command = 'r';
-                       break;
                case 'x':
                        if (command != '\0') {
                                fprintf(stderr,
                case 'x':
                        if (command != '\0') {
                                fprintf(stderr,
-                                       "x and %c are mutually exclusive\n",
-                                       command);
+                                       "%c and %c are mutually exclusive\n",
+                                       *cp, command);
                                goto usage;
                        }
                                goto usage;
                        }
-                       command = 'x';
+                       command = *cp;
                        break;
                default:
                        fprintf(stderr, "Bad key character %c\n", *cp);
                        break;
                default:
                        fprintf(stderr, "Bad key character %c\n", *cp);
@@ -161,7 +145,10 @@ usage:
                                fprintf(stderr, "%s: not on tape\n", name);
                                continue;
                        }
                                fprintf(stderr, "%s: not on tape\n", name);
                                continue;
                        }
-                       treescan(name, ino, listfile);
+                       if (hflag)
+                               treescan(name, ino, listfile);
+                       else
+                               listfile(name, ino, inodetype(ino));
                }
                done(0);
 
                }
                done(0);
 
index da80fae..797b0bd 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
-static char sccsid[] = "@(#)restore.c  3.4     (Berkeley)      83/02/28";
+static char sccsid[] = "@(#)restore.c  3.5     (Berkeley)      83/03/05";
 #endif
 
 #include "restore.h"
 #endif
 
 #include "restore.h"
@@ -87,7 +87,7 @@ addfile(name, ino, type)
 }
 
 /*
 }
 
 /*
- *     For each directory entry, determine which catagory it falls
+ *     For each directory entry, determine which category it falls
  *     into as follows:
  *     KEEP - entries that are to be left alone.
  *     NEW - new entries to be added.
  *     into as follows:
  *     KEEP - entries that are to be left alone.
  *     NEW - new entries to be added.
@@ -113,7 +113,7 @@ markfile(name, ino, type)
 
        /*
         * This routine is called once for each element in the 
 
        /*
         * This routine is called once for each element in the 
-        * directory heirarchy, with a full path name.
+        * directory hierarchy, with a full path name.
         * The "type" value is incorrectly specified as LEAF for
         * directories that are not on the dump tape.
         */
         * The "type" value is incorrectly specified as LEAF for
         * directories that are not on the dump tape.
         */
@@ -450,39 +450,68 @@ createfiles()
        vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
        getvol((long)1);
        vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
        getvol((long)1);
+       skipmaps();
+       skipdirs();
        first = lowerbnd(ROOTINO);
        last = upperbnd(maxino - 1);
        for (;;) {
        first = lowerbnd(ROOTINO);
        last = upperbnd(maxino - 1);
        for (;;) {
-               skipmaps();
-               skipdirs();
                first = lowerbnd(first);
                last = upperbnd(last);
                first = lowerbnd(first);
                last = upperbnd(last);
+               /*
+                * Check to see if any files remain to be extracted
+                */
                if (first > last)
                        return;
                if (first > last)
                        return;
+               /*
+                * Reject any volumes with inodes greater
+                * than the last one needed
+                */
                while (curfile.ino > last) {
                        curfile.action = SKIP;
                        getvol((long)0);
                while (curfile.ino > last) {
                        curfile.action = SKIP;
                        getvol((long)0);
-                       if (volno == 1) {
-                               skipmaps();
-                               skipdirs();
-                       }
+                       skipmaps();
+                       skipdirs();
                }
                }
+               /*
+                * Decide on the next inode needed.
+                * Skip across the inodes until it is found
+                * or an out of order volume change is encountered
+                */
                next = lowerbnd(curfile.ino);
                do      {
                        curvol = volno;
                        while (next > curfile.ino && volno == curvol)
                                skipfile();
                next = lowerbnd(curfile.ino);
                do      {
                        curvol = volno;
                        while (next > curfile.ino && volno == curvol)
                                skipfile();
+                       skipmaps();
+                       skipdirs();
                } while (volno == curvol + 1);
                } while (volno == curvol + 1);
+               /*
+                * If volume change out of order occurred the
+                * current state must be re calculated
+                */
                if (volno != curvol)
                        continue;
                if (volno != curvol)
                        continue;
+               /*
+                * If the current inode is greater than the one we were
+                * looking for then we missed the one we were looking for.
+                * Since we only attempt to extract files listed in the
+                * dump map, the file must have been lost due to a tape
+                * read error. Thus we report all requested files between
+                * the one we were looking for, and the one we found as
+                * missing, and delete their request flags.
+                */
                while (next < curfile.ino) {
                        ep = lookupino(next);
                        if (ep == NIL)
                                panic("corrupted symbol table\n");
                        fprintf(stderr, "%s: not found on tape\n", myname(ep));
                        ep->e_flags &= ~NEW;
                while (next < curfile.ino) {
                        ep = lookupino(next);
                        if (ep == NIL)
                                panic("corrupted symbol table\n");
                        fprintf(stderr, "%s: not found on tape\n", myname(ep));
                        ep->e_flags &= ~NEW;
-                       next = lowerbnd(next + 1);
+                       next = lowerbnd(next);
                }
                }
+               /*
+                * The current inode is the one that we are looking for,
+                * so extract it per its requested name.
+                */
                if (next == curfile.ino && next <= last) {
                        ep = lookupino(next);
                        if (ep == NIL)
                if (next == curfile.ino && next <= last) {
                        ep = lookupino(next);
                        if (ep == NIL)
index 396181d..85c8885 100644 (file)
@@ -1,7 +1,7 @@
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
 /* Copyright (c) 1983 Regents of the University of California */
 
 #ifndef lint
-static char sccsid[] = "@(#)tape.c     3.5     (Berkeley)      83/02/28";
+static char sccsid[] = "@(#)tape.c     3.6     (Berkeley)      83/03/05";
 #endif
 
 #include "restore.h"
 #endif
 
 #include "restore.h"
@@ -42,7 +42,7 @@ setinput(source)
        magtape = index(host, ':');
        if (magtape == 0) {
 nohost:
        magtape = index(host, ':');
        if (magtape == 0) {
 nohost:
-               msg("need keyletter ``f'' and device ``host:tape''");
+               msg("need keyletter ``f'' and device ``host:tape''\n");
                done(1);
        }
        *magtape++ = '\0';
                done(1);
        }
        *magtape++ = '\0';
@@ -98,10 +98,10 @@ setup()
 #endif
        }
        flsht();
 #endif
        }
        flsht();
-       if (readhdr(&spcl) == FAIL) {
+       if (gethead(&spcl) == FAIL) {
                bct--; /* push back this block */
                cvtflag++;
                bct--; /* push back this block */
                cvtflag++;
-               if (readhdr(&spcl) == FAIL) {
+               if (gethead(&spcl) == FAIL) {
                        fprintf(stderr, "Tape is not a dump tape\n");
                        done(1);
                }
                        fprintf(stderr, "Tape is not a dump tape\n");
                        done(1);
                }
@@ -196,7 +196,7 @@ again:
        else 
                newvol = 0;
        while (newvol <= 0) {
        else 
                newvol = 0;
        while (newvol <= 0) {
-               fprintf(stderr, "Specify volume #: ");
+               fprintf(stderr, "Specify next volume #: ");
                if (gets(tbf) == NULL)
                        continue;
                newvol = atoi(tbf);
                if (gets(tbf) == NULL)
                        continue;
                newvol = atoi(tbf);
@@ -208,7 +208,7 @@ again:
        if (newvol == volno)
                return;
        closemt();
        if (newvol == volno)
                return;
        closemt();
-       fprintf(stderr, "Mount tape volume %d then type return: ", newvol);
+       fprintf(stderr, "Mount tape volume %d then type return ", newvol);
        while (getchar() != '\n')
                ;
 #ifdef RRESTOR
        while (getchar() != '\n')
                ;
 #ifdef RRESTOR
@@ -238,14 +238,13 @@ gethdr:
                volno = 0;
                goto again;
        }
                volno = 0;
                goto again;
        }
+       blksread = savecnt;
        if (curfile.action == USING) {
                if (volno == 1)
                        panic("active file into volume 1\n");
        if (curfile.action == USING) {
                if (volno == 1)
                        panic("active file into volume 1\n");
-               blksread = savecnt;
                return;
        }
                return;
        }
-       if (readhdr(&spcl) == FAIL)
-               panic("no header after volume mark!\n");
+       (void) gethead(&spcl);
        findinode(&spcl, curfile.action == UNKNOWN ? 1 : 0);
        if (gettingfile) {
                gettingfile = 0;
        findinode(&spcl, curfile.action == UNKNOWN ? 1 : 0);
        if (gettingfile) {
                gettingfile = 0;
@@ -397,7 +396,7 @@ loop:
                if ((size -= TP_BSIZE) <= 0)
                        break;
        }
                if ((size -= TP_BSIZE) <= 0)
                        break;
        }
-       if (gethead(&spcl) == GOOD && size > 0) {
+       if (readhdr(&spcl) == GOOD && size > 0) {
                if (checktype(&spcl, TS_ADDR) == GOOD)
                        goto loop;
                fprintf(stderr, "Missing address (header) block for %s\n",
                if (checktype(&spcl, TS_ADDR) == GOOD)
                        goto loop;
                fprintf(stderr, "Missing address (header) block for %s\n",
@@ -603,8 +602,10 @@ readhdr(b)
        struct s_spcl *b;
 {
 
        struct s_spcl *b;
 {
 
-       if (gethead(b) == FAIL)
+       if (gethead(b) == FAIL) {
+               dprintf(stderr, "readhdr fails at %d blocks\n", blksread);
                return(FAIL);
                return(FAIL);
+       }
        return(GOOD);
 }
 
        return(GOOD);
 }
 
@@ -615,6 +616,7 @@ readhdr(b)
 gethead(buf)
        struct s_spcl *buf;
 {
 gethead(buf)
        struct s_spcl *buf;
 {
+       long i;
        union u_ospcl {
                char dummy[TP_BSIZE];
                struct  s_ospcl {
        union u_ospcl {
                char dummy[TP_BSIZE];
                struct  s_ospcl {
@@ -645,14 +647,9 @@ gethead(buf)
 
        if (!cvtflag) {
                readtape((char *)buf);
 
        if (!cvtflag) {
                readtape((char *)buf);
-               if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == FAIL) {
-                       dprintf(stderr, "gethead fails at %d blocks\n",
-                               blksread);
+               if (buf->c_magic != NFS_MAGIC || checksum((int *)buf) == FAIL)
                        return(FAIL);
                        return(FAIL);
-               }
-               if (dflag)
-                       accthdr(buf);
-               return(GOOD);
+               goto good;
        }
        readtape((char *)(&u_ospcl.s_ospcl));
        bzero((char *)buf, (long)TP_BSIZE);
        }
        readtape((char *)(&u_ospcl.s_ospcl));
        bzero((char *)buf, (long)TP_BSIZE);
@@ -676,11 +673,37 @@ gethead(buf)
        buf->c_count = u_ospcl.s_ospcl.c_count;
        bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256);
        if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
        buf->c_count = u_ospcl.s_ospcl.c_count;
        bcopy(u_ospcl.s_ospcl.c_addr, buf->c_addr, (long)256);
        if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
-           checksum((int *)(&u_ospcl.s_ospcl)) == FAIL) {
-               dprintf(stderr, "gethead fails at %d blocks\n", blksread);
+           checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
                return(FAIL);
                return(FAIL);
-       }
        buf->c_magic = NFS_MAGIC;
        buf->c_magic = NFS_MAGIC;
+
+good:
+       switch (buf->c_type) {
+
+       case TS_CLRI:
+       case TS_BITS:
+               /*
+                * Have to patch up missing information in bit map headers
+                */
+               buf->c_inumber = 0;
+               buf->c_dinode.di_size = buf->c_count * TP_BSIZE;
+               for (i = 0; i < buf->c_count; i++)
+                       buf->c_addr[i]++;
+               break;
+
+       case TS_TAPE:
+       case TS_END:
+               buf->c_inumber = 0;
+               break;
+
+       case TS_INODE:
+       case TS_ADDR:
+               break;
+
+       default:
+               panic("gethead: unknown inode type %d\n", buf->c_type);
+               break;
+       }
        if (dflag)
                accthdr(buf);
        return(GOOD);
        if (dflag)
                accthdr(buf);
        return(GOOD);
@@ -692,41 +715,41 @@ gethead(buf)
 accthdr(header)
        struct s_spcl *header;
 {
 accthdr(header)
        struct s_spcl *header;
 {
-       static ino_t previno = 0;
+       static ino_t previno = 0xffffffff;
        static int prevtype;
        static long predict;
        long blks, i;
 
        static int prevtype;
        static long predict;
        long blks, i;
 
-       if (previno == 0)
+       if (header->c_type == TS_TAPE) {
+               fprintf(stderr, "Volume header\n");
+               return;
+       }
+       if (previno == 0xffffffff)
                goto newcalc;
        switch (prevtype) {
                goto newcalc;
        switch (prevtype) {
-       case TS_TAPE:
-               fprintf(stderr, "Volume");
-               break;
        case TS_BITS:
        case TS_BITS:
-               fprintf(stderr, "Dump mask");
+               fprintf(stderr, "Dump mask header");
                break;
        case TS_CLRI:
                break;
        case TS_CLRI:
-               fprintf(stderr, "Remove mask");
+               fprintf(stderr, "Remove mask header");
                break;
        case TS_INODE:
                break;
        case TS_INODE:
-               fprintf(stderr, "File");
+               fprintf(stderr, "File header, ino %d", previno);
                break;
        case TS_ADDR:
                break;
        case TS_ADDR:
-               fprintf(stderr, "File continuation");
+               fprintf(stderr, "File continuation header, ino %d", previno);
                break;
        case TS_END:
                break;
        case TS_END:
-               fprintf(stderr, "End of tape");
+               fprintf(stderr, "End of tape header");
                break;
        }
                break;
        }
-       fprintf(stderr, " header, ino %d", previno);
        if (predict != blksread - 1)
                fprintf(stderr, "; predicted %d blocks, got %d blocks",
                        predict, blksread - 1);
        fprintf(stderr, "\n");
 newcalc:
        blks = 0;
        if (predict != blksread - 1)
                fprintf(stderr, "; predicted %d blocks, got %d blocks",
                        predict, blksread - 1);
        fprintf(stderr, "\n");
 newcalc:
        blks = 0;
-       if (header->c_type != TS_TAPE && header->c_type != TS_END)
+       if (header->c_type != TS_END)
                for (i = 0; i < header->c_count; i++)
                        if (header->c_addr[i] != 0)
                                blks++;
                for (i = 0; i < header->c_count; i++)
                        if (header->c_addr[i] != 0)
                                blks++;
@@ -745,7 +768,6 @@ findinode(header, complain)
        int complain;
 {
        static long skipcnt = 0;
        int complain;
 {
        static long skipcnt = 0;
-       long i;
 
        curfile.name = "<name unknown>";
        curfile.action = UNKNOWN;
 
        curfile.name = "<name unknown>";
        curfile.action = UNKNOWN;
@@ -768,16 +790,10 @@ findinode(header, complain)
                }
                if (checktype(header, TS_CLRI) == GOOD) {
                        curfile.name = "<file removal list>";
                }
                if (checktype(header, TS_CLRI) == GOOD) {
                        curfile.name = "<file removal list>";
-                       header->c_dinode.di_size = header->c_count * TP_BSIZE;
-                       for (i = 0; i < header->c_count; i++)
-                               header->c_addr[i]++;
                        break;
                }
                if (checktype(header, TS_BITS) == GOOD) {
                        curfile.name = "<file dump list>";
                        break;
                }
                if (checktype(header, TS_BITS) == GOOD) {
                        curfile.name = "<file dump list>";
-                       header->c_dinode.di_size = header->c_count * TP_BSIZE;
-                       for (i = 0; i < header->c_count; i++)
-                               header->c_addr[i]++;
                        break;
                }
                while (gethead(header) == FAIL)
                        break;
                }
                while (gethead(header) == FAIL)