]> git.wh0rd.org - dump.git/commitdiff
QFA support.
authorStelian Pop <stelian@popies.net>
Tue, 10 Apr 2001 12:46:53 +0000 (12:46 +0000)
committerStelian Pop <stelian@popies.net>
Tue, 10 Apr 2001 12:46:53 +0000 (12:46 +0000)
16 files changed:
CHANGES
THANKS
config.h.in
configure
configure.in
dump/dump.8.in
dump/dump.h
dump/main.c
dump/tape.c
restore/extern.h
restore/main.c
restore/restore.8.in
restore/restore.c
restore/restore.h
restore/tape.c
restore/utilities.c

diff --git a/CHANGES b/CHANGES
index 942238c68e05cddd9ce0a2edda97cf7ef7985ce9..01d6b6736ebe5e707f5626fea8f7abd632266873 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-$Id: CHANGES,v 1.108 2001/04/06 10:09:39 stelian Exp $
+$Id: CHANGES,v 1.109 2001/04/10 12:46:53 stelian Exp $
 
 Changes between versions 0.4b21 and 0.4b22 (released ????????????????)
 ======================================================================
@@ -33,6 +33,15 @@ Changes between versions 0.4b21 and 0.4b22 (released ????????????????)
 6.     Made --prefix option work in configure. All the install path
        are now based on the configure parameters.
 
+7.     Added the Quick File Access mode in dump/restore, contributed
+       by Uwe Gohlke <uwe@ugsoft.de>. In this mode, dump stores in
+       a file tape position for each inode, and this file is used by 
+       restore (if called with parameter Q and the filename)
+       to directly position the tape at the file restore is currently 
+       working on.  This saves hours when restoring single files from
+       large backups, saves the tapes and the drive's head. Use
+       --enable-qfa option of configure to compile in the QFA support.
+
 Changes between versions 0.4b20 and 0.4b21 (released January 13, 2001)
 ======================================================================
 
diff --git a/THANKS b/THANKS
index 368b7719aefce3d5c62076e3554b34c880d1ba19..02c17e7c107f3f9266da2a76b38ac1210b5b5275 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -1,4 +1,4 @@
-$Id: THANKS,v 1.43 2001/02/22 10:57:39 stelian Exp $
+$Id: THANKS,v 1.44 2001/04/10 12:46:53 stelian Exp $
 
 Dump and restore were written by the people of the CSRG at the University
 of California, Berkeley.
@@ -36,6 +36,7 @@ Bernhard Erdmann      bernhard.erdmann@gmx.de
 Jason Fearon           jasonf@netrider.org.au
 Jeremy Fitzhardinge    jeremy@goop.org
 Eirik Fuller           eirik@netcom.com
+Uwe Gohlke             uwe@ugsoft.de
 Andreas Hasenack       andreas@conectiva.com.br
 Christian Haul         haul@informatik.tu-darmstadt.de
 Jean-Paul van der Jagt jeanpaul@dutepp0.et.tudelft.nl
index c08eced97e30c6f774e40887f3f6de9d134223ec..311292a82e9af5162b090a626b67e80262581cbe 100644 (file)
@@ -59,3 +59,9 @@
 
 /* Define this if you have zlib compression library */
 #undef HAVE_ZLIB
+
+/* Define this if you want Quick File Access support */
+#undef USE_QFA
+
+/* Define this if you want to include Quick File Access debugging code */
+#undef DEBUG_QFA
index 7b7fc23818c3c04bc8b5ee131235ce68aef326fd..b4ce3b2020538bd425a7f6c0556c88a320238dac 100755 (executable)
--- a/configure
+++ b/configure
@@ -25,6 +25,10 @@ ac_help="$ac_help
   --enable-oldstylefscript   enable old style F script (no arguments)"
 ac_help="$ac_help
   --enable-largefile         enable Large File System support (your glibc needs to support it)"
+ac_help="$ac_help
+  --enable-qfa               enable Quick File Access support"
+ac_help="$ac_help
+  --enable-qfadebug          include Quick File Access debugging code"
 ac_help="$ac_help
   --with-cc=COMPILER         select compiler to use"
 ac_help="$ac_help
@@ -564,7 +568,7 @@ MCONFIG=./MCONFIG
 
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:568: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:572: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -591,7 +595,7 @@ else
 fi
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:595: checking whether ln -s works" >&5
+echo "configure:599: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -614,7 +618,7 @@ fi
 # Extract the first word of "cp", so it can be a program name with args.
 set dummy cp; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:618: checking for $ac_word" >&5
+echo "configure:622: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_CP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -650,7 +654,7 @@ fi
 # Extract the first word of "mv", so it can be a program name with args.
 set dummy mv; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:654: checking for $ac_word" >&5
+echo "configure:658: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MV'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -686,7 +690,7 @@ fi
 # Extract the first word of "rm", so it can be a program name with args.
 set dummy rm; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:690: checking for $ac_word" >&5
