-$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 ???????????????)
=====================================================================
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)
=====================================================================
.\" 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
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,
* 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 $
*/
/*-
extern char *gTapeposfile;
extern char gTps[255];
extern int32_t gThisDumpDate;
-int GetTapePos __P((long *pos));
#endif /* USE_QFA */
#ifndef __P
#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>
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");
#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");
#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>
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 *));
+static void MkTapeString __P((struct s_spcl *, long));
+#endif
/*
* Concurrent dump mods (Caltech) - disk block reading and tape writing
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 */
#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);
}
}
}
/*
* 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);
}
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 */
#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>
case 'Q':
gTapeposfile = optarg;
tapeposflag = 1;
+ aflag = 1;
break;
#endif
case 's':
.\" 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
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
#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>
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);
#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>
#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';
{
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);
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);