* Ported to Linux's Second Extended File System as part of the
* dump and restore backup suit
* Remy Card <card@Linux.EU.Org>, 1994-1997
- * Stelian Pop <pop@noos.fr>, 1999-2000
- * Stelian Pop <pop@noos.fr> - Alcôve <www.alcove.fr>, 2000
+ * Stelian Pop <stelian@popies.net>, 1999-2000
+ * Stelian Pop <stelian@popies.net> - Alcôve <www.alcove.com>, 2000-2002
*/
/*-
* 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.
*
#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.46 2001/05/12 11:36:12 stelian Exp $";
+ "$Id: tape.c,v 1.77 2003/04/18 07:47:57 stelian Exp $";
#endif /* not lint */
#include <config.h>
#include <signal.h>
#include <stdio.h>
#include <compaterr.h>
+#include <system.h>
#ifdef __STDC__
#include <stdlib.h>
#include <string.h>
#ifdef __linux__
#include <sys/types.h>
+#include <sys/time.h>
#include <time.h>
-#include <linux/types.h>
#endif
#include <sys/param.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mtio.h>
#ifdef __linux__
+#ifdef HAVE_EXT2FS_EXT2_FS_H
+#include <ext2fs/ext2_fs.h>
+#else
#include <linux/ext2_fs.h>
+#endif
#include <ext2fs/ext2fs.h>
+#include <sys/stat.h>
#include <bsdcompat.h>
#elif defined sunos
#include <sys/vnode.h>
#include <zlib.h>
#endif /* HAVE_ZLIB */
+#ifdef HAVE_BZLIB
+#include <bzlib.h>
+#endif /* HAVE_BZLIB */
+
+#ifdef HAVE_LZO
+#include <minilzo.h>
+#endif /* HAVE_LZO */
+
#include "dump.h"
int writesize; /* size of malloc()ed buffer for tape */
long blocksthisvol; /* number of blocks on current output file */
extern int ntrec; /* blocking factor on tape */
extern int cartridge;
-extern char *host;
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 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, void *, size_t));
+static ssize_t dump_atomic_write __P((int, const void *, 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));
-static int system_command __P((const char *, const char *, int));
+#ifdef USE_QFA
+static int GetTapePos __P((long long *));
+static void MkTapeString __P((struct s_spcl *, long long));
+#endif
/*
* Concurrent dump mods (Caltech) - disk block reading and tape writing
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 (! 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))
+ AfileActive = 0;
+ else {
+ union u_spcl tmp;
+ tmp = *(union u_spcl *)dp;
+ /* Write the record, _uncompressed_ */
+ if (isspcl) {
+ tmp.s_spcl.c_flags &= ~DR_COMPRESSED;
+ mkchecksum(&tmp);
+ }
+ if (write(Afile, &tmp, TP_BSIZE) != TP_BSIZE)
+ msg("error writing archive file: %s\n",
+ strerror(errno));
+ }
+ }
+
nextblock++;
if (isspcl)
lastspclrec = spcl.c_tapea;
}
static void
-sigpipe(int signo)
+sigpipe(UNUSED(int signo))
{
quit("Broken pipe\n");
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;
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 */
/* 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);
*/
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");
asize += tenths + returned.clen / density;
blockswritten += ntrec;
blocksthisvol += ntrec;
- if (!pipeout && !unlimited && (blocksperfile ?
- (blocksthisvol >= blocksperfile) : (asize > tsize))) {
- close_rewind();
- startnewtape(0);
- }
- timeest();
-}
-
-/*
- * Executes the command in a shell.
- * Returns -1 if an error occured, the exit status of
- * the command on success.
- */
-int system_command(const char *command, const char *device, int volnum) {
- int pid, status;
- char commandstr[4096];
-
- pid = fork();
- if (pid == -1) {
- perror(" DUMP: unable to fork");
- return -1;
- }
- if (pid == 0) {
- setuid(getuid());
- setgid(getgid());
-#if OLD_STYLE_FSCRIPT
- snprintf(commandstr, sizeof(commandstr), "%s", command);
-#else
- snprintf(commandstr, sizeof(commandstr), "%s %s %d", command, device, volnum);
-#endif
- commandstr[sizeof(commandstr) - 1] = '\0';
- execl("/bin/sh", "sh", "-c", commandstr, NULL);
- perror(" DUMP: unable to execute shell");
- exit(-1);
- }
- do {
- if (waitpid(pid, &status, 0) == -1) {
- if (errno != EINTR) {
- perror(" DUMP: waitpid error");
- return -1;
+ if (!pipeout && !unlimited) {
+ if (blocksperfile) {
+ if ( compressed ? (bytes_written - tapea_bytes + SLAVES * (writesize + sizeof(struct tapebuf))) >= (((long long)blocksperfile) * 1024)
+ : blocksthisvol >= blocksperfile ) {
+ close_rewind();
+ startnewtape(0);
}
- } else {
- if (WIFEXITED(status))
- return WEXITSTATUS(status);
- else
- return -1;
}
- } while(1);
+ else if (asize > tsize) {
+ close_rewind();
+ startnewtape(0);
+ }
+ }
+ timeest();
}
time_t
* 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);
#ifdef RDUMP
if (host) {
rmtclose();
- while (rmtopen(tape, 0) < 0)
+ while (rmtopen(tape, O_RDONLY) < 0)
sleep(10);
rmtclose();
}
#endif
{
(void) close(tapefd);
- while ((f = OPEN(tape, 0)) < 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);
+ if (!fifoout) {
+ while ((f = OPEN(tape, O_RDONLY)) < 0)
+ sleep (10);
+ (void) close(f);
+ }
}
}
return do_stats();
void
close_rewind(void)
{
+ int eot_code = 1;
(void)trewind();
- if (nexttape || Mflag || (eot_code == 0) )
+ if (nexttape || Mflag)
+ return;
+ 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 (!nogripe) {
msg("Change Volumes: Mount volume #%d\n", tapeno+1);
void
rollforward(void)
{
- register struct req *p, *q, *prev;
- register struct slave *tslp;
+ struct req *p, *q = NULL, *prev;
+ struct slave *tslp;
int i, size, savedtapea, got;
union u_spcl *ntb, *otb;
struct slave_results returned;
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);
}
* 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);
msg("Dumping volume %d on %s\n", tapeno, tape);
}
#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);
}
+#ifdef RDUMP
+ if (!host)
+#endif
+ {
+ struct mtget mt_stat;
+ magtapeout = ioctl(tapefd, MTIOCGET, (char *)&mt_stat) == 0;
+ /*
+ msg("Output is to %s\n",
+ magtapeout ? "tape" : "file/pipe");
+ */
+ }
enslave(); /* Share open tape file descriptor with slaves */
if (tapeno > 1)
msg("Volume %d begins with blocks from inode %d\n",
tapeno, slp->inode);
+ if (tapeno < (int)TP_NINOS)
+ volinfo[tapeno] = slp->inode;
}
}
void
-dumpabort(int signo)
+dumpabort(UNUSED(int signo))
{
if (master != 0 && master != getpid())
* 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);
#ifdef LINUX_FORK_BUG
int i, j;
#else
- register int i, j;
+ int i, j;
#endif
master = getpid();
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);
+ doslave(cmd[0],
+#ifdef WRITEDEBUG
+ i,
+#endif
+ (slaves[i].pid == slp->pid));
Exit(X_FINOK);
}
else
* 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);
void
killall(void)
{
- register int i;
+ int i;
for (i = 0; i < SLAVES; i++)
if (slaves[i].pid > 0) {
* slaves.
*/
static void
-doslave(int cmd, int slave_number)
+doslave(int cmd,
+#ifdef WRITEDEBUG
+ int slave_number,
+#endif
+ int first)
{
- register int nread;
- int nextslave, size, eot_count, bufsize;
- volatile int wrote = 0;
- char *buffer;
-#ifdef HAVE_ZLIB
- struct tapebuf *comp_buf = NULL;
- int compresult, do_compress = slave_number > 0;
+ int nread;
+ 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;
-#endif /* HAVE_ZLIB */
+#ifdef HAVE_BZLIB
+ unsigned int worklen2;
+#endif
+#ifdef HAVE_LZO
+ lzo_align_t __LZO_MMODEL *LZO_WorkMem;
+#endif
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
struct slave_results returns;
#ifdef __linux__
errcode_t retval;
#endif
#ifdef USE_QFA
- long curtapepos;
+ long long curtapepos;
union u_spcl *uspclptr;
struct s_spcl *spclptr;
#endif /* USE_QFA */
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGUSR2);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+ sigemptyset(&set);
/*
* Need our own seek pointer.
if ((diskfd = OPEN(disk, O_RDONLY)) < 0)
quit("slave couldn't reopen disk: %s\n", strerror(errno));
#ifdef __linux__
+#ifdef BLKFLSBUF
+ (void)ioctl(diskfd, BLKFLSBUF);
+#endif
ext2fs_close(fs);
retval = dump_fs_open(disk, &fs);
if (retval)
/*
* 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");
}
-#ifdef HAVE_ZLIB
+#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");
- comp_buf->flags = 0;
+ 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 */
+#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) {
- register struct req *p = slp->req;
+ while ((nread = dump_atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) {
+ struct req *p = slp->req;
for (trecno = 0; trecno < ntrec;
trecno += p->count, p += p->count) {
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");
bufsize = writesize; /* length to write */
returns.clen = returns.unclen = bufsize;
-#ifdef HAVE_ZLIB
+#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
if (compressed && do_compress) {
comp_buf->length = bufsize;
worklen = TP_BSIZE + writesize;
- compresult = compress2(comp_buf->buf, &worklen,
- (char *)slp->tblock[0], writesize, compressed);
- if (compresult == Z_OK && worklen <= (writesize - 16)) {
+ compresult = 1;
+#ifdef HAVE_ZLIB
+ if (zipflag == COMPRESS_ZLIB) {
+ compresult = compress2(comp_buf->buf,
+ &worklen,
+ (char *)slp->tblock[0],
+ writesize,
+ compressed);
+ if (compresult == Z_OK)
+ compresult = 1;
+ else
+ compresult = 0;
+ }
+#endif /* HAVE_ZLIB */
+#ifdef HAVE_BZLIB
+ if (zipflag == COMPRESS_BZLIB) {
+ worklen2 = worklen;
+ compresult = BZ2_bzBuffToBuffCompress(
+ comp_buf->buf,
+ &worklen2,
+ (char *)slp->tblock[0],
+ writesize,
+ compressed,
+ 0, 30);
+ worklen = worklen2;
+ if (compresult == BZ_OK)
+ compresult = 1;
+ else
+ compresult = 0;
+ }
+
+#endif /* HAVE_BZLIB */
+#ifdef HAVE_LZO
+ if (zipflag == COMPRESS_LZO) {
+ compresult = lzo1x_1_compress((char *)slp->tblock[0],writesize,
+ comp_buf->buf,
+ (lzo_uintp)&worklen,
+ LZO_WorkMem);
+ 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;
}
/* compress the remaining blocks if we're compressing */
do_compress = compressed;
-#endif /* HAVE_ZLIB */
+#endif /* HAVE_ZLIB || HAVE_BZLIB || HAVE_LZO */
if (sigsetjmp(jmpbuf, 1) == 0) {
ready = 1;
if (!caught)
- (void) pause();
+ sigsuspend(&set);
}
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");
- }
+ int i;
+ int firstpass = 1;
+ for (i = 0; i < ntrec; ++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;
+ if (gtperr == 0)
+ gtperr = GetTapePos(&curtapepos);
}
+ if (gtperr == 0)
+ MkTapeString(spclptr, curtapepos);
}
}
}
#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
* 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.
* 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, void *buf, size_t count)
{
int got, need = count;
while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0)
(char *)buf += got;
} while (got == -1 && errno == EINTR);
- return (got < 0 ? got : count - need);
+ return (got < 0 ? got : (ssize_t)count - need);
}
/*
* 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 void *buf, size_t count)
{
int got, need = count;
while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0)
(char *)buf += got;
} while (got == -1 && errno == EINTR);
- return (got < 0 ? got : count - need);
+ return (got < 0 ? got : (ssize_t)count - need);
}
/*
* read the current tape position
*/
-int
-GetTapePos(long *pos)
+static int
+GetTapePos(long long *pos)
{
int err = 0;
- *pos = 0;
- if (ioctl(tapefd, MTIOCPOS, pos) == -1) {
+#ifdef RDUMP
+ if (host) {
+ *pos = (long long) rmtseek(0, SEEK_CUR);
+ err = *pos < 0;
+ }
+ else
+#endif
+ {
+ if (magtapeout) {
+ long mtpos;
+ *pos = 0;
+ err = (ioctl(tapefd, MTIOCPOS, &mtpos) < 0);
+ *pos = (long long)mtpos;
+ }
+ else {
+ *pos = LSEEK(tapefd, 0, SEEK_CUR);
+ err = (*pos < 0);
+ }
+ }
+ if (err) {
err = errno;
- msg("[%ld] error: %d (getting tapepos: %ld)\n", getpid(),
+ msg("[%ld] error: %d (getting tapepos: %lld)\n", getpid(),
err, *pos);
return err;
}
return err;
}
+
+static void
+MkTapeString(struct s_spcl *spclptr, long long curtapepos) {
+
+#ifdef DEBUG_QFA
+ msg("inode %ld at tapepos %lld\n", spclptr->c_inumber, curtapepos);
+#endif
+
+ snprintf(gTps, sizeof(gTps), "%ld\t%d\t%lld\n",
+ (unsigned long)spclptr->c_inumber,
+ tapeno,
+ curtapepos);
+ gTps[sizeof(gTps) - 1] = '\0';
+ if (write(gTapeposfd, gTps, strlen(gTps)) != (ssize_t)strlen(gTps)) {
+ warn("error writing tapepos file.\n");
+ }
+}
#endif /* USE_QFA */