+echo "configure:694: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_RM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -745,7 +749,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:749: checking host system type" >&5
+echo "configure:753: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -766,7 +770,7 @@ host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
 echo "$ac_t""$host" 1>&6
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:770: checking build system type" >&5
+echo "configure:774: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -792,7 +796,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:796: checking for $ac_word" >&5
+echo "configure:800: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -824,7 +828,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:828: checking for $ac_word" >&5
+echo "configure:832: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -859,7 +863,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:863: checking for $ac_word" >&5
+echo "configure:867: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -891,7 +895,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:895: checking for $ac_word" >&5
+echo "configure:899: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -926,7 +930,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}patch", so it can be a program name with args.
 set dummy ${ac_tool_prefix}patch; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:930: checking for $ac_word" >&5
+echo "configure:934: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_PATCH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -958,7 +962,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "patch", so it can be a program name with args.
 set dummy patch; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:962: checking for $ac_word" >&5
+echo "configure:966: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_PATCH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -993,7 +997,7 @@ fi
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:997: checking for $ac_word" >&5
+echo "configure:1001: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1023,7 +1027,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1027: checking for $ac_word" >&5
+echo "configure:1031: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1074,7 +1078,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1078: checking for $ac_word" >&5
+echo "configure:1082: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1106,7 +1110,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1110: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1114: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1117,12 +1121,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1121 "configure"
+#line 1125 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1126: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1148,12 +1152,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1152: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1156: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1157: checking whether we are using GNU C" >&5
+echo "configure:1161: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1162,7 +1166,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1170: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1181,7 +1185,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1185: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1189: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1224,7 +1228,7 @@ fi
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1228: checking for a BSD compatible install" >&5
+echo "configure:1232: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1409,6 +1413,40 @@ else
 fi
 
 
+# Check whether --enable-qfa or --disable-qfa was given.
+if test "${enable_qfa+set}" = set; then
+  enableval="$enable_qfa"
+  if test "$enableval" = "yes"
+then
+       cat >> confdefs.h <<\EOF
+#define USE_QFA 1
+EOF
+
+fi
+
+else
+  echo "Not enabling Quick File Access support"
+
+fi
+
+
+# Check whether --enable-qfadebug or --disable-qfadebug was given.
+if test "${enable_qfadebug+set}" = set; then
+  enableval="$enable_qfadebug"
+  if test "$enableval" = "yes"
+then
+       cat >> confdefs.h <<\EOF
+#define DEBUG_QFA 1
+EOF
+
+fi
+
+else
+  echo "Not including Quick File Access debugging code"
+
+fi
+
+
 # Check whether --with-cc or --without-cc was given.
 if test "${with_cc+set}" = set; then
   withval="$with_cc"
@@ -1539,7 +1577,7 @@ fi
 
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1543: checking how to run the C preprocessor" >&5
+echo "configure:1581: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1554,13 +1592,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1558 "configure"
+#line 1596 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1564: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1571,13 +1609,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1575 "configure"
+#line 1613 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1581: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1619: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1588,13 +1626,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1592 "configure"
+#line 1630 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1598: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1636: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1620,17 +1658,17 @@ echo "$ac_t""$CPP" 1>&6
 
 ac_safe=`echo "ext2fs/ext2fs.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for ext2fs/ext2fs.h""... $ac_c" 1>&6
-echo "configure:1624: checking for ext2fs/ext2fs.h" >&5
+echo "configure:1662: checking for ext2fs/ext2fs.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1629 "configure"
+#line 1667 "configure"
 #include "confdefs.h"
 #include <ext2fs/ext2fs.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1634: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1672: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1653,7 +1691,7 @@ ext2fs_h=no
 fi
 
 echo $ac_n "checking for ext2fs_open in -lext2fs""... $ac_c" 1>&6
-echo "configure:1657: checking for ext2fs_open in -lext2fs" >&5
+echo "configure:1695: checking for ext2fs_open in -lext2fs" >&5
 ac_lib_var=`echo ext2fs'_'ext2fs_open | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1661,7 +1699,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lext2fs -lcom_err $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1665 "configure"
+#line 1703 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1672,7 +1710,7 @@ int main() {
 ext2fs_open()
 ; return 0; }
 EOF
