X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftape.c;h=9d57ddf9099d7d2b31ecb2dea9b08ac71a5205fb;hp=ce150568df6af077126891da2cfb5ca118be253b;hb=b45f51d61e911ac8a040bef1efda6afd82261e03;hpb=1227625a12a66e0ded78a1997c2d23f23202a382 diff --git a/dump/tape.c b/dump/tape.c index ce15056..9d57ddf 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,9 +40,17 @@ */ #ifndef lint +#if 0 static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95"; +#endif +static const char rcsid[] = + "$Id: tape.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; #endif /* not lint */ +#ifdef __linux__ +#include +#include +#endif #include #include #include @@ -80,7 +89,6 @@ int write(), read(); #include #endif #include "dump.h" -#include "pathnames.h" int writesize; /* size of malloc()ed buffer for tape */ long lastspclrec = -1; /* tape block number of last written header */ @@ -92,7 +100,7 @@ extern int cartridge; extern char *host; char *nexttape; -static int atomic __P((int (*)(), int, char *, int)); +static int atomic __P((ssize_t (*)(), int, char *, int)); static void doslave __P((int, int)); static void enslave __P((void)); static void flushtape __P((void)); @@ -153,7 +161,7 @@ alloctape() * repositioning after stopping, i.e, streaming mode, where the gap is * variable, 0.30" to 0.45". The gap is maximal when the tape stops. */ - if (blocksperfile == 0) + if (blocksperfile == 0 && !unlimited) tenths = writesize / density + (cartridge ? 16 : density == 625 ? 5 : 8); /* @@ -321,7 +329,7 @@ flushtape() asize += tenths; blockswritten += ntrec; blocksthisvol += ntrec; - if (!pipeout && (blocksperfile ? + if (!pipeout && !unlimited && (blocksperfile ? (blocksthisvol >= blocksperfile) : (asize > tsize))) { close_rewind(); startnewtape(0); @@ -337,12 +345,12 @@ trewind() for (f = 0; f < SLAVES; f++) { /* - * Drain the results, but unlike EOT we DO (or should) care - * what the return values were, since if we detect EOT after - * we think we've written the last blocks to the tape anyway, + * Drain the results, but unlike EOT we DO (or should) care + * what the return values were, since if we detect EOT after + * we think we've written the last blocks to the tape anyway, * we have to replay those blocks with rollforward. * - * fixme: punt for now. + * fixme: punt for now. */ if (slaves[f].sent) { if (atomic(read, slaves[f].fd, (char *)&got, sizeof got) @@ -385,9 +393,16 @@ trewind() void close_rewind() { + time_t tstart_changevol, tend_changevol; + trewind(); if (nexttape) return; +#ifdef __linux__ + (void)time4(&(tstart_changevol)); +#else + (void)time((time_t *)&(tstart_changevol)); +#endif if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); broadcast("CHANGE DUMP VOLUMES!\7\7\n"); @@ -397,6 +412,13 @@ close_rewind() dumpabort(0); /*NOTREACHED*/ } +#ifdef __linux__ + (void)time4(&(tend_changevol)); +#else + (void)time((time_t *)&(tend_changevol)); +#endif + if ((tstart_changevol != (time_t)-1) && (tend_changevol != (time_t)-1)) + tstart_writing += (tend_changevol - tstart_changevol); } void @@ -406,13 +428,17 @@ rollforward() register struct slave *tslp; int i, size, savedtapea, got; union u_spcl *ntb, *otb; +#ifdef __linux__ + int blks; + long lastfirstrec; +#endif tslp = &slaves[SLAVES]; ntb = (union u_spcl *)tslp->tblock[1]; /* - * Each of the N slaves should have requests that need to - * be replayed on the next tape. Use the extra slave buffers - * (slaves[SLAVES]) to construct request lists to be sent to + * Each of the N slaves should have requests that need to + * be replayed on the next tape. Use the extra slave buffers + * (slaves[SLAVES]) to construct request lists to be sent to * each slave in turn. */ for (i = 0; i < SLAVES; i++) { @@ -420,7 +446,7 @@ rollforward() otb = (union u_spcl *)slp->tblock; /* - * For each request in the current slave, copy it to tslp. + * For each request in the current slave, copy it to tslp. */ prev = NULL; @@ -457,6 +483,9 @@ rollforward() dumpabort(0); } slp->sent = 1; +#ifdef __linux__ + lastfirstrec = slp->firstrec; +#endif if (++slp >= &slaves[SLAVES]) slp = &slaves[0]; @@ -464,8 +493,8 @@ rollforward() if (prev->dblk != 0) { /* - * If the last one was a disk block, make the - * first of this one be the last bit of that disk + * If the last one was a disk block, make the + * first of this one be the last bit of that disk * block... */ q->dblk = prev->dblk + @@ -473,7 +502,7 @@ rollforward() ntb = (union u_spcl *)tslp->tblock; } else { /* - * It wasn't a disk block. Copy the data to its + * It wasn't a disk block. Copy the data to its * new location in the buffer. */ q->dblk = 0; @@ -484,7 +513,11 @@ rollforward() slp->req[0] = *q; nextblock = slp->tblock; if (q->dblk == 0) +#ifdef __linux__ + *(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)tslp->tblock; +#else nextblock++; +#endif trecno = 1; /* @@ -503,6 +536,22 @@ rollforward() quit("EOT detected at start of the tape!\n"); } } + +#ifdef __linux__ + blks = 0; + if (spcl.c_type != TS_END) { + for (i = 0; i < spcl.c_count; i++) + if (spcl.c_addr[i] != 0) + blks++; + } + + slp->firstrec = lastfirstrec + ntrec; + slp->count = lastspclrec + blks + 1 - spcl.c_tapea; + slp->inode = curino; + asize += tenths; + blockswritten += ntrec; + blocksthisvol += ntrec; +#endif } /* @@ -571,7 +620,7 @@ restore_check_point: case X_FINOK: msg("Child %d finishes X_FINOK\n", childpid); break; - case X_ABORT: + case X_ABORT: msg("Child %d finishes X_ABORT\n", childpid); break; case X_REWRITE: @@ -621,7 +670,7 @@ restore_check_point: while ((tapefd = (host ? rmtopen(tape, 2) : pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0) #else - while ((tapefd = (pipeout ? 1 : + while ((tapefd = (pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0) #endif { @@ -636,7 +685,7 @@ restore_check_point: blocksthisvol = 0; if (top) newtape++; /* new tape signal */ - spcl.c_count = slp->count; + spcl.c_count = slp->count; /* * measure firstrec in TP_BSIZE units since restore doesn't * know the correct ntrec value... @@ -671,7 +720,7 @@ dumpabort(signo) Exit(X_ABORT); } -__dead void +void Exit(status) int status; { @@ -751,7 +800,6 @@ enslave() quit("master/slave protocol botched 4\n"); #endif - /* write pid of next slave to each slave */ for (i = 0; i < SLAVES; i++) (void) atomic(write, slaves[i].fd, (char *) &slaves[(i + 1) % SLAVES].pid, @@ -766,8 +814,10 @@ killall() register int i; for (i = 0; i < SLAVES; i++) - if (slaves[i].pid > 0) + if (slaves[i].pid > 0) { (void) kill(slaves[i].pid, SIGKILL); + slaves[i].sent = 0; + } } /* @@ -788,9 +838,6 @@ doslave(cmd, slave_number) errcode_t retval; #endif -#ifdef TDEBUG - msg("slave %d, pid %d\n", slave_number, getpid()); -#endif /* * Need our own seek pointer. */ @@ -825,7 +872,7 @@ doslave(cmd, slave_number) p->count * TP_BSIZE); } else { if (p->count != 1 || atomic(read, cmd, - (char *)slp->tblock[trecno], + (char *)slp->tblock[trecno], TP_BSIZE) != TP_BSIZE) quit("master/slave protocol botched.\n"); } @@ -839,6 +886,7 @@ doslave(cmd, slave_number) caught = 0; /* Try to write the data... */ + wrote = 0; eot_count = 0; size = 0; @@ -852,9 +900,9 @@ doslave(cmd, slave_number) wrote = write(tapefd, slp->tblock[0]+size, writesize-size); #ifdef WRITEDEBUG - msg("slave %d wrote %d\n", slave_number, wrote); + printf("slave %d wrote %d\n", slave_number, wrote); #endif - if (wrote < 0) + if (wrote < 0) break; if (wrote == 0) eot_count++; @@ -862,19 +910,23 @@ doslave(cmd, slave_number) } #ifdef WRITEDEBUG - if (size != writesize) - msg("slave %d only wrote %d out of %d bytes and gave up.\n", + if (size != writesize) + printf("slave %d only wrote %d out of %d bytes and gave up.\n", slave_number, size, writesize); #endif + /* + * Handle ENOSPC as an EOT condition. + */ + if (wrote < 0 && errno == ENOSPC) { + wrote = 0; + eot_count++; + } + if (eot_count > 0) size = 0; - /* - * fixme: Pyramids running OSx return ENOSPC - * at EOT on 1/2 inch drives. - */ - if (size < 0) { + if (wrote < 0) { (void) kill(master, SIGUSR1); for (;;) (void) sigpause(0); @@ -884,7 +936,7 @@ doslave(cmd, slave_number) * (for EOT handling) */ (void) atomic(write, cmd, (char *)&size, sizeof size); - } + } /* * If partial write, don't want next slave to go. @@ -903,7 +955,8 @@ doslave(cmd, slave_number) */ static int atomic(func, fd, buf, count) - int (*func)(), fd; + ssize_t (*func)(); + int fd; char *buf; int count; {