X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftape.c;h=6f829f88802083d8992b5ffd50462489c9298909;hp=d80e49a842464af0432b4c28670bc0243a793c5d;hb=241ddca30657af0cb9dbc60685712d7a4989ee49;hpb=61e9d4ff6082c1c460bac40ff15c62839278dd48 diff --git a/dump/tape.c b/dump/tape.c index d80e49a..6f829f8 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -37,7 +37,7 @@ #ifndef lint static const char rcsid[] = - "$Id: tape.c,v 1.76 2003/04/09 10:42:57 stelian Exp $"; + "$Id: tape.c,v 1.87 2004/11/22 10:32:32 stelian Exp $"; #endif /* not lint */ #include @@ -60,6 +60,11 @@ int write(), read(); #ifdef __linux__ #include #include +#include +#include /* for definition of BLKFLSBUF */ +#ifndef BLKFLSBUF /* last resort... */ +#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */ +#endif #include #endif #include @@ -104,17 +109,19 @@ int write(), read(); int writesize; /* size of malloc()ed buffer for tape */ long lastspclrec = -1; /* tape block number of last written header */ int trecno = 0; /* next record to write in current block */ -extern long blocksperfile; /* number of blocks per output file */ +extern long *blocksperfiles; /* number of blocks per output file(s) */ +long blocksperfiles_current; /* current position in blocksperfiles */ long blocksthisvol; /* number of blocks on current output file */ extern int ntrec; /* blocking factor on tape */ extern int cartridge; char *nexttape; extern pid_t rshpid; +int eot_code = 1; long long tapea_bytes = 0; /* bytes_written at start of current volume */ static int magtapeout; /* output is really a tape */ -static ssize_t dump_atomic_read __P((int, void *, size_t)); -static ssize_t dump_atomic_write __P((int, const void *, size_t)); +static ssize_t dump_atomic_read __P((int, char *, size_t)); +static ssize_t dump_atomic_write __P((int, const char *, size_t)); #ifdef WRITEDEBUG static void doslave __P((int, int, int)); #else @@ -126,7 +133,8 @@ static void killall __P((void)); static void rollforward __P((void)); #ifdef USE_QFA static int GetTapePos __P((long long *)); -static void MkTapeString __P((struct s_spcl *, long long)); +static int MkTapeString __P((struct s_spcl *, long long)); +#define FILESQFAPOS 20 #endif /* @@ -138,7 +146,7 @@ static void MkTapeString __P((struct s_spcl *, long long)); * The following structure defines the instruction packets sent to slaves. */ struct req { - daddr_t dblk; + ext2_loff_t dblk; int count; }; int reqsiz; @@ -194,7 +202,7 @@ alloctape(void) * 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 && !unlimited) + if (!blocksperfiles && !unlimited) tenths = (cartridge ? 16 : density == 625 ? 5 : 8); else { tenths = 0; @@ -230,7 +238,7 @@ void writerec(const void *dp, int isspcl) { - slp->req[trecno].dblk = (daddr_t)0; + slp->req[trecno].dblk = (ext2_loff_t)0; slp->req[trecno].count = 1; /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */ *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp; @@ -268,9 +276,10 @@ writerec(const void *dp, int isspcl) } void -dumpblock(daddr_t blkno, int size) +dumpblock(blk_t blkno, int size) { - int avail, tpblks, dblkno; + int avail, tpblks; + ext2_loff_t dblkno; dblkno = fsbtodb(sblock, blkno); tpblks = size >> tp_bshift; @@ -466,10 +475,14 @@ flushtape(void) } blks = 0; - if (spcl.c_type != TS_END) { - for (i = 0; i < spcl.c_count; i++) - if (spcl.c_addr[i] != 0) - blks++; + if (spcl.c_type == TS_CLRI || spcl.c_type == TS_BITS) + blks = spcl.c_count; + else { + if (spcl.c_type != TS_END) { + for (i = 0; i < spcl.c_count; i++) + if (spcl.c_addr[i] != 0) + blks++; + } } slp->count = lastspclrec + blks + 1 - spcl.c_tapea; slp->tapea = spcl.c_tapea; @@ -481,9 +494,9 @@ flushtape(void) blockswritten += ntrec; blocksthisvol += ntrec; if (!pipeout && !unlimited) { - if (blocksperfile) { - if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfile) * 1024) - : blocksthisvol >= blocksperfile ) { + if (blocksperfiles && blocksperfiles[blocksperfiles_current]) { + if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfiles[blocksperfiles_current]) * 1024) + : blocksthisvol >= blocksperfiles[blocksperfiles_current] ) { close_rewind(); startnewtape(0); } @@ -569,8 +582,6 @@ close_rewind(void) { int eot_code = 1; (void)trewind(); - if (nexttape || Mflag) - return; if (eot_script) { msg("Launching %s\n", eot_script); eot_code = system_command(eot_script, tape, tapeno); @@ -581,6 +592,8 @@ close_rewind(void) } if (eot_code == 0) return; + if (nexttape || Mflag) + return; if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); broadcast("CHANGE DUMP VOLUMES!\7\7\n"); @@ -868,6 +881,8 @@ restore_check_point: tape[MAXPATHLEN - 1] = '\0'; msg("Dumping volume %d on %s\n", tapeno, tape); } + if (blocksperfiles && blocksperfiles_current < *blocksperfiles) + blocksperfiles_current++; #ifdef RDUMP while ((tapefd = (host ? rmtopen(tape, O_WRONLY|O_CREAT|O_TRUNC) : pipeout ? fileno(stdout) : @@ -1081,9 +1096,6 @@ doslave(int cmd, int compresult; volatile int do_compress = !first; unsigned long worklen; -#ifdef HAVE_BZLIB - unsigned int worklen2; -#endif #ifdef HAVE_LZO lzo_align_t __LZO_MMODEL *LZO_WorkMem; #endif @@ -1096,6 +1108,9 @@ doslave(int cmd, long long curtapepos; union u_spcl *uspclptr; struct s_spcl *spclptr; + /* long maxntrecs = 300000000 / (ntrec * 1024); last tested: 50 000 000 */ + long maxntrecs = 50000; /* every 50MB */ + long cntntrecs = maxntrecs; #endif /* USE_QFA */ sigset_t set; @@ -1112,7 +1127,7 @@ doslave(int cmd, quit("slave couldn't reopen disk: %s\n", strerror(errno)); #ifdef __linux__ #ifdef BLKFLSBUF - (void)ioctl(diskfd, BLKFLSBUF); + (void)ioctl(diskfd, BLKFLSBUF, 0); #endif ext2fs_close(fs); retval = dump_fs_open(disk, &fs); @@ -1133,10 +1148,10 @@ doslave(int cmd, if (compressed) { int bsiz = sizeof(struct tapebuf) + writesize; /* Add extra space to deal with compression enlarging the buffer */ - if (TP_BSIZE > writesize/64 + 19) + if (TP_BSIZE > writesize/16 + 67) bsiz += TP_BSIZE; else - bsiz += writesize/64 + 19; + bsiz += writesize/16 + 67; comp_buf = malloc(bsiz); if (comp_buf == NULL) quit("couldn't allocate a compress buffer.\n"); @@ -1217,7 +1232,7 @@ doslave(int cmd, #endif /* HAVE_ZLIB */ #ifdef HAVE_BZLIB if (zipflag == COMPRESS_BZLIB) { - worklen2 = worklen; + unsigned int worklen2 = worklen; compresult = BZ2_bzBuffToBuffCompress( comp_buf->buf, &worklen2, @@ -1235,10 +1250,12 @@ doslave(int cmd, #endif /* HAVE_BZLIB */ #ifdef HAVE_LZO if (zipflag == COMPRESS_LZO) { + lzo_uint worklen2 = worklen; compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize, comp_buf->buf, - (lzo_uintp)&worklen, + &worklen2, LZO_WorkMem); + worklen = worklen2; if (compresult == LZO_E_OK) compresult = 1; else @@ -1277,23 +1294,30 @@ doslave(int cmd, #ifdef USE_QFA if (gTapeposfd >= 0) { int i; - int firstpass = 1; - for (i = 0; i < ntrec; ++i) { + int foundone = 0; + + for (i = 0; (i < ntrec) && !foundone; ++i) { uspclptr = (union u_spcl *)&slp->tblock[i]; spclptr = &uspclptr->s_spcl; if ((spclptr->c_magic == NFS_MAGIC) && - (spclptr->c_type == TS_INODE) && - ((spclptr->c_dinode.di_mode & S_IFMT) != IFDIR) && - (spclptr->c_date == gThisDumpDate)) { - /* if an error occured previously don't - * try again */ - if (firstpass) { - firstpass = 0; + (spclptr->c_type == TS_INODE) && + (spclptr->c_date == gThisDumpDate) && + !(spclptr->c_dinode.di_mode & S_IFDIR) + ) { + foundone = 1; + /* if (cntntrecs >= maxntrecs) { only write every maxntrecs amount of data */ + cntntrecs = 0; if (gtperr == 0) gtperr = GetTapePos(&curtapepos); - } - if (gtperr == 0) - MkTapeString(spclptr, curtapepos); + /* if an error occured previously don't + * try again */ + if (gtperr == 0) { +#ifdef DEBUG_QFA + msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos); +#endif + gtperr = MkTapeString(spclptr, curtapepos); + } + /* } */ } } } @@ -1350,6 +1374,11 @@ doslave(int cmd, * Signal the next slave to go. */ (void) kill(nextslave, SIGUSR2); +#ifdef USE_QFA + if (gTapeposfd >= 0) { + cntntrecs += ntrec; + } +#endif /* USE_QFA */ } if (nread != 0) quit("error reading command pipe: %s\n", strerror(errno)); @@ -1361,13 +1390,13 @@ doslave(int cmd, * loop until the count is satisfied (or error). */ static ssize_t -dump_atomic_read(int fd, void *buf, size_t count) +dump_atomic_read(int fd, char *buf, size_t count) { int got, need = count; do { while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0) - (char *)buf += got; + buf += got; } while (got == -1 && errno == EINTR); return (got < 0 ? got : (ssize_t)count - need); } @@ -1378,19 +1407,39 @@ dump_atomic_read(int fd, void *buf, size_t count) * loop until the count is satisfied (or error). */ static ssize_t -dump_atomic_write(int fd, const void *buf, size_t count) +dump_atomic_write(int fd, const char *buf, size_t count) { int got, need = count; do { while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0) - (char *)buf += got; + buf += got; } while (got == -1 && errno == EINTR); return (got < 0 ? got : (ssize_t)count - need); } +/* +int +SetLogicalPos(void) +{ + int err = 0; + struct mt_pos buf; + + buf.mt_op = MTSETDRVBUFFER; + buf.mt_count = MT_ST_BOOLEANS | MT_ST_SCSI2LOGICAL; + if (ioctl(tapefd, MTIOCTOP, &buf) == -1) { + err = errno; + msg("[%ld] error: %d (setting logical)\n", + (unsigned long)getpid(), err); + } + return err; +} +*/ + #ifdef USE_QFA +#define LSEEK_GET_TAPEPOS 10 +#define LSEEK_GO2_TAPEPOS 11 /* * read the current tape position */ @@ -1401,7 +1450,7 @@ GetTapePos(long long *pos) #ifdef RDUMP if (host) { - *pos = (long long) rmtseek(0, SEEK_CUR); + *pos = (long long) rmtseek((OFF_T)0, (int)LSEEK_GET_TAPEPOS); err = *pos < 0; } else @@ -1427,8 +1476,10 @@ GetTapePos(long long *pos) return err; } -static void -MkTapeString(struct s_spcl *spclptr, long long curtapepos) { +static int +MkTapeString(struct s_spcl *spclptr, long long curtapepos) +{ + int err = 0; #ifdef DEBUG_QFA msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos); @@ -1440,7 +1491,9 @@ MkTapeString(struct s_spcl *spclptr, long long curtapepos) { curtapepos); gTps[sizeof(gTps) - 1] = '\0'; if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) { - warn("error writing tapepos file.\n"); + err = errno; + warn("error writing tapepos file. (error %d)\n", errno); } + return err; } #endif /* USE_QFA */