-if { (eval echo configure:1676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1698,9 +1736,9 @@ if test "$ext2fs_h" = no -o "$ext2fs_lib" = no; then
 fi
 
 echo $ac_n "checking for ext2_ino_t type in libext2fs headers""... $ac_c" 1>&6
-echo "configure:1702: checking for ext2_ino_t type in libext2fs headers" >&5
+echo "configure:1740: checking for ext2_ino_t type in libext2fs headers" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1704 "configure"
+#line 1742 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <linux/ext2_fs.h>
@@ -1709,7 +1747,7 @@ int main() {
 ext2_ino_t ino = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1713: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_EXT2_INO_T 1
@@ -1724,9 +1762,9 @@ fi
 rm -f conftest*
 
 echo $ac_n "checking for s_journal_inum field in ext2_super_block struct""... $ac_c" 1>&6
-echo "configure:1728: checking for s_journal_inum field in ext2_super_block struct" >&5
+echo "configure:1766: checking for s_journal_inum field in ext2_super_block struct" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1730 "configure"
+#line 1768 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <linux/ext2_fs.h>
@@ -1735,7 +1773,7 @@ int main() {
 struct ext2_super_block es; es.s_journal_inum = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1739: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   cat >> confdefs.h <<\EOF
 #define HAVE_EXT2_JOURNAL_INUM 1
@@ -1750,7 +1788,7 @@ fi
 rm -f conftest*
 
 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
-echo "configure:1754: checking for tgetent in -ltermcap" >&5
+echo "configure:1792: checking for tgetent in -ltermcap" >&5
 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1758,7 +1796,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ltermcap  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1762 "configure"
+#line 1800 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1769,7 +1807,7 @@ int main() {
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:1773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1798,17 +1836,17 @@ fi
 
 ac_safe=`echo "readline/readline.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for readline/readline.h""... $ac_c" 1>&6
-echo "configure:1802: checking for readline/readline.h" >&5
+echo "configure:1840: checking for readline/readline.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1807 "configure"
+#line 1845 "configure"
 #include "confdefs.h"
 #include <readline/readline.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1831,7 +1869,7 @@ readline_h=no
 fi
 
 echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:1835: checking for readline in -lreadline" >&5
+echo "configure:1873: checking for readline in -lreadline" >&5
 ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1839,7 +1877,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lreadline "-ltermcap" $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1843 "configure"
+#line 1881 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1850,7 +1888,7 @@ int main() {
 readline()
 ; return 0; }
 EOF
-if { (eval echo configure:1854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1879,17 +1917,17 @@ fi
 
 ac_safe=`echo "zlib.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for zlib.h""... $ac_c" 1>&6
-echo "configure:1883: checking for zlib.h" >&5
+echo "configure:1921: checking for zlib.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1888 "configure"
+#line 1926 "configure"
 #include "confdefs.h"
 #include <zlib.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1893: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1931: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1912,7 +1950,7 @@ zlib_h=no
 fi
 
 echo $ac_n "checking for compress2 in -lz""... $ac_c" 1>&6
-echo "configure:1916: checking for compress2 in -lz" >&5
+echo "configure:1954: checking for compress2 in -lz" >&5
 ac_lib_var=`echo z'_'compress2 | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1920,7 +1958,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lz  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1924 "configure"
+#line 1962 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1931,7 +1969,7 @@ int main() {
 compress2()
 ; return 0; }
 EOF
-if { (eval echo configure:1935: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1966,12 +2004,12 @@ fi
 for ac_func in err errx verr verrx vwarn vwarnx warn warnx realpath lchown
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1970: checking for $ac_func" >&5
+echo "configure:2008: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1975 "configure"
+#line 2013 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1994,7 +2032,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2019,12 +2057,12 @@ fi
 done
 
 echo $ac_n "checking for glob""... $ac_c" 1>&6
-echo "configure:2023: checking for glob" >&5
+echo "configure:2061: checking for glob" >&5
 if eval "test \"`echo '$''{'ac_cv_func_glob'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2028 "configure"
+#line 2066 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char glob(); below.  */
@@ -2047,7 +2085,7 @@ glob();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_glob=yes"
 else
@@ -2068,10 +2106,10 @@ fi
 
 
 echo $ac_n "checking for extended glob routines""... $ac_c" 1>&6
-echo "configure:2072: checking for extended glob routines" >&5
+echo "configure:2110: checking for extended glob routines" >&5
 if test "$ac_cv_func_glob" = "yes"; then
        cat > conftest.$ac_ext <<EOF
-#line 2075 "configure"
+#line 2113 "configure"
 #include "confdefs.h"
 
 #      include <glob.h>
@@ -2102,12 +2140,12 @@ rm -f conftest*
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2106: checking for ANSI C header files" >&5
+echo "configure:2144: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2111 "configure"
+#line 2149 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2115,7 +2153,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2119: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2132,7 +2170,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2136 "configure"
+#line 2174 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2150,7 +2188,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2154 "configure"
+#line 2192 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2171,7 +2209,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2175 "configure"
+#line 2213 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2182,7 +2220,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:2186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2206,12 +2244,12 @@ EOF
 fi
 
 echo $ac_n "checking for quad_t""... $ac_c" 1>&6
-echo "configure:2210: checking for quad_t" >&5
+echo "configure:2248: checking for quad_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_quad_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2215 "configure"
+#line 2253 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2239,12 +2277,12 @@ EOF
 fi
 
 echo $ac_n "checking for u_quad_t""... $ac_c" 1>&6
-echo "configure:2243: checking for u_quad_t" >&5
+echo "configure:2281: checking for u_quad_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_quad_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2248 "configure"
+#line 2286 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
index 6f8e57b99a150cdd8fad9212e72af0d6284c811a..b5dd89cf92e2a5a2e5979bcd3e12378d0181c9a5 100644 (file)
@@ -135,6 +135,32 @@ fi
 echo "Not enabling Large File System support"
 )
 
+dnl
+dnl Handle --enable-qfa
+dnl
+AC_ARG_ENABLE([qfa],
+[  --enable-qfa               enable Quick File Access support],
+if test "$enableval" = "yes"
+then
+       AC_DEFINE(USE_QFA)
+fi
+,
+echo "Not enabling Quick File Access support"
+)
+
+dnl
+dnl Handle --enable-qfadebug
+dnl
+AC_ARG_ENABLE([qfadebug],
+[  --enable-qfadebug          include Quick File Access debugging code],
+if test "$enableval" = "yes"
+then
+       AC_DEFINE(DEBUG_QFA)
+fi
+,
+echo "Not including Quick File Access debugging code"
+)
+
 dnl
 dnl set $(CC) from --with-cc=value
 dnl
index 52b8713a98ae8ea4f5796af3ce05588aed03bf97..e16204696be9b56b3435ea5f929f62d6db6ad372 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.24 2001/03/28 12:59:48 stelian Exp $
+.\"    $Id: dump.8.in,v 1.25 2001/04/10 12:46:53 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt DUMP 8
@@ -49,6 +49,7 @@
 .Op Fl F Ar script
 .Op Fl h Ar level
 .Op Fl L Ar label
+.Op Fl Q Ar file
 .Op Fl s Ar feet
 .Op Fl T Ar date
 .Op Fl z Ar compression level
@@ -239,6 +240,14 @@ notify all operators in the group
 .Dq operator
 by means similar to a
 .Xr wall 1 .
+.It Fl Q Ar file
+Enable the Quick File Access support. Tape positions for each
+inode are stored into the file
+.Ar file
+which is used by restore (if called with parameter Q and the filename)
+to directly position the tape at the file restore is currently working
+on.  This saves hours when restoring single files from large backups,
+saves the tapes and the drive's head.
 .It Fl s Ar feet
 Attempt to calculate the amount of tape needed at a particular density.
 If this amount is exceeded,
index 5485ec4a3bd2b1454c8dacee4016d5ff113782e1..8235858b0bc916b4ee03dbecb9c91a84381d2abe 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <pop@noos.fr>, 1999-2000
  *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  *
- *     $Id: dump.h,v 1.22 2001/03/20 10:02:48 stelian Exp $
+ *     $Id: dump.h,v 1.23 2001/04/10 12:46:53 stelian Exp $
  */
 
 /*-
@@ -107,6 +107,15 @@ long       dev_bsize;      /* block size of underlying disk device */
 int    dev_bshift;     /* log2(dev_bsize) */
 int    tp_bshift;      /* log2(TP_BSIZE) */
 
+#ifdef USE_QFA
+#define        QFA_MAGIC       "495115637697"
+#define QFA_VERSION    "1.0"
+int    gTapeposfd;
+char   *gTapeposfile;
+char   gTps[255];
+int    GetTapePos __P((long *pos));
+#endif /* USE_QFA */
+
 #ifndef __P
 #include <sys/cdefs.h>
 #endif
index b032334d22ebd824dfb19d88d5455cc716877c9d..272d5978a29bd7adc631f902195f0fb8467e91cc 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.41 2001/03/28 12:59:48 stelian Exp $";
+       "$Id: main.c,v 1.42 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -89,6 +89,9 @@ int   tapeno = 0;     /* current tape number */
 int    density = 0;    /* density in bytes/0.1" " <- this is for hilit19 */
 int    ntrec = NTREC;  /* # tape blocks in each tape record */
 int    cartridge = 0;  /* Assume non-cartridge tape */
+#ifdef USE_QFA
+int    tapepos = 0;    /* assume no QFA tapeposition needed by user */
+#endif /* USA_QFA */
 int    dokerberos = 0; /* Use Kerberos authentication */
 long   dev_bsize = 1;  /* recalculated below */
 long   blocksperfile;  /* output blocks per file */
@@ -153,17 +156,24 @@ main(int argc, char *argv[])
 
        obsolete(&argc, &argv);
 
+#ifdef USE_QFA
+       gTapeposfd = -1;
+#endif /* USA_QFA */
+
        while ((ch = getopt(argc, argv,
                            "0123456789aB:b:cd:e:f:F:h:L:"
 #ifdef KERBEROS
                            "k"
 #endif
-                           "Mns:ST:uWw"
+                           "Mn"
+#ifdef USE_QFA
+                           "Q:"
+#endif
+                           "s:ST:uWw"
 #ifdef HAVE_ZLIB
                            "z::"
 #endif
                            )) != -1)
-#undef optstring
                switch (ch) {
                /* dump level */
                case '0': case '1': case '2': case '3': case '4':
@@ -262,6 +272,13 @@ main(int argc, char *argv[])
                        notify = 1;
                        break;
 
+#ifdef USE_QFA
+               case 'Q':               /* create tapeposfile */
+                       gTapeposfile = optarg;
+                       tapepos = 1;
+                       break;
+#endif /* USA_QFA */
+                       
                case 's':               /* tape size, feet */
                        unlimited = 0;
                        tsize = numarg("tape size", 1L, 0L) * 12 * 10;
@@ -646,6 +663,21 @@ main(int argc, char *argv[])
                    tapesize, fetapes);
        }
 
+#ifdef USE_QFA
+       if (tapepos) {
+               msg("writing QFA positions to %s\n", gTapeposfile);
+               if ((gTapeposfd = open(gTapeposfile, O_RDWR|O_CREAT)) < 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);
+               if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
+                       quit("can't write tapeposfile\n");
+               sprintf(gTps, "ino\ttapeno\ttapepos\n");
+               if (write(gTapeposfd, gTps, strlen(gTps)) != strlen(gTps))
+                       quit("can't write tapeposfile\n");
+       }
+#endif /* USE_QFA */
+
        /*
         * Allocate tape buffer.
         */
@@ -778,8 +810,12 @@ usage(void)
                "k"
 #endif
                "MnSu"
-               "] [-B records] [-b blocksize]\n"
-               "\t%s [-d density] [-e inode#] [-f file] [-h level] [-s feet]\n"
+               "] [-B records] [-b blocksize] [-d density]\n"
+               "\t%s [-e inode#] [-f file] [-h level] "
+#ifdef USE_QFA
+               "[-Q file] "
+#endif
+               "[-s feet]\n"
                "\t%s [-T date] "
 #ifdef HAVE_ZLIB
                "[-z zlevel] "
@@ -891,6 +927,7 @@ obsolete(int *argcp, char **argvp[])
                case 'F':
                case 'h':
                case 'L':
+               case 'Q':
                case 's':
                case 'T':
                        if (*argv == NULL) {
index 890c77b8e3ed6f93d53412706ddd09fe56e2a15e..8c62acb487131841c6ac2db4bdfc01fa627efed5 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.40 2001/03/28 12:59:48 stelian Exp $";
+       "$Id: tape.c,v 1.41 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -68,6 +68,7 @@ int    write(), read();
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <sys/mtio.h>
 #ifdef __linux__
 #include <linux/ext2_fs.h>
 #include <ext2fs/ext2fs.h>
@@ -158,6 +159,9 @@ static int ready;   /* have we reached the lock point without having */
                        /* received the SIGUSR2 signal from the prev slave? */
 static sigjmp_buf jmpbuf;      /* where to jump to if we are ready when the */
                        /* SIGUSR2 arrives from the previous slave */
+#ifdef USE_QFA
+static int gtperr = 0;
+#endif
 
 int
 alloctape(void)
@@ -860,7 +864,7 @@ restore_check_point:
                        open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
 #else
                while ((tapefd = (pipeout ? fileno(stdout) :
-                                 open(tape, O_WRONLY|O_CREAT, 0666))) < 0)
+                                 open(tape, O_RDWR|O_CREAT, 0666))) < 0)
 #endif
                    {
                        msg("Cannot open output \"%s\".\n", tape);
@@ -1046,6 +1050,11 @@ doslave(int cmd, int slave_number)
 #ifdef __linux__
        errcode_t retval;
 #endif
+#ifdef USE_QFA
+       long curtapepos;
+       union u_spcl *uspclptr;
+       struct s_spcl *spclptr;
+#endif /* USA_QFA */
 
        /*
         * Need our own seek pointer.
@@ -1097,6 +1106,29 @@ doslave(int cmd, int slave_number)
                        }
                }
 
+#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)) {
+                                                       quit("error writing tapepos file.\n");
+                                               }
+                                       }
+                               }
+                       }
+               }
+#endif /* USE_QFA */
+                                               
                /* Try to write the data... */
                wrote = 0;
                eot_count = 0;
@@ -1240,3 +1272,24 @@ atomic_write(int fd, const void *buf, size_t count)
        } while (got == -1 && errno == EINTR);
        return (got < 0 ? got : count - need);
 }
