#ifndef lint
static const char rcsid[] =
- "$Id: tape.c,v 1.77 2003/04/18 07:47:57 stelian Exp $";
+ "$Id: tape.c,v 1.82 2004/03/08 14:04:04 stelian Exp $";
#endif /* not lint */
#include <config.h>
#ifdef __linux__
#include <sys/types.h>
#include <sys/time.h>
+#include <linux/fs.h> /* for definition of BLKFLSBUF */
#include <time.h>
#endif
#include <sys/param.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;
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 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
/*
* 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;
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);
}
{
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);
}
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");
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) :
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;
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);
#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);
+ }
+ /* } */
}
}
}
* 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));
}
+/*
+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
*/
#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
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);
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 */