X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=restore%2Frestore.c;h=67a8465904dd26f81a911f249cd7cc8e0c80b77a;hp=3cc2badf9654143be991a5102c5f8ad599960ba6;hb=df3d2ef98b911ebb7a7b7c6137e60e28eb39e5f1;hpb=103122b3455278bdf377ce24821168be90238fda diff --git a/restore/restore.c b/restore/restore.c index 3cc2bad..67a8465 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -18,11 +18,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -41,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: restore.c,v 1.24 2002/01/22 11:12:28 stelian Exp $"; + "$Id: restore.c,v 1.37 2005/07/07 09:16:08 stelian Exp $"; #endif /* not lint */ #include @@ -58,11 +54,20 @@ static const char rcsid[] = #endif #include #else /* __linux__ */ +#ifdef sunos +#include +#include +#else #include +#endif #endif /* __linux__ */ +#include + +#include #include #include +#include #ifdef __linux__ #include @@ -83,7 +88,7 @@ listfile(char *name, dump_ino_t ino, int type) long descend = hflag ? GOOD : FAIL; #ifdef USE_QFA long tnum; - long tpos; + long long tpos; #endif if (TSTINO(ino, dumpmap) == 0) @@ -92,7 +97,7 @@ listfile(char *name, dump_ino_t ino, int type) #ifdef USE_QFA if (tapeposflag) { /* add QFA positions to output */ (void)Inode2Tapepos(ino, &tnum, &tpos, 1); - fprintf(stdout, "%10lu\t%ld\t%ld\t%s\n", (unsigned long)ino, + fprintf(stdout, "%10lu\t%ld\t%lld\t%s\n", (unsigned long)ino, tnum, tpos, name); } else @@ -108,7 +113,7 @@ listfile(char *name, dump_ino_t ino, int type) long addfile(char *name, dump_ino_t ino, int type) { - register struct entry *ep, *np; + struct entry *ep, *np; long descend = hflag ? GOOD : FAIL; char buf[100]; @@ -140,7 +145,11 @@ addfile(char *name, dump_ino_t ino, int type) } } ep = addentry(name, ino, type); +#ifdef USE_QFA + if ((type == NODE) && (!createtapeposflag)) +#else if (type == NODE) +#endif newnode(ep); ep->e_flags |= NEW; return (descend); @@ -152,7 +161,7 @@ addfile(char *name, dump_ino_t ino, int type) */ /* ARGSUSED */ long -deletefile(char *name, dump_ino_t ino, int type) +deletefile(char *name, dump_ino_t ino, UNUSED(int type)) { long descend = hflag ? GOOD : FAIL; struct entry *ep; @@ -192,8 +201,8 @@ static struct entry *removelist; void removeoldleaves(void) { - register struct entry *ep, *nextep; - register dump_ino_t i, mydirino; + struct entry *ep, *nextep; + dump_ino_t i, mydirino; Vprintf(stdout, "Mark entries to be removed.\n"); if ((ep = lookupino(WINO))) { @@ -210,8 +219,11 @@ removeoldleaves(void) continue; #ifdef __linux__ (void)fprintf(stderr, "BUG! Should call delwhiteout\n"); +#else +#ifdef sunos #else delwhiteout(ep); +#endif #endif freeentry(ep); } @@ -249,7 +261,7 @@ removeoldleaves(void) long nodeupdates(char *name, dump_ino_t ino, int type) { - register struct entry *ep, *np, *ip; + struct entry *ep, *np, *ip; long descend = GOOD; int lookuptype = 0; int key = 0; @@ -558,21 +570,26 @@ keyval(int key) void findunreflinks(void) { - register struct entry *ep, *np; - register dump_ino_t i; + struct entry *ep, *np; + dump_ino_t i; + int j; Vprintf(stdout, "Find unreferenced names.\n"); for (i = ROOTINO; i < maxino; i++) { ep = lookupino(i); if (ep == NULL || ep->e_type == LEAF || TSTINO(i, dumpmap) == 0) continue; - for (np = ep->e_entries; np != NULL; np = np->e_sibling) { - if (np->e_flags == 0) { - Dprintf(stdout, - "%s: remove unreferenced name\n", - myname(np)); - removeleaf(np); - freeentry(np); + if (ep->e_entries == NULL) + continue; + for (j = 0; j < dirhash_size; j++) { + for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { + if (np->e_flags == 0) { + Dprintf(stdout, + "%s: remove unreferenced name\n", + myname(np)); + removeleaf(np); + freeentry(np); + } } } } @@ -580,15 +597,19 @@ findunreflinks(void) * Any leaves remaining in removed directories is unreferenced. */ for (ep = removelist; ep != NULL; ep = ep->e_next) { - for (np = ep->e_entries; np != NULL; np = np->e_sibling) { - if (np->e_type == LEAF) { - if (np->e_flags != 0) - badentry(np, "unreferenced with flags"); - Dprintf(stdout, - "%s: remove unreferenced name\n", - myname(np)); - removeleaf(np); - freeentry(np); + if (ep->e_entries == NULL) + continue; + for (j = 0; j < dirhash_size; j++) { + for (np = ep->e_entries[j]; np != NULL; np = np->e_sibling) { + if (np->e_type == LEAF) { + if (np->e_flags != 0) + badentry(np, "unreferenced with flags"); + Dprintf(stdout, + "%s: remove unreferenced name\n", + myname(np)); + removeleaf(np); + freeentry(np); + } } } } @@ -606,7 +627,7 @@ findunreflinks(void) void removeoldnodes(void) { - register struct entry *ep, **prev; + struct entry *ep, **prev; long change; Vprintf(stdout, "Remove old nodes (directories).\n"); @@ -614,10 +635,19 @@ removeoldnodes(void) change = 0; prev = &removelist; for (ep = removelist; ep != NULL; ep = *prev) { + int docont = 0; if (ep->e_entries != NULL) { - prev = &ep->e_next; - continue; + int i; + for (i = 0; i < dirhash_size; i++) { + if (ep->e_entries[i] != NULL) { + prev = &ep->e_next; + docont = 1; + break; + } + } } + if (docont) + continue; *prev = ep->e_next; removenode(ep); freeentry(ep); @@ -639,7 +669,10 @@ compare_entry(struct entry *ep, int do_compare) badentry(ep, "unexpected file on tape"); do_compare_error; } - if (do_compare) (void) comparefile(myname(ep)); + if (do_compare) { + (void) comparefile(myname(ep)); + skipxattr(); + } ep->e_flags &= ~(NEW|EXTRACT); } @@ -649,7 +682,7 @@ compare_entry(struct entry *ep, int do_compare) void compareleaves(void) { - register struct entry *ep; + struct entry *ep; dump_ino_t first; long curvol; @@ -736,9 +769,10 @@ compareleaves(void) void createleaves(char *symtabfile) { - register struct entry *ep; + struct entry *ep; dump_ino_t first; long curvol; + int doremove; if (command == 'R') { Vprintf(stdout, "Continue extraction of new leaves\n"); @@ -789,18 +823,20 @@ createleaves(char *symtabfile) * be removed since its type may change from one leaf type * to another (e.g. "file" to "character special"). */ - if ((ep->e_flags & EXTRACT) != 0) { - removeleaf(ep); - ep->e_flags &= ~REMOVED; - } - (void) extractfile(myname(ep)); + if ((ep->e_flags & EXTRACT) != 0) + doremove = 1; + else + doremove = 0; + (void) extractfile(ep, doremove); + skipxattr(); ep->e_flags &= ~(NEW|EXTRACT); + /* * We checkpoint the restore after every tape reel, so * as to simplify the amount of work required by the * 'R' command. */ - next: +next: if (curvol != volno) { dumpsymtable(symtabfile, volno); skipmaps(); @@ -835,20 +871,27 @@ createleaves(char *symtabfile) void createfiles(void) { - register dump_ino_t first, next, last; - register struct entry *ep; + dump_ino_t first, next, last; + struct entry *ep; long curvol; #ifdef USE_QFA - long tnum, tpos, curtpos, tmpcnt; + long tnum, tmpcnt; + long long tpos, curtpos = 0; time_t tistart, tiend, titaken; + int volChg; #endif Vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; #ifdef USE_QFA - if (!tapeposflag) + if (tapeposflag) + curfile.ino = 0; + else #endif - getvol((long)1); + if (volinfo[1] == ROOTINO) + curfile.ino = 0; + else + getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(ROOTINO); @@ -897,38 +940,56 @@ createfiles(void) #ifdef USE_QFA tistart = time(NULL); if (tapeposflag) { - /* get tape position for inode (position directly) */ - (void)Inode2Tapepos(next, &tnum, &tpos, 1); - if (tpos == 0) - /* get tape position for last available inode - * (position before) */ - (void)Inode2Tapepos(next, &tnum, &tpos, 0); + /* get tape position for inode */ + (void)Inode2Tapepos(next, &tnum, &tpos, 0); if (tpos != 0) { - if (tnum != volno) + if (tnum != volno) { (void)RequestVol(tnum); + volChg = 1; + } else { + volChg = 0; + } if (GetTapePos(&curtpos) == 0) { /* curtpos +1000 ???, some drives * might be too slow */ - if (tpos > curtpos) { + if (((tpos > (curtpos + 1000)) && (volChg == 0)) || ((tpos != curtpos) && (volChg == 1))) { + volChg = 0; #ifdef DEBUG_QFA - msg("positioning tape %ld from %ld to %ld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next); + msg("positioning tape %ld from %lld to %lld for inode %lu ...\n", volno, curtpos, tpos, (unsigned long)next); #endif if (GotoTapePos(tpos) == 0) { #ifdef DEBUG_QFA - if (GetTapePos(&curtpos) == 0) - msg("before resnyc at tape position %ld\n", curtpos); + if (GetTapePos(&curtpos) == 0) { + msg("before resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name); + } #endif - (void)ReReadFromTape(); + ReReadInodeFromTape(next); #ifdef DEBUG_QFA - if (GetTapePos(&curtpos) == 0) - msg("after resync at tape position %ld\n", curtpos); + if (GetTapePos(&curtpos) == 0) { + msg("after resnyc at tape position %lld (%ld, %ld, %s)\n", curtpos, next, curfile.ino, curfile.name); + } #endif } + } else { +#ifdef DEBUG_QFA + msg("already at tape %ld position %ld for inode %lu ...\n", volno, tpos, (unsigned long)next); +#endif } } } } + else #endif /* USA_QFA */ + if (volinfo[1] == ROOTINO) { + int i, goodvol = 1; + + for (i = 1; i < (int)TP_NINOS && volinfo[i] != 0; ++i) + if (volinfo[i] < next) + goodvol = i; + + if (goodvol != volno) + RequestVol(goodvol); + } do { curvol = volno; @@ -972,8 +1033,11 @@ createfiles(void) ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); - fprintf(stderr, "%s: (inode %lu) not found on tape\n", - myname(ep), (unsigned long)next); +#ifdef USE_QFA + if (!createtapeposflag) +#endif + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + myname(ep), (unsigned long)next); ep->e_flags &= ~NEW; next = lowerbnd(next); } @@ -985,7 +1049,23 @@ createfiles(void) ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); - (void) extractfile(myname(ep)); +#ifdef USE_QFA + if (createtapeposflag) { +#ifdef DEBUG_QFA + msg("inode %ld at tapepos %ld\n", curfile.ino, curtapepos); +#endif + sprintf(gTps, "%ld\t%ld\t%lld\n", (unsigned long)curfile.ino, volno, curtapepos); + if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) + warn("error writing tapepos file.\n"); + skipfile(); + } else { +#endif /* USE_QFA */ + (void) extractfile(ep, 0); + skipxattr(); + +#ifdef USE_QFA + } +#endif /* USE_QFA */ ep->e_flags &= ~NEW; if (volno != curvol) skipmaps(); @@ -999,8 +1079,8 @@ createfiles(void) void createlinks(void) { - register struct entry *np, *ep; - register dump_ino_t i; + struct entry *np, *ep; + dump_ino_t i; char name[BUFSIZ]; if ((ep = lookupino(WINO))) { @@ -1010,8 +1090,11 @@ createlinks(void) continue; #ifdef __linux__ (void)fprintf(stderr, "BUG! Should call addwhiteout\n"); +#else +#ifdef sunos #else (void) addwhiteout(myname(ep)); +#endif #endif ep->e_flags &= ~NEW; } @@ -1043,8 +1126,8 @@ createlinks(void) void checkrestore(void) { - register struct entry *ep; - register dump_ino_t i; + struct entry *ep; + dump_ino_t i; Vprintf(stdout, "Check the symbol table.\n"); for (i = WINO; i < maxino; i++) {