+
+
+#ifdef USE_QFA
+/*
+ * read the current tape position
+ */
+int
+GetTapePos(long *pos)
+{
+       int err = 0;
+
+       *pos = 0;
+       if (ioctl(tapefd, MTIOCPOS, pos) == -1) {
+               err = errno;
+               msg("[%ld] error: %d (getting tapepos: %ld)\n", getpid(), 
+                       err, *pos);
+               return err;
+       }
+       return err;
+}
+#endif /* USE_QFA */
index e63a136c01086f6cf3d0fc6b68c26ed7abc76926..c985c20f92006cd748d66a4abeb5ec8534be4aa5 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <pop@noos.fr>, 1999-2000
  *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  *
- *     $Id: extern.h,v 1.12 2001/03/20 10:02:48 stelian Exp $
+ *     $Id: extern.h,v 1.13 2001/04/10 12:46:53 stelian Exp $
  */
 
 /*-
@@ -125,3 +125,11 @@ int                rmtseek __P((int, int));
 int fsetflags __P((const char *, unsigned long));
 int fgetflags __P((const char *, unsigned long *));
 int setflags __P((int, unsigned long));
+
+#ifdef USE_QFA
+int    Inode2Tapepos __P((dump_ino_t, long *, long *, int));
+int    GetTapePos __P((long *));
+int    GotoTapePos __P((long));
+void   ReReadFromTape __P((void));
+void   RequestVol __P((long));
+#endif
index fd002258af1aac06b90d532522ee1df429498f6a..8911d2069475a9366848a7644d17324f7db88d88 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: main.c,v 1.19 2001/03/23 14:40:12 stelian Exp $";
+       "$Id: main.c,v 1.20 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -115,6 +115,10 @@ main(int argc, char *argv[])
        char *p, name[MAXPATHLEN];
        FILE *filelist = NULL;
        char fname[MAXPATHLEN];
+#ifdef USE_QFA
+       time_t tistart, tiend, titaken;
+       tapeposflag = 0;
+#endif
 
        /* Temp files should *not* be readable.  We set permissions later. */
        (void) umask(077);
