Made -Q option work on regular files.
authorStelian Pop <stelian@popies.net>
Tue, 22 Jan 2002 11:12:28 +0000 (11:12 +0000)
committerStelian Pop <stelian@popies.net>
Tue, 22 Jan 2002 11:12:28 +0000 (11:12 +0000)
CHANGES
dump/dump.8.in
dump/dump.h
dump/main.c
dump/tape.c
restore/main.c
restore/restore.8.in
restore/restore.c
restore/tape.c

diff --git a/CHANGES b/CHANGES
index 1e9bd77a62905934833130425faadcab0d9c53d6..55a910a0642492607f0f29631107ef0b6854627a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.156 2002/01/16 10:29:23 stelian Exp $
+$Id: CHANGES,v 1.157 2002/01/22 11:12:28 stelian Exp $
 
 Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
 =====================================================================
@@ -16,6 +16,11 @@ Changes between versions 0.4b26 and 0.4b27 (released ???????????????)
        restores in -i or -x mode (automatically walks through the
        multiple dump volumes).
 
+5.     Extended the QFA mode to work with local files. This way,
+       restore can know in advance the tape number and the offset
+       for the inodes to extract and can minimize the extraction
+       time by seeking directly to the good tape/offset.
+
 Changes between versions 0.4b25 and 0.4b26 (released January 7, 2002)
 =====================================================================
 
index ff04b2d25e091eab0a4fd1921e31bf6c320a244a..22ed34036b76f39e42ab77254a50e96930df1084 100644 (file)
@@ -30,7 +30,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: dump.8.in,v 1.35 2002/01/16 09:32:14 stelian Exp $
+.\"    $Id: dump.8.in,v 1.36 2002/01/22 11:12:28 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt DUMP 8
@@ -298,6 +298,9 @@ page, on how to set the driver to return logical tape positions.
 Before calling restore with parameter Q, always make sure the st
 driver is set to return the same type of tape position used during the 
 call to dump. Otherwise restore may be confused.
+.Pp
+This option can be used when dumping to local tapes (see above)
+or to local files.
 .It Fl s Ar feet
 Attempt to calculate the amount of tape needed at a particular density.
 If this amount is exceeded,
index 062f45e5781d2a231beb0eceeb4d298a832fe3e3..e2c008f016a51134dd163483493374bcac5632ce 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <stelian@popies.net>, 1999-2000
  *     Stelian Pop <stelian@popies.net> - AlcĂ´ve <www.alcove.com>, 2000-2002
  *
- *     $Id: dump.h,v 1.34 2002/01/16 09:32:14 stelian Exp $
+ *     $Id: dump.h,v 1.35 2002/01/22 11:12:28 stelian Exp $
  */
 
 /*-
@@ -118,7 +118,6 @@ extern int  gTapeposfd;
 extern char    *gTapeposfile;
 extern char    gTps[255];
 extern int32_t gThisDumpDate;
-int    GetTapePos __P((long *pos));
 #endif /* USE_QFA */
 
 #ifndef __P
index c76f9ae693237eaf7bbe01a99bb6d74ef467c27d..a64ad67c0fcc67e0f6a7a8036073458b1010744f 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.65 2002/01/16 09:32:14 stelian Exp $";
+       "$Id: main.c,v 1.66 2002/01/22 11:12:28 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -470,6 +470,13 @@ main(int argc, char *argv[])
                tapeprefix = strchr(host, ':');
                *tapeprefix++ = '\0';
 #ifdef RDUMP
+#ifdef USE_QFA
+               if (tapepos) {
+                       msg("Cannot use -Q option on remote media\n");
+                       msg("The ENTIRE dump is aborted.\n");
+                       exit(X_STARTUP);
+               }
+#endif
                if (index(tapeprefix, '\n')) {
                        msg("invalid characters in tape\n");
                        msg("The ENTIRE dump is aborted.\n");
@@ -846,10 +853,11 @@ main(int argc, char *argv[])
 #ifdef USE_QFA
        if (tapepos) {
                msg("writing QFA positions to %s\n", gTapeposfile);
-               if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR)) < 0)
+               if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR)) < 0)
                        quit("can't open tapeposfile\n");
                /* print QFA-file header */
-               sprintf(gTps, "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
+               snprintf(gTps, sizeof(gTps), "%s\n%s\n%ld\n\n", QFA_MAGIC, QFA_VERSION, (unsigned long)spcl.c_date);
+               gTps[sizeof(gTps) - 1] = '\0';
                if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
                        quit("can't write tapeposfile\n");
                sprintf(gTps, "ino\ttapeno\ttapepos\n");
index 918a445bfd153f678e3a652271c491b5702fcf01..df8676362d65c5bbab59772eb0c0c77bcbef02ee 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.59 2002/01/16 09:32:14 stelian Exp $";
+       "$Id: tape.c,v 1.60 2002/01/22 11:12:28 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -115,6 +115,7 @@ 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));
@@ -123,6 +124,10 @@ 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 *));
+static void MkTapeString __P((struct s_spcl *, long));
+#endif
 
 /*
  * Concurrent dump mods (Caltech) - disk block reading and tape writing
@@ -850,6 +855,17 @@ restore_check_point:
                        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 */
 
@@ -1191,22 +1207,18 @@ doslave(int cmd, int slave_number, int first)
 
 #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_date == gThisDumpDate)) {
