#!/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,2007 # Ian Jackson # Copyright (C) 1999 Peter Maydell # # 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 3, 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, consult the Free Software Foundation's # website at www.fsf.org, or the GNU Project website at www.gnu.org. # 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/chiark-backup'; require "$etc/settings.pl"; require 'backuplib.pl'; } $|=1; @ARGV==2 or die; ($tapeid,$tapedesc)= @ARGV; 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= ); 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= ); close A or die $!; # better be a decimal number $advance =~ m/^\d+$/ or die "$advance ?"; # Get a list of all filesystems readfsys('all'); openlog(); # 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 { runsystem("mt -f $ntape fsf $advance"); $currenttapefilenumber= $advance; } 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 $!; $gz= $gzi if length $gzi; if ($gz) { $bufir='GZOR'; pipe(GZOR,GZOW) or die $!; $ddcmd .= " conv=sync"; } if ($dopt{'noinc'}) { pboth("Incrementals of $atf_print ($prefix) suppressed in config.\n"); } 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; } nexttapefile("inc $prefix:$atf_print"); # Same trick as full uses to do a pipeline whilst keeping track # of all exit statuses: # dump /dev/null startprocess '&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(); } # 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 $!; pboth("Next FULL dump tape is $next\n"); setstatus "INCREMENTAL successful: $tapedesc, next full is $next"; exit 0;