@@ -135,12 +139,16 @@ main(int argc, char *argv[])
        for (p = tmpdir + strlen(tmpdir) - 1; p >= tmpdir && *p == '/'; p--)
                ;                                                               
        obsolete(&argc, &argv);
+       while ((ch = getopt(argc, argv, 
+               "b:CcdD:f:hi"
 #ifdef KERBEROS
-#define        optlist "b:CcdD:f:hikmMNRrs:tT:uvxX:y"
-#else
-#define        optlist "b:CcdD:f:himMNRrs:tT:uvxX:y"
+               "k"
+#endif
+               "mMN"
+#ifdef USE_QFA
+               "Q:"
 #endif
-       while ((ch = getopt(argc, argv, optlist)) != -1)
+               "Rrs:tT:uvxX:y")) != -1)
                switch(ch) {
                case 'b':
                        /* Change default tape blocksize. */
@@ -198,6 +206,12 @@ main(int argc, char *argv[])
                case 'N':
                        Nflag = 1;
                        break;
+#ifdef USE_QFA
+               case 'Q':
+                       gTapeposfile = optarg;
+                       tapeposflag = 1;
+                       break;
+#endif
                case 's':
                        /* Dumpnum (skip to) for multifile dump tapes. */
                        dumpnum = strtol(optarg, &p, 10);
@@ -248,6 +262,45 @@ main(int argc, char *argv[])
                *--argv = ".";
        }
 
