/[BackupPC]/upstream/2.1.0/bin/BackupPC_link
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/2.1.0/bin/BackupPC_link

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Jun 22 19:12:04 2005 UTC (17 years ago) by dpavlin
File size: 7917 byte(s)
import of version 2.1.0

1 dpavlin 1 #!/bin/perl
2     #============================================================= -*-perl-*-
3     #
4     # BackupPC_link: link new backup into pool
5     #
6     # DESCRIPTION
7     #
8     # BackupPC_link inspects every file in a new backup and
9     # checks if an existing file from any previous backup is
10     # identical. If so, the file is removed and replaced by
11     # a hardlink to the existing file. If the file is new,
12     # a hardlink to the file is made in the pool area, so that
13     # this file is available for checking against future backups.
14     #
15     # Then, for incremental backups, hardlinks are made in the
16     # backup directories to all files that were not extracted during
17     # the incremental backups. The means the incremental dump looks
18     # like a complete image of the PC.
19     #
20     # AUTHOR
21     # Craig Barratt <cbarratt@users.sourceforge.net>
22     #
23     # COPYRIGHT
24     # Copyright (C) 2001-2003 Craig Barratt
25     #
26     # This program is free software; you can redistribute it and/or modify
27     # it under the terms of the GNU General Public License as published by
28     # the Free Software Foundation; either version 2 of the License, or
29     # (at your option) any later version.
30     #
31     # This program is distributed in the hope that it will be useful,
32     # but WITHOUT ANY WARRANTY; without even the implied warranty of
33     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34     # GNU General Public License for more details.
35     #
36     # You should have received a copy of the GNU General Public License
37     # along with this program; if not, write to the Free Software
38     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39     #
40     #========================================================================
41     #
42     # Version 2.1.0, released 20 Jun 2004.
43     #
44     # See http://backuppc.sourceforge.net.
45     #
46     #========================================================================
47    
48     use strict;
49     no utf8;
50     use lib "__INSTALLDIR__/lib";
51     use BackupPC::Lib;
52     use BackupPC::Attrib;
53     use BackupPC::PoolWrite;
54    
55     use File::Find;
56     use File::Path;
57     use Digest::MD5;
58    
59     ###########################################################################
60     # Initialize
61     ###########################################################################
62    
63     die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
64     my $TopDir = $bpc->TopDir();
65     my $BinDir = $bpc->BinDir();
66     my %Conf = $bpc->Conf();
67    
68     $bpc->ChildInit();
69    
70     if ( @ARGV != 1 ) {
71     print("usage: $0 <host>\n");
72     exit(1);
73     }
74     if ( $ARGV[0] !~ /^([\w\.\s-]+)$/ ) {
75     print("$0: bad host name '$ARGV[0]'\n");
76     exit(1);
77     }
78     my $host = $1;
79     my $Dir = "$TopDir/pc/$host";
80     my($CurrDumpDir, $Compress);
81    
82     #
83     # Re-read config file, so we can include the PC-specific config
84     #
85     $bpc->ConfigRead($host);
86     %Conf = $bpc->Conf();
87    
88     ###########################################################################
89     # Process any backups that haven't been linked
90     ###########################################################################
91     my $md5 = Digest::MD5->new;
92     my($nFilesNew, $sizeNew, $sizeNewComp);
93     my($nFilesExist, $sizeExist, $sizeExistComp);
94     while ( 1 ) {
95     my @Backups = $bpc->BackupInfoRead($host);
96     $nFilesNew = $sizeNew = $sizeNewComp = 0;
97     $nFilesExist = $sizeExist = $sizeExistComp = 0;
98     my($num);
99     for ( $num = 0 ; $num < @Backups ; $num++ ) {
100     last if ( $Backups[$num]{nFilesNew} eq ""
101     || -f "$Dir/NewFileList.$Backups[$num]{num}" );
102     }
103     last if ( $num >= @Backups );
104     #
105     # Process list of new files left by BackupPC_dump
106     #
107     $CurrDumpDir = "$Dir/$Backups[$num]{num}";
108     $Compress = $Backups[$num]{compress};
109     if ( open(NEW, "<", "$Dir/NewFileList.$Backups[$num]{num}") ) {
110     binmode(NEW);
111     while ( <NEW> ) {
112     chomp;
113     next if ( !/(\w+) (\d+) (.*)/ );
114     LinkNewFile($1, $2, "$CurrDumpDir/$3");
115     }
116     close(NEW);
117     }
118     unlink("$Dir/NewFileList.$Backups[$num]{num}")
119     if ( -f "$Dir/NewFileList.$Backups[$num]{num}" );
120    
121     #
122     # See if we should fill in this dump. We only need to fill
123     # in incremental dumps. We can only fill in the incremental
124     # dump if there is an existing filled in dump with the same
125     # type of compression (on or off). Eg, we can't fill in
126     # a compressed incremental if the most recent filled in dump
127     # is not compressed.
128     #
129     my $noFill = 1;
130     my $fillFromNum;
131     if ( $Backups[$num]{type} ne "incr" ) {
132     $noFill = 0
133     } elsif ( $Conf{IncrFill} ) {
134     my $i;
135     for ( $i = $num - 1 ; $i >= 0 ; $i-- ) {
136     last if ( !$Backups[$i]{noFill}
137     && ($Backups[$i]{compress} ? 1 : 0)
138     == ($Compress ? 1 : 0) );
139     }
140     my $prevDump = "$Dir/$Backups[$i]{num}";
141     if ( $i >= 0 && -d $prevDump ) {
142     find({wanted => \&FillIncr, no_chdir => 1}, $prevDump);
143     $noFill = 0;
144     $fillFromNum = $Backups[$i]{num};
145     }
146     }
147     #
148     # Update the backup info file in $TopDir/pc/$host/backups
149     #
150     @Backups = $bpc->BackupInfoRead($host);
151     $Backups[$num]{nFilesExist} += $nFilesExist;
152     $Backups[$num]{sizeExist} += $sizeExist;
153     $Backups[$num]{sizeExistComp} += $sizeExistComp;
154     $Backups[$num]{nFilesNew} += $nFilesNew;
155     $Backups[$num]{sizeNew} += $sizeNew;
156     $Backups[$num]{sizeNewComp} += $sizeNewComp;
157     $Backups[$num]{noFill} = $noFill;
158     $Backups[$num]{fillFromNum} = $fillFromNum;
159     $bpc->BackupInfoWrite($host, @Backups);
160     }
161    
162     ###########################################################################
163     # Subroutines
164     ###########################################################################
165    
166     #
167     # Fill in an incremental dump by making hardlinks to the previous
168     # dump.
169     #
170     sub FillIncr
171     {
172     my($name) = $File::Find::name;
173     my($newName);
174    
175     $name = $1 if ( $name =~ /(.*)/ );
176     return if ( $name !~ m{\Q$Dir\E/(\d+)/(.*)} );
177     $newName = "$CurrDumpDir/$2";
178     if ( -d $name && -d $newName ) {
179     #
180     # Merge the file attributes.
181     #
182     my $newAttr = BackupPC::Attrib->new({ compress => $Compress });
183     my $attr = BackupPC::Attrib->new({ compress => $Compress });
184     $newAttr->read($newName) if ( -f $newAttr->fileName($newName) );
185     $attr->read($name) if ( -f $attr->fileName($name) );
186     $newAttr->merge($attr);
187     #
188     # Now write it out, adding a link to the pool if necessary
189     #
190     my $data = $newAttr->writeData;
191     my $origSize = length($data);
192     my $fileName = $newAttr->fileName($newName);
193     my $poolWrite = BackupPC::PoolWrite->new($bpc, $fileName,
194     length($data), $Compress);
195     $poolWrite->write(\$data);
196     my($exists, $digest, $outSize, $errs) = $poolWrite->close;
197     if ( @$errs ) {
198     print("log ", join("", @$errs));
199     }
200     if ( $exists ) {
201     $nFilesExist++;
202     $sizeExist += $origSize;
203     $sizeExistComp += $outSize;
204     } elsif ( $outSize > 0 ) {
205     $nFilesNew++;
206     $sizeNew += $origSize;
207     $sizeNewComp += -s $outSize;
208     LinkNewFile($digest, $origSize, $fileName);
209     }
210     } elsif ( -f $name && !-f $newName ) {
211     #
212     # Exists in the older filled backup, and not in the new, so link it
213     #
214     link($name, $newName);
215     }
216     }
217    
218     #
219     # Add a link in the pool to a new file
220     #
221     sub LinkNewFile
222     {
223     my($d, $size, $fileName) = @_;
224     my $res = $bpc->MakeFileLink($fileName, $d, 1, $Compress);
225     if ( $res == 1 ) {
226     $nFilesExist++;
227     $sizeExist += $size;
228     $sizeExistComp += -s $fileName;
229     } elsif ( $res == 2 ) {
230     $nFilesNew++;
231     $sizeNew += $size;
232     $sizeNewComp += -s $fileName;
233     } elsif ( $res != 0 && $res != -1 ) {
234     print("log BackupPC_link got error $res when calling"
235     . " MakeFileLink($fileName, $d, 1)\n");
236     }
237     }

Properties

Name Value
svn:executable

  ViewVC Help
Powered by ViewVC 1.1.26