chiark / gitweb /
@@ -1,3 +1,10 @@
[chiark-utils.git] / backup / increm
index 1d2aaa774afe6633558af65fdd5665ae0ad25f59..945bb0e5dec5118b1e561be5a5f6fdb62b9da61a 100755 (executable)
@@ -1,7 +1,34 @@
 #!/usr/bin/perl
+# increm
+# Do an incremental backup; ONLY for invocation by full !
+#
+# This file is part of chiark backup, a system for backing up GNU/Linux and
+# other UN*X-compatible machines, as used on chiark.greenend.org.uk.
+#
+# chiark backup is:
+#  Copyright (C) 1997-1998,2000-2001 Ian Jackson <ian@chiark.greenend.org.uk>
+#  Copyright (C) 1999 Peter Maydell <pmaydell@chiark.greenend.org.uk>
+#
+# This is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2, or (at your option) any later version.
+#
+# This is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# We are invoked by full if the tape description file says that it is
+# for an incremental backup.  We expect two commandline argument which
+# is the ID string of the tape to use, and the description (which
+# includes ID and function).
 
 BEGIN {
-    $etc= '/etc/backup';
+    $etc= '/etc/chiark-backup';
     require "$etc/settings.pl";
     require 'backuplib.pl';
 }
@@ -13,69 +40,107 @@ $|=1;
 
 print "Running incremental onto $tapedesc ...\n" or die $!;
 
+# Just check that we weren't passed a bogus ID (the tape description
+# file for incrementals is just 'incremental\nend\n')
 open T,"$etc/tape.$tapeid" or die "Tape $tapeid not found: $!\n";
 close T;
 
+# This is only used for the 'next FULL backup is X' message at the end.
 open NF,"next-full" or die $!;
 chomp($next= <NF>);
 close NF or die $!;
 
 setstatus "FAILED during incremental";
 
+# Read the number of the incremental involved
+# (ie, (how many files are already on the tape) - 1)
 open A,"increm-advance" or die $!;
 chomp($advance= <A>);
 close A or die $!;
 
+# better be a decimal number
 $advance =~ m/^\d+$/ or die "$advance ?";
 
-system "mt -f $ntape rewind"; $? and die $?;
-if ($advance == 1) {
-    open TI,">TAPEID" or die $!;
-    print TI "$tapeid\n$tapedesc\n" or die $!;
-    close TI or die $!;
+# Get a list of all filesystems
+readfsys('all');
+openlog();
 
-    system "tar -b$blocksize -vvcf TAPEID.tar TAPEID"; $? and die $?;
-    system "dd if=TAPEID.tar of=$ntape bs=${blocksize}b count=10"; $? and die $?;
+# Rewind the tape and if we are the first incremental on the tape then
+# write the TAPEID record, otherwise skip forward to the correct point.
+# (full will already have checked that this is the right tape before
+# it invoked us, so no need to read the existing TAPEID record first.)
+runsystem("mt -f $ntape rewind");
+if ($advance == 1) {
+    writetapeid($tapeid,$tapedesc);
 } else {
-    system "mt -f $ntape fsf $advance"; $? and die $?;
+    runsystem("mt -f $ntape fsf $advance");
+    $currenttapefilenumber= $advance;
 }
 
-readfsys('all');
-openlog();
-
 sub closepipes () {
     close(DUMPOR); close(BUFOR);
     close(DUMPOW); close(BUFOW);
+    close(GZOR); close(GZOW);
 }
 
 setstatus "PROBLEMS during incremental dump";
 
 for $tf (@fsys) {
+
+    parsefsys();
+    prepfsys();
+    
+    $bufir='DUMPOR';
+    $ddcmd= "$nasty dd ibs=$softblocksizebytes obs=$blocksizebytes of=$ntape";
+
     pipe(DUMPOR,DUMPOW) or die $!;
     pipe(BUFOR,BUFOW) or die $!;
-    parsefsys();
-    if ($tm ne 'dump') {
-       print "Not dumping $atf ($prefix) - not \`dump'.\n" or die $!;
-       print LOG "Not dumping $atf ($prefix) - not \`dump'.\n" or die $!;
+
+    $gz= $gzi if length $gzi;
+    if ($gz) {
+       $bufir='GZOR';
+       pipe(GZOR,GZOW) or die $!;
+       $ddcmd .= " conv=sync";
+    }
+
+    if ($tm eq 'dump') {
+       $dumplabel= $pcstr.$atf_print.'$';
+       $dumpcmd= "dump 1Lbfu $dumplabel $softblocksizekb - $atf";
+    } elsif ($tm eq 'gtar') {
+       $dumpcmd= "tar NCcfl $fsidfile $atf - .";
+    } else {
+       pboth("Not dumping $atf_print ($prefix) - not supported.\n");
        next;
     }
-    startprocess '</dev/null','>&DUMPOW',$rstr."dump 1bfu $softblocksizekb - $atf";
-    startprocess '<&DUMPOR','>&BUFOW','writebuffer';
-    startprocess '<&BUFOR','>/dev/null'
-       ,"dd ibs=$softblocksizebytes obs=$blocksizebytes of=$ntape";
+
+    nexttapefile("inc $prefix:$atf_print");
+    
+    # Same trick as full uses to do a pipeline whilst keeping track
+    # of all exit statuses:
+    #   dump </dev/null | writebuffer | dd >/dev/null
+    startprocess '</dev/null','>&DUMPOW',"$nice ".$rstr.$dumpcmd;
+    if ($gz) {
+       startprocess '<&DUMPOR','>&GZOW',"$nice gzip -v$gz";
+    }
+    startprocess "<&$bufir",'>&BUFOW',"$nasty writebuffer";
+    startprocess '<&BUFOR','>/dev/null',"$nasty $ddcmd";
     closepipes();
     endprocesses();
+    # advance is a file counter, so it needs to be updated for each 
+    # dump we do to tape.
     $advance++;
+
+    finfsys();
 }
 
-system "mt -f $tape rewind"; $? and die $?;
+# Rewind the tape, and increment the counter of incremental backups.
+runsystem("mt -f $tape rewind");
 open IAN,">increm-advance.new" or die $!;
 print IAN "$advance\n" or die $!;
 close IAN or die $!;
 rename 'increm-advance.new','increm-advance' or die $!;
 
-print LOG "Next FULL dump tape is $next\n" or die $!;
-print "Next FULL dump tape is $next\n" or die $!;
+pboth("Next FULL dump tape is $next\n");
 
 setstatus "INCREMENTAL successful: $tapedesc, next full is $next";
 exit 0;