+#ifdef USE_QFA
+       if (tapeposflag) {
+               msg("reading QFA positions from %s\n", gTapeposfile);
+               if ((gTapeposfp = fopen(gTapeposfile, "r")) == NULL)
+                       errx(1, "can't open file for reading -- %s",
+                               gTapeposfile);
+               /* start reading header info */
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               gTps[strlen(gTps) - 1] = 0;     /* delete end of line */
+               if (strcmp(gTps, QFA_MAGIC) != 0)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               gTps[strlen(gTps) - 1] = 0;
+               if (strcmp(gTps, QFA_VERSION) != 0)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               /* read dumpdate */
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               gTps[strlen(gTps) - 1] = 0;
+               /* TODO: check dumpdate from QFA file with current dump file's
+                * dump date */
+               /* if not equal either output warning and continue without QFA
+                * or abort */
+               /* read empty line */
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               gTps[strlen(gTps) - 1] = 0;
+               /* read table header line */
+               if (fgets(gTps, sizeof(gTps), gTapeposfp) == NULL)
+                       errx(1, "not requested format of -- %s", gTapeposfile);
+               gTps[strlen(gTps) - 1] = 0;
+               /* end reading header info */
+               /* tape position table starts here */
+               gSeekstart = ftell(gTapeposfp); /* remember for later use */
+}
+#endif /* USE_QFA */
+
        switch (command) {
        /*
         * Compare contents of tape.
@@ -375,6 +428,9 @@ main(int argc, char *argv[])
         * Batch extraction of tape contents.
         */
        case 'x':
+#ifdef USE_QFA
+               tistart = time(NULL);
+#endif
                setup();
                extractdirs(1);
                initsymtable((char *)0);
@@ -395,6 +451,14 @@ main(int argc, char *argv[])
                setdirmodes(0);
                if (dflag)
                        checkrestore();
+#ifdef USE_QFA
+               tiend = time(NULL);
+               titaken = tiend - tistart;
+#ifdef USE_QFA
+               msg("restore took %d:%02d:%02d\n", titaken / 3600, 
+                       (titaken % 3600) / 60, titaken % 60);
+#endif
+#endif
                break;
        }
        exit(0);
@@ -464,6 +528,7 @@ obsolete(int *argcp, char **argvp[])
                case 'b':
                case 'D':
                case 'f':
+               case 'Q':
                case 's':
                case 'T':
                case 'X':
index 7903d7e5e5f2455322c0670f4346ca121479a9bf..441fec41f15d68d76a18dfe4f27a1a3c9f5d8a4b 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.12 2001/03/23 14:40:12 stelian Exp $
+.\"    $Id: restore.8.in,v 1.13 2001/04/10 12:46:53 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt RESTORE 8
@@ -44,6 +44,7 @@
 .Op Fl b Ar blocksize
 .Op Fl D Ar filesystem
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Nm restore
@@ -51,6 +52,7 @@
 .Op Fl chkmMNuvy
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Nm restore
@@ -58,6 +60,7 @@
 .Op Fl ckMNuvy
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Nm restore
@@ -65,6 +68,7 @@
 .Op Fl ckMNuvy
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Nm restore
@@ -72,6 +76,7 @@
 .Op Fl chkMNuvy
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Op Fl X Ar filelist
@@ -81,6 +86,7 @@
 .Op Fl chkmMNuvy
 .Op Fl b Ar blocksize
 .Op Fl f Ar file
+.Op Fl Q Ar file
 .Op Fl s Ar fileno
 .Op Fl T Ar directory
 .Op Fl X Ar filelist
@@ -364,6 +370,11 @@ The
 flag causes
 .Nm
 to only print file names. Files are not extracted.
+.It Fl Q Ar file
+Use the file
+.Ar file
+in order to read tape position as stored using the dump Quick File
+Access mode.
 .It Fl s Ar fileno
 Read from the specified
 .Ar fileno
