* 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
*/
/*-
#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.55 2001/09/06 09:00:32 stelian Exp $";
+ "$Id: tape.c,v 1.63 2002/02/21 09:25:31 stelian Exp $";
#endif /* not lint */
#include <config.h>
#endif
#include <sys/param.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mtio.h>
#ifdef __linux__
#include <linux/ext2_fs.h>
#endif
#include <ext2fs/ext2fs.h>
+#include <sys/stat.h>
#include <bsdcompat.h>
#elif defined sunos
#include <sys/vnode.h>
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 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));
+#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 (Afile < 0 && isspcl && (spcl.c_type == TS_END))
+ Afile = -Afile;
+ if (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;
+ 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;
void
rollforward(void)
{
- register struct req *p, *q = NULL, *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;
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 < TP_NINOS)
+ volinfo[tapeno] = slp->inode;
}
}
#ifdef LINUX_FORK_BUG
int i, j;
#else
- register int i, j;
+ int i, j;
#endif
master = getpid();
void
killall(void)
{
- register int i;
+ int i;
for (i = 0; i < SLAVES; i++)
if (slaves[i].pid > 0) {
static void
doslave(int cmd, int slave_number, int first)
{
- register int nread;
+ int nread;
int nextslave, size, eot_count, bufsize;
volatile int wrote = 0;
char *buffer;
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.
* 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;
+ struct req *p = slp->req;
for (trecno = 0; trecno < ntrec;
trecno += p->count, p += p->count) {
if (compressed && do_compress) {
comp_buf->length = bufsize;
worklen = TP_BSIZE + writesize;
+ compresult = 1;
#ifdef HAVE_ZLIB
if (!bzipflag) {
compresult = compress2(comp_buf->buf,
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) &&
- (spclptr->c_date == gThisDumpDate)) {
- /* 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;
+ 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 (gtperr == 0) {
+ if ((gtperr = GetTapePos(&curtapepos)) == 0)
+ MkTapeString(spclptr, curtapepos);
}
}
}
/*
* 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)) != strlen(gTps)) {
+ warn("error writing tapepos file.\n");
+ }
+}
#endif /* USE_QFA */