chiark / gitweb /
chiark-backup's snaprsync sedderies mountpoint out before sums diff.
[chiark-utils.git] / backup / increm
1 #!/usr/bin/perl
2 # increm
3 # Do an incremental backup; ONLY for invocation by full !
4 #
5 # This file is part of chiark backup, a system for backing up GNU/Linux and
6 # other UN*X-compatible machines, as used on chiark.greenend.org.uk.
7 #
8 # chiark backup is:
9 #  Copyright (C) 1997-1998,2000-2001 Ian Jackson <ian@chiark.greenend.org.uk>
10 #  Copyright (C) 1999 Peter Maydell <pmaydell@chiark.greenend.org.uk>
11 #
12 # This is free software; you can redistribute it and/or modify it under the
13 # terms of the GNU General Public License as published by the Free Software
14 # Foundation; either version 2, or (at your option) any later version.
15 #
16 # This is distributed in the hope that it will be useful, but WITHOUT ANY
17 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19 # details.
20 #
21 # You should have received a copy of the GNU General Public License along
22 # with this program; if not, write to the Free Software Foundation, Inc.,
23 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25 # We are invoked by full if the tape description file says that it is
26 # for an incremental backup.  We expect two commandline argument which
27 # is the ID string of the tape to use, and the description (which
28 # includes ID and function).
29
30 BEGIN {
31     $etc= '/etc/chiark-backup';
32     require "$etc/settings.pl";
33     require 'backuplib.pl';
34 }
35
36 $|=1;
37
38 @ARGV==2 or die;
39 ($tapeid,$tapedesc)= @ARGV;
40
41 print "Running incremental onto $tapedesc ...\n" or die $!;
42
43 # Just check that we weren't passed a bogus ID (the tape description
44 # file for incrementals is just 'incremental\nend\n')
45 open T,"$etc/tape.$tapeid" or die "Tape $tapeid not found: $!\n";
46 close T;
47
48 # This is only used for the 'next FULL backup is X' message at the end.
49 open NF,"next-full" or die $!;
50 chomp($next= <NF>);
51 close NF or die $!;
52
53 setstatus "FAILED during incremental";
54
55 # Read the number of the incremental involved
56 # (ie, (how many files are already on the tape) - 1)
57 open A,"increm-advance" or die $!;
58 chomp($advance= <A>);
59 close A or die $!;
60
61 # better be a decimal number
62 $advance =~ m/^\d+$/ or die "$advance ?";
63
64 # Get a list of all filesystems
65 readfsys('all');
66 openlog();
67
68 # Rewind the tape and if we are the first incremental on the tape then
69 # write the TAPEID record, otherwise skip forward to the correct point.
70 # (full will already have checked that this is the right tape before
71 # it invoked us, so no need to read the existing TAPEID record first.)
72 runsystem("mt -f $ntape rewind");
73 if ($advance == 1) {
74     writetapeid($tapeid,$tapedesc);
75 } else {
76     runsystem("mt -f $ntape fsf $advance");
77     $currenttapefilenumber= $advance;
78 }
79
80 sub closepipes () {
81     close(DUMPOR); close(BUFOR);
82     close(DUMPOW); close(BUFOW);
83     close(GZOR); close(GZOW);
84 }
85
86 setstatus "PROBLEMS during incremental dump";
87
88 for $tf (@fsys) {
89
90     parsefsys();
91     prepfsys();
92     
93     $bufir='DUMPOR';
94     $ddcmd= "$nasty dd ibs=$softblocksizebytes obs=$blocksizebytes of=$ntape";
95
96     pipe(DUMPOR,DUMPOW) or die $!;
97     pipe(BUFOR,BUFOW) or die $!;
98
99     $gz= $gzi if length $gzi;
100     if ($gz) {
101         $bufir='GZOR';
102         pipe(GZOR,GZOW) or die $!;
103         $ddcmd .= " conv=sync";
104     }
105
106     if ($dopt{'noinc'}) {
107         pboth("Incrementals of $atf_print ($prefix) suppressed in config.\n");
108     }
109
110     if ($tm eq 'dump') {
111         $dumplabel= $pcstr.$atf_print.'$';
112         $dumpcmd= "dump 1Lbfu $dumplabel $softblocksizekb - $atf";
113     } elsif ($tm eq 'gtar') {
114         $dumpcmd= "tar NCcfl $fsidfile $atf - .";
115     } else {
116         pboth("Not dumping $atf_print ($prefix) - not supported.\n");
117         next;
118     }
119
120     nexttapefile("inc $prefix:$atf_print");
121     
122     # Same trick as full uses to do a pipeline whilst keeping track
123     # of all exit statuses:
124     #   dump </dev/null | writebuffer | dd >/dev/null
125     startprocess '</dev/null','>&DUMPOW',"$nice ".$rstr.$dumpcmd;
126     if ($gz) {
127         startprocess '<&DUMPOR','>&GZOW',"$nice gzip -v$gz";
128     }
129     startprocess "<&$bufir",'>&BUFOW',"$nasty writebuffer";
130     startprocess '<&BUFOR','>/dev/null',"$nasty $ddcmd";
131     closepipes();
132     endprocesses();
133     # advance is a file counter, so it needs to be updated for each 
134     # dump we do to tape.
135     $advance++;
136
137     finfsys();
138 }
139
140 # Rewind the tape, and increment the counter of incremental backups.
141 runsystem("mt -f $tape rewind");
142 open IAN,">increm-advance.new" or die $!;
143 print IAN "$advance\n" or die $!;
144 close IAN or die $!;
145 rename 'increm-advance.new','increm-advance' or die $!;
146
147 pboth("Next FULL dump tape is $next\n");
148
149 setstatus "INCREMENTAL successful: $tapedesc, next full is $next";
150 exit 0;