index bc38b655874b148c8e78f347a4ab8e5a6a287642..86152040d158624e53693f007a812f138f7f6990 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: restore.c,v 1.14 2001/03/20 10:02:48 stelian Exp $";
+       "$Id: restore.c,v 1.15 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -76,11 +76,23 @@ long
 listfile(char *name, dump_ino_t ino, int type)
 {
        long descend = hflag ? GOOD : FAIL;
+#ifdef USE_QFA
+       long tnum;
+       long tpos;
+#endif
 
        if (TSTINO(ino, dumpmap) == 0)
                return (descend);
        Vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir ");
-       fprintf(stdout, "%10lu\t%s\n", (unsigned long)ino, name);
+#ifdef USE_QFA
+       if (tapeposflag) {      /* add QFA positions to output */
+               (void)Inode2Tapepos(ino, &tnum, &tpos, 1);
+               fprintf(stdout, "%10lu\t%ld\t%ld\t%s\n", (unsigned long)ino, 
+                       tnum, tpos, name);
+       }
+       else
+#endif
+               fprintf(stdout, "%10lu\t%s\n", (unsigned long)ino, name);
        return (descend);
 }
 
@@ -782,6 +794,10 @@ createfiles(void)
        register dump_ino_t first, next, last;
        register struct entry *ep;
        long curvol;
+#ifdef USE_QFA
+       long tnum, tpos, curtpos, tmpcnt;
+       time_t tistart, tiend, titaken;
+#endif
 
        Vprintf(stdout, "Extract requested files\n");
        curfile.action = SKIP;
@@ -791,6 +807,9 @@ createfiles(void)
        first = lowerbnd(ROOTINO);
        last = upperbnd(maxino - 1);
        for (;;) {
+#ifdef USE_QFA
+               tmpcnt = 1;
+#endif
                first = lowerbnd(first);
                last = upperbnd(last);
                /*
@@ -814,13 +833,64 @@ createfiles(void)
                 * or an out of order volume change is encountered
                 */
                next = lowerbnd(curfile.ino);
+#ifdef USE_QFA
+               tistart = time(NULL);
+               if (tapeposflag) {
+                       /* get tape position for inode (position directly) */
+                       (void)Inode2Tapepos(next, &tnum, &tpos, 1);
+                       if (tpos == 0)
+                               /* get tape position for last available inode
+                                * (position before) */
+                               (void)Inode2Tapepos(next, &tnum, &tpos, 0);
+                       if (tpos != 0) {
+                               if (tnum != volno)
+                                       (void)RequestVol(tnum);
+                               if (GetTapePos(&curtpos) == 0) {
+                                       /*  curtpos +1000 ???, some drives 
+                                        *  might be too slow */
+                                       if (tpos > curtpos) {
+#ifdef DEBUG_QFA
+                                               msg("positioning tape %ld from %ld to %ld for inode %10lu ...\n", volno, curtpos, tpos, (unsigned long)next);
+#endif
+                                               if (GotoTapePos(tpos) == 0) {
+#ifdef DEBUG_QFA
+                                                       if (GetTapePos(&curtpos) == 0)
+                                                               msg("before resnyc at tape position %ld\n", curtpos);
+#endif
+                                                       (void)ReReadFromTape();
+#ifdef DEBUG_QFA
+                                                       if (GetTapePos(&curtpos) == 0)
+                                                               msg("after resync at tape position %ld\n", curtpos);
+#endif
+                                               }
+                                       }
+                               }
+                       }
+               }
+#endif /* USA_QFA */
+
                do      {
                        curvol = volno;
-                       while (next > curfile.ino && volno == curvol)
+                       while (next > curfile.ino && volno == curvol) {
+#ifdef USE_QFA
+                               ++tmpcnt;
+#endif
                                skipfile();
+                       }
                        skipmaps();
                        skipdirs();
                } while (volno == curvol + 1);
+#ifdef USE_QFA
+               tiend = time(NULL);
+               titaken = tiend - tistart;
+#ifdef DEBUG_QFA
+               if (titaken / 60 > 0)
+                       msg("%ld reads took %d:%02d:%02d\n", 
+                               tmpcnt, titaken / 3600, 
+                               (titaken % 3600) / 60, titaken % 60);
+#endif
+#endif /* USE_QFA */
+
                /*
                 * If volume change out of order occurred the
                 * current state must be recalculated
index 6c77e5afd5dda49bffef0935c3d22f73d96b16b2..dba1ddcdf6a4f2cff466e3ad4af89a2a0ee1810d 100644 (file)
@@ -5,7 +5,7 @@
  *     Stelian Pop <pop@noos.fr>, 1999-2000
  *     Stelian Pop <pop@noos.fr> - AlcĂ´ve <www.alcove.fr>, 2000
  *
- *     $Id: restore.h,v 1.14 2001/03/20 10:02:48 stelian Exp $
+ *     $Id: restore.h,v 1.15 2001/04/10 12:46:53 stelian Exp $
  */
 
 /*
@@ -161,3 +161,13 @@ typedef struct rstdirdesc RST_DIR;
 
 #define GOOD 1
 #define FAIL 0
+
+#ifdef USE_QFA
+#define QFA_MAGIC      "495115637697"
+#define QFA_VERSION    "1.0"
+FILE   *gTapeposfp;
+char   *gTapeposfile;
+char   gTps[255];
+long   gSeekstart;
+int    tapeposflag;
+#endif /* USE_QFA */
index 63eae65ef23cf95a29dd747bed9f3e0a08496bd2..f434143116847216ceee0722e32be8921117cc86 100644 (file)
@@ -46,7 +46,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.31 2001/03/27 08:09:21 stelian Exp $";
+       "$Id: tape.c,v 1.32 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -82,6 +82,9 @@ static const char rcsid[] =
 #include "extern.h"
 #include "pathnames.h"
 
+#ifdef USE_QFA
+int            noresyncmesg = 0;
+#endif /* USE_QFA */
 static long    fssize = MAXBSIZE;
 static int     mt = -1;
 static int     pipein = 0;
@@ -2095,8 +2098,11 @@ findinode(struct s_spcl *header)
                }
        } while (header->c_type == TS_ADDR);
        if (skipcnt > 0)