+                                       /* if an error occured previously don't
+                                        * try again */
+                                       if (gtperr == 0) {
+                                               if ((gtperr = GetTapePos(&curtapepos)) == 0)
+                                                       MkTapeString(spclptr, curtapepos);
                                        }
                                }
                        }
@@ -1307,13 +1319,20 @@ atomic_write(int fd, const void *buf, size_t count)
 /*
  * read the current tape position
  */
-int
+static int
 GetTapePos(long *pos)
 {
        int err = 0;
 
-       *pos = 0;
-       if (ioctl(tapefd, MTIOCPOS, pos) == -1) {
+       if (magtapeout) {
+               *pos = 0;
+               err = (ioctl(tapefd, MTIOCPOS, pos) < 0);
+       }
+       else {
+               *pos = lseek(tapefd, 0, SEEK_CUR);
+               err = (*pos < 0);
+       }
+       if (err) {
                err = errno;
                msg("[%ld] error: %d (getting tapepos: %ld)\n", getpid(), 
                        err, *pos);
@@ -1321,4 +1340,21 @@ GetTapePos(long *pos)
        }
        return err;
 }
+
+static void 
+MkTapeString(struct s_spcl *spclptr, long curtapepos) {
+
+#ifdef DEBUG_QFA
+       msg("inode %ld at tapepos %ld\n", spclptr->c_inumber, curtapepos);
+#endif
+
+       snprintf(gTps, sizeof(gTps), "%ld\t%d\t%ld\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 */
index d0ca888b92be4da03b897bc46d2a1b0a00355be5..ab058abcdaf74eb3d2f94344f35e95e3e5750a9b 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.35 2002/01/16 10:29:26 stelian Exp $";
+       "$Id: main.c,v 1.36 2002/01/22 11:12:28 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -240,6 +240,7 @@ main(int argc, char *argv[])
                case 'Q':
                        gTapeposfile = optarg;
                        tapeposflag = 1;
+                       aflag = 1;
                        break;
 #endif
                case 's':
index 703111ef5b2afd8339f86354240a3569efc230d4..90fb1e323427e7f92cbae1db99173a8672f04e08 100644 (file)
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"    $Id: restore.8.in,v 1.22 2002/01/16 10:29:26 stelian Exp $
+.\"    $Id: restore.8.in,v 1.23 2002/01/22 11:12:28 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt RESTORE 8
@@ -450,6 +450,9 @@ page, on how to set the driver to return logical tape positions.
 Before calling restore with parameter Q, always make sure the st
 driver is set to return the same type of tape position used during the 
 call to dump. Otherwise restore may be confused.
+.Pp
+This option can be used when restoring from local tapes (see above)
+or from local files.
 .It Fl s Ar fileno
 Read from the specified
 .Ar fileno
index c96fe6c7f08f1b86c8613ee0feeacce9336c505e..3cc2badf9654143be991a5102c5f8ad599960ba6 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: restore.c,v 1.23 2002/01/16 10:53:28 stelian Exp $";
+       "$Id: restore.c,v 1.24 2002/01/22 11:12:28 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -845,7 +845,10 @@ createfiles(void)
 
        Vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
-       getvol((long)1);
+#ifdef USE_QFA
+       if (!tapeposflag)
+#endif
+               getvol((long)1);
        skipmaps();
        skipdirs();
        first = lowerbnd(ROOTINO);
index 50d8a3e1daef9a10bd59c5527651855ca41d0a9a..cf024713643ab76e53dca89f0142f14279196b65 100644 (file)
@@ -46,7 +46,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.53 2002/01/16 10:29:26 stelian Exp $";
+       "$Id: tape.c,v 1.54 2002/01/22 11:12:28 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -190,6 +190,10 @@ setinput(char *source)
 
 #ifdef RRESTORE
        if (strchr(source, ':')) {
+#ifdef USE_QFA
+               if (tapeposflag)
+                       errx(1, "cannot use -Q option on remote media");
+#endif
                host = source;
                source = strchr(host, ':');
                *source++ = '\0';
@@ -2385,8 +2389,15 @@ GetTapePos(long *pos)
 {
        int err = 0;
 
-       *pos = 0;
-       if (ioctl(mt, MTIOCPOS, pos) == -1) {
+       if (magtapein) {
+               *pos = 0;
+               err = (ioctl(mt, MTIOCPOS, pos) < 0);
+       }
+       else {
+               *pos = lseek(mt, 0, SEEK_CUR);
+               err = (*pos < 0);
+       }
+       if (err) {
                err = errno;
                fprintf(stdout, "[%ld] error: %d (getting tapepos: %ld)\n", 
                        (unsigned long)getpid(), err, *pos);
@@ -2407,11 +2418,18 @@ int
 GotoTapePos(long pos)
 {
        int err = 0;
-       struct mt_pos buf;
 
-       buf.mt_op = MTSEEK;
-       buf.mt_count = pos;
-       if (ioctl(mt, MTIOCTOP, &buf) == -1) {
+       if (magtapein) {
+               struct mt_pos buf;
+               buf.mt_op = MTSEEK;
+               buf.mt_count = pos;
+               err = (ioctl(mt, MTIOCTOP, &buf) < 0);
+       }
+       else {
+               pos = lseek(mt, pos, SEEK_SET);
+               err = (pos < 0);
+       }
+       if (err) {
                err = errno;
                fprintf(stdout, "[%ld] error: %d (setting tapepos: %ld)\n", 
                        (unsigned long)getpid(), err, pos);