X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=dump%2Ftape.c;h=3f2ae89a651bedf6f37189240cc2b5ff8352b09f;hb=86fab47e75fc141db053271654a2570fddcd0f46;hp=8cf9ce18b9aab89ed0a95c0db2edbfafe604e83e;hpb=43ef843b59f89bb96ebec8647aa23ad43ae6789c;p=dump.git diff --git a/dump/tape.c b/dump/tape.c index 8cf9ce1..3f2ae89 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -41,10 +41,11 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.35 2001/03/20 09:14:58 stelian Exp $"; + "$Id: tape.c,v 1.46 2001/05/12 11:36:12 stelian Exp $"; #endif /* not lint */ #include +#include #include #include #include @@ -68,6 +69,7 @@ int write(), read(); #include #include #include +#include #ifdef __linux__ #include #include @@ -158,6 +160,9 @@ static int ready; /* have we reached the lock point without having */ /* received the SIGUSR2 signal from the prev slave? */ static sigjmp_buf jmpbuf; /* where to jump to if we are ready when the */ /* SIGUSR2 arrives from the previous slave */ +#ifdef USE_QFA +static int gtperr = 0; +#endif int alloctape(void) @@ -253,7 +258,8 @@ tperror(int errnum) quit("Cannot recover\n"); /* NOTREACHED */ } - msg("write error %d blocks into volume %d: %s\n", blocksthisvol, tapeno, strerror(errnum)); + msg("write error %d blocks into volume %d: %s\n", + blocksthisvol, tapeno, strerror(errnum)); broadcast("DUMP WRITE ERROR!\n"); if (query("Do you want to rewrite this volume?")) { msg("Closing this volume. Prepare to restart with new media;\n"); @@ -297,13 +303,13 @@ do_stats(void) long txfrate = volkb / ttaken; msg("Volume %d took %d:%02d:%02d\n", tapeno, ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60); - msg("Volume %d transfer rate: %ld KB/s\n", tapeno, + msg("Volume %d transfer rate: %ld kB/s\n", tapeno, txfrate); xferrate += txfrate; if (compressed) { double rate = .0005 + (double) blocks / (double) volkb; - msg("Volume %d %ldKB uncompressed, %ldKB compressed," - " compression ratio %1.3f\n", + msg("Volume %d %ldkB uncompressed, %ldkB compressed," + " %1.3f:1\n", tapeno, blocks, volkb, rate); } } @@ -326,7 +332,7 @@ mktimeest(time_t tnow) / blockswritten * tapesize; if (tnow > tstart_volume) (void)snprintf(msgbuf, sizeof(msgbuf), - "%3.2f%% done at %ld KB/s, finished in %d:%02d\n", + "%3.2f%% done at %ld kB/s, finished in %d:%02d\n", (blockswritten * 100.0) / tapesize, (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume), (int)(deltat / 3600), (int)((deltat % 3600) / 60)); @@ -542,7 +548,7 @@ trewind(void) #endif { (void) close(tapefd); - while ((f = open(tape, 0)) < 0) + while ((f = OPEN(tape, 0)) < 0) sleep (10); (void) close(f); } @@ -856,10 +862,10 @@ restore_check_point: #ifdef RDUMP while ((tapefd = (host ? rmtopen(tape, 2) : pipeout ? fileno(stdout) : - open(tape, O_WRONLY|O_CREAT, 0666))) < 0) + OPEN(tape, O_WRONLY|O_CREAT, 0666))) < 0) #else while ((tapefd = (pipeout ? fileno(stdout) : - open(tape, O_WRONLY|O_CREAT, 0666))) < 0) + OPEN(tape, O_RDWR|O_CREAT, 0666))) < 0) #endif { msg("Cannot open output \"%s\".\n", tape); @@ -882,9 +888,10 @@ restore_check_point: spcl.c_volume++; spcl.c_type = TS_TAPE; spcl.c_flags |= DR_NEWHEADER; + spcl.c_ntrec = ntrec; if (compressed) spcl.c_flags |= DR_COMPRESSED; - writeheader((ino_t)slp->inode); + writeheader((dump_ino_t)slp->inode); spcl.c_flags &=~ DR_NEWHEADER; msg("Volume %d started with block %ld at: %s", tapeno, spcl.c_tapea, ctime(&tstart_volume)); @@ -989,6 +996,8 @@ enslave(void) doslave(cmd[0], i); Exit(X_FINOK); } + else + close(cmd[0]); } #ifdef LINUX_FORK_BUG @@ -1038,19 +1047,24 @@ doslave(int cmd, int slave_number) char *buffer; #ifdef HAVE_ZLIB struct tapebuf *comp_buf = NULL; - int compresult, complevel = 6, do_compress = 0; + int compresult, do_compress = slave_number > 0; unsigned long worklen; #endif /* HAVE_ZLIB */ struct slave_results returns; #ifdef __linux__ errcode_t retval; #endif +#ifdef USE_QFA + long curtapepos; + union u_spcl *uspclptr; + struct s_spcl *spclptr; +#endif /* USE_QFA */ /* * Need our own seek pointer. */ (void) close(diskfd); - if ((diskfd = open(disk, O_RDONLY)) < 0) + if ((diskfd = OPEN(disk, O_RDONLY)) < 0) quit("slave couldn't reopen disk: %s\n", strerror(errno)); #ifdef __linux__ ext2fs_close(fs); @@ -1095,13 +1109,6 @@ doslave(int cmd, int slave_number) quit("master/slave protocol botched.\n"); } } - if (sigsetjmp(jmpbuf, 1) == 0) { - ready = 1; - if (!caught) - (void) pause(); - } - ready = 0; - caught = 0; /* Try to write the data... */ wrote = 0; @@ -1113,23 +1120,24 @@ doslave(int cmd, int slave_number) #ifdef HAVE_ZLIB /* - * The first NR_SLAVE blocks are not compressed. - * When writing a compressed dump, each block is - * written from struct tapebuf with an 4 byte prefix + * When writing a compressed dump, each block except + * the first one on each tape is written + * from struct tapebuf with an 4 byte prefix * followed by the data. This can be less than * writesize. Restore, on a short read, can compare the * length read to the compressed length in the header * to verify that the read was good. Blocks which don't * compress well are written uncompressed. + * The first block written by each slave is not compressed + * and does not have a prefix. */ - if (compressed) { + if (compressed && do_compress) { comp_buf->length = bufsize; worklen = TP_BSIZE + writesize; - if (do_compress) - compresult = compress2(comp_buf->buf, &worklen, - (char *)slp->tblock[0], writesize, complevel); - if (compresult == Z_OK && worklen <= writesize-32) { + compresult = compress2(comp_buf->buf, &worklen, + (char *)slp->tblock[0], writesize, compressed); + if (compresult == Z_OK && worklen <= (writesize - 16)) { /* write the compressed buffer */ comp_buf->length = worklen; comp_buf->compressed = 1; @@ -1146,10 +1154,41 @@ doslave(int cmd, int slave_number) memcpy(comp_buf->buf, (char *)slp->tblock[0], writesize); } } - /* compress the remaining blocks */ + /* compress the remaining blocks if we're compressing */ do_compress = compressed; #endif /* HAVE_ZLIB */ + if (sigsetjmp(jmpbuf, 1) == 0) { + ready = 1; + if (!caught) + (void) pause(); + } + ready = 0; + caught = 0; + +#ifdef USE_QFA + if (gTapeposfd >= 0) { + uspclptr = (union u_spcl *)&slp->tblock[0]; + spclptr = &uspclptr->s_spcl; + if ((spclptr->c_magic == NFS_MAGIC) && + (spclptr->c_type == TS_INODE)) { + /* if an error occured previously don't + * try again */ + if (gtperr == 0) { + if ((gtperr = GetTapePos(&curtapepos)) == 0) { +#ifdef DEBUG_QFA + msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos); +#endif + sprintf(gTps, "%ld\t%d\t%ld\n", (unsigned long)spclptr->c_inumber, tapeno, curtapepos); + if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps)) { + warn("error writing tapepos file.\n"); + } + } + } + } + } +#endif /* USE_QFA */ + while (eot_count < 10 && size < bufsize) { #ifdef RDUMP if (host) @@ -1238,3 +1277,24 @@ atomic_write(int fd, const void *buf, size_t count) } while (got == -1 && errno == EINTR); return (got < 0 ? got : count - need); } + + +#ifdef USE_QFA +/* + * read the current tape position + */ +int +GetTapePos(long *pos) +{ + int err = 0; + + *pos = 0; + if (ioctl(tapefd, MTIOCPOS, pos) == -1) { + err = errno; + msg("[%ld] error: %d (getting tapepos: %ld)\n", getpid(), + err, *pos); + return err; + } + return err; +} +#endif /* USE_QFA */