X-Git-Url: https://git.wh0rd.org/?p=dump.git;a=blobdiff_plain;f=dump%2Ftape.c;h=89f630d278ea3484c4ac8aa8054575a81bcdc7a6;hp=39d8b4caae4023890c9be13f6604ac8faf851391;hb=1ba0c4bb3595ad2d15cd378e989933a883c8f77e;hpb=7ad0e4095900bf99e57eedf254d7162ef5112f43 diff --git a/dump/tape.c b/dump/tape.c index 39d8b4c..89f630d 100644 --- a/dump/tape.c +++ b/dump/tape.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: tape.c,v 1.65 2002/03/11 10:17:43 stelian Exp $"; + "$Id: tape.c,v 1.88 2005/03/02 08:46:55 stelian Exp $"; #endif /* not lint */ #include @@ -64,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 @@ -99,12 +100,17 @@ int write(), read(); #include #endif /* HAVE_BZLIB */ +#ifdef HAVE_LZO +#include +#endif /* HAVE_LZO */ + #include "dump.h" 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; @@ -114,16 +120,21 @@ 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 atomic_read __P((int, void *, size_t)); -static ssize_t 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 +static void doslave __P((int, int)); +#endif static void enslave __P((void)); static void flushtape __P((void)); 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 /* @@ -135,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; @@ -191,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; @@ -227,20 +238,20 @@ 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; /* Need to write it to the archive file */ - if (Afile < 0 && isspcl && (spcl.c_type == TS_END)) - Afile = -Afile; - if (Afile > 0) { + if (! AfileActive && isspcl && (spcl.c_type == TS_END)) + AfileActive = 1; + if (AfileActive && Afile >= 0) { /* When we dump an inode which is not a directory, * it means we ended the archive contents */ if (isspcl && (spcl.c_type == TS_INODE) && ((spcl.c_dinode.di_mode & S_IFMT) != IFDIR)) - Afile = -Afile; + AfileActive = 0; else { union u_spcl tmp; tmp = *(union u_spcl *)dp; @@ -265,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; @@ -311,7 +323,7 @@ tperror(int errnum) } static void -sigpipe(int signo) +sigpipe(UNUSED(int signo)) { quit("Broken pipe\n"); @@ -332,7 +344,7 @@ do_stats(void) blocks = spcl.c_tapea - tapea_volume; msg("Volume %d completed at: %s", tapeno, ctime(&tnow)); if (! compressed) - msg("Volume %d %ld tape blocks (%.2fMB)\n", tapeno, + msg("Volume %d %ld blocks (%.2fMB)\n", tapeno, blocks, ((double)blocks * TP_BSIZE / 1048576)); if (ttaken > 0) { long volkb = (bytes_written - tapea_bytes) / 1024; @@ -408,9 +420,13 @@ flushtape(void) int siz = (char *)nextblock - (char *)slp->req; + /* make sure returned has sane values in case we don't read + * them from the slave in this pass */ + returned.unclen = returned.clen = writesize; + slp->req[trecno].count = 0; /* Sentinel */ - if (atomic_write( slp->fd, (char *)slp->req, siz) != siz) + if (dump_atomic_write( slp->fd, (char *)slp->req, siz) != siz) quit("error writing command pipe: %s\n", strerror(errno)); slp->sent = 1; /* we sent a request, read the response later */ @@ -421,7 +437,7 @@ flushtape(void) /* Read results back from next slave */ if (slp->sent) { - if (atomic_read( slp->fd, (char *)&returned, sizeof returned) + if (dump_atomic_read( slp->fd, (char *)&returned, sizeof returned) != sizeof returned) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -446,7 +462,7 @@ flushtape(void) */ for (i = 0; i < SLAVES; i++) { if (slaves[i].sent) { - if (atomic_read( slaves[i].fd, + if (dump_atomic_read( slaves[i].fd, (char *)&returned, sizeof returned) != sizeof returned) { perror(" DUMP: error reading command pipe in master"); @@ -463,10 +479,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; @@ -478,9 +498,9 @@ flushtape(void) blockswritten += ntrec; blocksthisvol += ntrec; if (!pipeout && !unlimited) { - if (blocksperfile) { - if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= 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); } @@ -510,7 +530,7 @@ trewind(void) * fixme: punt for now. */ if (slaves[f].sent) { - if (atomic_read( slaves[f].fd, (char *)&returned, sizeof returned) + if (dump_atomic_read( slaves[f].fd, (char *)&returned, sizeof returned) != sizeof returned) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -542,7 +562,7 @@ trewind(void) #ifdef RDUMP if (host) { rmtclose(); - while (rmtopen(tape, 0) < 0) + while (rmtopen(tape, O_RDONLY) < 0) sleep(10); rmtclose(); } @@ -551,20 +571,11 @@ trewind(void) { (void) close(tapefd); if (!fifoout) { - while ((f = OPEN(tape, 0)) < 0) + while ((f = OPEN(tape, O_RDONLY)) < 0) sleep (10); (void) close(f); } } - eot_code = 1; - if (eot_script && spcl.c_type != TS_END) { - msg("Launching %s\n", eot_script); - eot_code = system_command(eot_script, tape, tapeno); - } - if (eot_code != 0 && eot_code != 1) { - msg("Dump aborted by the end of tape script\n"); - dumpabort(0); - } } return do_stats(); } @@ -573,8 +584,19 @@ trewind(void) void close_rewind(void) { + int eot_code = 1; (void)trewind(); - if (nexttape || Mflag || (eot_code == 0) ) + if (eot_script) { + msg("Launching %s\n", eot_script); + eot_code = system_command(eot_script, tape, tapeno); + } + if (eot_code != 0 && eot_code != 1) { + msg("Dump aborted by the end of tape script\n"); + dumpabort(0); + } + if (eot_code == 0) + return; + if (nexttape || Mflag) return; if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); @@ -602,6 +624,10 @@ rollforward(void) tslp = &slaves[SLAVES]; ntb = (union u_spcl *)tslp->tblock[1]; + /* make sure returned has sane values in case we don't read + * them from the slave in this pass */ + returned.unclen = returned.clen = writesize; + /* * Each of the N slaves should have requests that need to * be replayed on the next tape. Use the extra slave buffers @@ -645,7 +671,7 @@ rollforward(void) lastspclrec = savedtapea - 1; } size = (char *)ntb - (char *)q; - if (atomic_write( slp->fd, (char *)q, size) != size) { + if (dump_atomic_write( slp->fd, (char *)q, size) != size) { perror(" DUMP: error writing command pipe"); dumpabort(0); } @@ -693,7 +719,7 @@ rollforward(void) * worked ok, otherwise the tape is much too short! */ if (slp->sent) { - if (atomic_read( slp->fd, (char *)&returned, sizeof returned) + if (dump_atomic_read( slp->fd, (char *)&returned, sizeof returned) != sizeof returned) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -863,16 +889,19 @@ 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, 2) : pipeout ? + while ((tapefd = (host ? rmtopen(tape, O_WRONLY|O_CREAT|O_TRUNC) : pipeout ? fileno(stdout) : - OPEN(tape, O_WRONLY|O_CREAT, 0666))) < 0) + OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0) #else while ((tapefd = (pipeout ? fileno(stdout) : - OPEN(tape, O_RDWR|O_CREAT, 0666))) < 0) + OPEN(tape, O_WRONLY|O_CREAT|O_TRUNC, 0666))) < 0) #endif { - msg("Cannot open output \"%s\".\n", tape); + msg("Cannot open output \"%s\": %s\n", tape, + strerror(errno)); if (!query("Do you want to retry the open?")) dumpabort(0); } @@ -913,13 +942,13 @@ restore_check_point: if (tapeno > 1) msg("Volume %d begins with blocks from inode %d\n", tapeno, slp->inode); - if (tapeno < TP_NINOS) + if (tapeno < (int)TP_NINOS) volinfo[tapeno] = slp->inode; } } void -dumpabort(int signo) +dumpabort(UNUSED(int signo)) { if (master != 0 && master != getpid()) @@ -949,7 +978,7 @@ Exit(int status) * proceed - handler for SIGUSR2, used to synchronize IO between the slaves. */ static void -proceed(int signo) +proceed(UNUSED(int signo)) { if (ready) siglongjmp(jmpbuf, 1); @@ -1006,11 +1035,15 @@ enslave(void) sigprocmask(SIG_BLOCK, &sigs, NULL); #ifdef LINUX_FORK_BUG - if (atomic_write( cmd[0], (char *) &i, sizeof i) + if (dump_atomic_write( cmd[0], (char *) &i, sizeof i) != sizeof i) quit("master/slave protocol botched 3\n"); #endif - doslave(cmd[0], i, (slaves[i].pid == slp->pid)); + doslave(cmd[0], +#ifdef WRITEDEBUG + i, +#endif + (slaves[i].pid == slp->pid)); Exit(X_FINOK); } else @@ -1024,12 +1057,12 @@ enslave(void) * returned from fork() causes a SEGV in the child process */ for (i = 0; i < SLAVES; i++) - if (atomic_read( slaves[i].fd, (char *) &j, sizeof j) != sizeof j) + if (dump_atomic_read( slaves[i].fd, (char *) &j, sizeof j) != sizeof j) quit("master/slave protocol botched 4\n"); #endif for (i = 0; i < SLAVES; i++) - (void) atomic_write( slaves[i].fd, + (void) dump_atomic_write( slaves[i].fd, (char *) &slaves[(i + 1) % SLAVES].pid, sizeof slaves[0].pid); @@ -1056,20 +1089,25 @@ killall(void) * slaves. */ static void -doslave(int cmd, int slave_number, int first) +doslave(int cmd, +#ifdef WRITEDEBUG + int slave_number, +#endif + int first) { int nread; - int nextslave, size, eot_count, bufsize; - volatile int wrote = 0; - char *buffer; -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) - struct tapebuf *comp_buf = NULL; - int compresult, do_compress = !first; + int nextslave; + volatile int wrote = 0, size, eot_count, bufsize; + char * volatile buffer; +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) + struct tapebuf * volatile comp_buf = NULL; + int compresult; + volatile int do_compress = !first; unsigned long worklen; -#ifdef HAVE_BZLIB - unsigned int worklen2; +#ifdef HAVE_LZO + lzo_align_t __LZO_MMODEL *LZO_WorkMem; #endif -#endif /* HAVE_ZLIB || HAVE_BZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ struct slave_results returns; #ifdef __linux__ errcode_t retval; @@ -1078,6 +1116,9 @@ doslave(int cmd, int slave_number, int first) 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; @@ -1094,7 +1135,7 @@ doslave(int cmd, int slave_number, int first) 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); @@ -1105,28 +1146,44 @@ doslave(int cmd, int slave_number, int first) /* * Need the pid of the next slave in the loop... */ - if ((nread = atomic_read( cmd, (char *)&nextslave, sizeof nextslave)) + if ((nread = dump_atomic_read( cmd, (char *)&nextslave, sizeof nextslave)) != sizeof nextslave) { quit("master/slave protocol botched - didn't get pid of next slave.\n"); } -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) /* if we're doing a compressed dump, allocate the compress buffer */ if (compressed) { - comp_buf = malloc(sizeof(struct tapebuf) + TP_BSIZE + writesize); + int bsiz = sizeof(struct tapebuf) + writesize; + /* Add extra space to deal with compression enlarging the buffer */ + if (TP_BSIZE > writesize/16 + 67) + bsiz += TP_BSIZE; + else + bsiz += writesize/16 + 67; + comp_buf = malloc(bsiz); if (comp_buf == NULL) quit("couldn't allocate a compress buffer.\n"); - if (bzipflag) - comp_buf->flags = COMPRESS_BZLIB; - else + if (zipflag == COMPRESS_ZLIB) comp_buf->flags = COMPRESS_ZLIB; + else if (zipflag == COMPRESS_BZLIB) + comp_buf->flags = COMPRESS_BZLIB; + else if (zipflag == COMPRESS_LZO) { + comp_buf->flags = COMPRESS_LZO; + if (lzo_init() != LZO_E_OK) quit("lzo_init failed\n"); + } else + quit("internal error - unknown compression method: %d\n", zipflag); } -#endif /* HAVE_ZLIB || HAVE_BZLIB */ +#ifdef HAVE_LZO + LZO_WorkMem = malloc(LZO1X_1_MEM_COMPRESS); + if (!LZO_WorkMem) + quit("couldn't allocate a compress buffer.\n"); +#endif +#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ /* * Get list of blocks to dump, read the blocks into tape buffer */ - while ((nread = atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) { + while ((nread = dump_atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) { struct req *p = slp->req; for (trecno = 0; trecno < ntrec; @@ -1135,7 +1192,7 @@ doslave(int cmd, int slave_number, int first) bread(p->dblk, slp->tblock[trecno], p->count * TP_BSIZE); } else { /* read record from pipe */ - if (p->count != 1 || atomic_read( cmd, + if (p->count != 1 || dump_atomic_read( cmd, (char *)slp->tblock[trecno], TP_BSIZE) != TP_BSIZE) quit("master/slave protocol botched.\n"); @@ -1150,7 +1207,7 @@ doslave(int cmd, int slave_number, int first) bufsize = writesize; /* length to write */ returns.clen = returns.unclen = bufsize; -#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) +#if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO) /* * When writing a compressed dump, each block except * the first one on each tape is written @@ -1169,7 +1226,7 @@ doslave(int cmd, int slave_number, int first) worklen = TP_BSIZE + writesize; compresult = 1; #ifdef HAVE_ZLIB - if (!bzipflag) { + if (zipflag == COMPRESS_ZLIB) { compresult = compress2(comp_buf->buf, &worklen, (char *)slp->tblock[0], @@ -1182,8 +1239,8 @@ doslave(int cmd, int slave_number, int first) } #endif /* HAVE_ZLIB */ #ifdef HAVE_BZLIB - if (bzipflag) { - worklen2 = worklen; + if (zipflag == COMPRESS_BZLIB) { + unsigned int worklen2 = worklen; compresult = BZ2_bzBuffToBuffCompress( comp_buf->buf, &worklen2, @@ -1199,7 +1256,21 @@ doslave(int cmd, int slave_number, int first) } #endif /* HAVE_BZLIB */ - if (compresult && worklen <= (writesize - 16)) { +#ifdef HAVE_LZO + if (zipflag == COMPRESS_LZO) { + lzo_uint worklen2 = worklen; + compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize, + comp_buf->buf, + &worklen2, + LZO_WorkMem); + worklen = worklen2; + if (compresult == LZO_E_OK) + compresult = 1; + else + compresult = 0; + } +#endif /* HAVE_LZO */ + if (compresult && worklen <= ((unsigned long)writesize - 16)) { /* write the compressed buffer */ comp_buf->length = worklen; comp_buf->compressed = 1; @@ -1218,7 +1289,7 @@ doslave(int cmd, int slave_number, int first) } /* compress the remaining blocks if we're compressing */ do_compress = compressed; -#endif /* HAVE_ZLIB || HAVE_BZLIB */ +#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */ if (sigsetjmp(jmpbuf, 1) == 0) { ready = 1; @@ -1231,23 +1302,30 @@ doslave(int cmd, int slave_number, int first) #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); + } + /* } */ } } } @@ -1263,11 +1341,12 @@ doslave(int cmd, int slave_number, int first) #ifdef WRITEDEBUG printf("slave %d wrote %d\n", slave_number, wrote); #endif - if (wrote < 0) + if (wrote < 0 && errno != ENOSPC) break; - if (wrote == 0) + if (wrote == 0 || (wrote < 0 && errno == ENOSPC)) eot_count++; - size += wrote; + else + size += wrote; } #ifdef WRITEDEBUG @@ -1297,12 +1376,17 @@ doslave(int cmd, int slave_number, int first) * pass size of data and size of write back to master * (for EOT handling) */ - (void) atomic_write( cmd, (char *)&returns, sizeof returns); + (void) dump_atomic_write( cmd, (char *)&returns, sizeof returns); /* * 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)); @@ -1314,15 +1398,15 @@ doslave(int cmd, int slave_number, int first) * loop until the count is satisfied (or error). */ static ssize_t -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 : count - need); + return (got < 0 ? got : (ssize_t)count - need); } /* @@ -1331,19 +1415,39 @@ atomic_read(int fd, void *buf, size_t count) * loop until the count is satisfied (or error). */ static ssize_t -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 : count - need); + 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 */ @@ -1354,7 +1458,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 @@ -1380,8 +1484,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); @@ -1392,8 +1498,10 @@ MkTapeString(struct s_spcl *spclptr, long long curtapepos) { tapeno, curtapepos); gTps[sizeof(gTps) - 1] = '\0'; - if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps)) { - warn("error writing tapepos file.\n"); + if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) { + err = errno; + warn("error writing tapepos file. (error %d)\n", errno); } + return err; } #endif /* USE_QFA */