-               fprintf(stderr, "resync restore, skipped %ld blocks\n",
-                   skipcnt);
+#ifdef USE_QFA
+               if (!noresyncmesg)
+#endif
+                       fprintf(stderr, "resync restore, skipped %ld blocks\n",
+                               skipcnt);
        skipcnt = 0;
 }
 
@@ -2250,3 +2256,72 @@ swabl(u_long x)
        return (x);
 }
 #endif
+
+#ifdef USE_QFA
+/*
+ * get the current position of the tape
+ */
+int
+GetTapePos(long *pos)
+{
+       int err = 0;
+
+       *pos = 0;
+       if (ioctl(mt, MTIOCPOS, pos) == -1) {
+               err = errno;
+               fprintf(stdout, "[%ld] error: %d (getting tapepos: %ld)\n", 
+                       (unsigned long)getpid(), err, *pos);
+               return err;
+       }
+       return err;
+}
+
+typedef struct mt_pos {
+       short    mt_op;
+       int      mt_count;
+} MTPosRec, *MTPosPtr;
+
+/*
+ * go to specified position on tape
+ */
+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) {
+               err = errno;
+               fprintf(stdout, "[%ld] error: %d (setting tapepos: %ld)\n", 
+                       (unsigned long)getpid(), err, pos);
+               return err;
+       }
+       return err;
+}
+
+/*
+ * read next data from tape to re-sync
+ */
+void
+ReReadFromTape(void)
+{
+       FLUSHTAPEBUF();
+       noresyncmesg = 1;
+       if (gethead(&spcl) == FAIL) {
+#ifdef DEBUG_QFA
+               fprintf(stdout, "DEBUG 1 gethead failed\n");
+#endif
+       }
+       findinode(&spcl);
+       noresyncmesg = 0;
+}
+
+void
+RequestVol(long tnum)
+{
+       FLUSHTAPEBUF();
+       getvol(tnum);
+}
+#endif /* USE_QFA */
index 34f9f8d7f14c4f8bba849178577088e708d0d6c3..e2bf2e2682f955f18df33bc80661ab32ab53f1ee 100644 (file)
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: utilities.c,v 1.13 2001/03/20 10:02:48 stelian Exp $";
+       "$Id: utilities.c,v 1.14 2001/04/10 12:46:53 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -465,3 +465,76 @@ panic(fmt, va_alist)
                exit(1);
        }
 }
+
+#ifdef USE_QFA
+/*
+ * search for ino in QFA file
+ *
+ * if exactmatch:
+ * if ino found return tape number and tape position
+ * if ino not found return tnum=0 and tpos=0
+ *
+ * if not exactmatch:
+ * if ino found return tape number and tape position
+ * if ino not found return tape number and tape position of last smaller ino
+ * if no smaller inode found return tnum=0 and tpos=0
+ */
+int
+Inode2Tapepos(dump_ino_t ino, long *tnum, long *tpos, int exactmatch)
+{
+       char *p, *pp;
+       char numbuff[32];
+       unsigned long tmpino;
+       long tmptnum;
+       long tmptpos;
+
+       *tpos = 0;
+       *tnum = 0;
+       if (fseek(gTapeposfp, gSeekstart, SEEK_SET) == -1)
+               return errno;
+       while (fgets(gTps, sizeof(gTps), gTapeposfp) != NULL) {
+               gTps[strlen(gTps) - 1] = 0;     /* delete end of line */
+               p = gTps;
+               bzero(numbuff, sizeof(numbuff));
+               pp = numbuff;
+               /* read inode */
+               while ((*p != 0) && (*p != '\t'))
+                       *pp++ = *p++;
+               tmpino = atol(numbuff);
+               if (*p == 0)
+                       return 1;       /* may NOT happen */    
+               p++;
+               bzero(numbuff, sizeof(numbuff));
+               pp = numbuff;
+               /* read tapenum */
+               while ((*p != 0) && (*p != '\t'))
+                       *pp++ = *p++;
+               if (*p == 0)
+                       return 1;       /* may NOT happen */    
+               tmptnum = atol(numbuff);
+               p++;
+               bzero(numbuff, sizeof(numbuff));
+               pp = numbuff;
+               /* read tapepos */
+               while ((*p != 0) && (*p != '\t'))
+                       *pp++ = *p++;
+               tmptpos = atol(numbuff);
+
+               if (exactmatch) {
+                       if (tmpino == ino)  {
+                               *tnum = tmptnum;
+                               *tpos = tmptpos;
+                               return 0;
+                       }
+               } else {
+                       if (tmpino > ino)  {
+                               return 0;
+                       } else {
+                               *tnum = tmptnum;
+                               *tpos = tmptpos;
+                       }
+               }
+       }
+       return 0;
+}
+#endif /* USE_QFA */