"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "bin/BackupPC_fsck" between
BackupPC-4.3.2.tar.gz and BackupPC-4.4.0.tar.gz

About: BackupPC is a high-performance, enterprise-grade system for backing up Linux and WinXX PCs and laptops to a server’s disk (http/cgi user interface).

BackupPC_fsck  (BackupPC-4.3.2):BackupPC_fsck  (BackupPC-4.4.0)
skipping to change at line 33 skipping to change at line 33
# This program is distributed in the hope that it will be useful, # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
#======================================================================== #========================================================================
# #
# Version 4.3.2, released 17 Feb 2020. # Version 4.4.0, released 20 Jun 2020.
# #
# See http://backuppc.sourceforge.net. # See http://backuppc.sourceforge.net.
# #
#======================================================================== #========================================================================
use strict; use strict;
no utf8; no utf8;
use lib "__INSTALLDIR__/lib"; use lib "__INSTALLDIR__/lib";
use BackupPC::Lib; use BackupPC::Lib;
use BackupPC::XS; use BackupPC::XS;
use BackupPC::Storage; use BackupPC::Storage;
use BackupPC::DirOps; use BackupPC::DirOps;
use Getopt::Std; use Getopt::Std;
use File::Path; use File::Path;
use Data::Dumper; use Data::Dumper;
my(@Ref, $RefTotal); my(@Ref, $RefTotal);
my $ErrorCnt = 0; my $ErrorCnt = 0;
my %opts; my %opts;
my $EmptyMD5 = pack("H*", "d41d8cd98f00b204e9800998ecf8427e"); my $EmptyMD5 = pack("H*", "d41d8cd98f00b204e9800998ecf8427e");
die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) ); die("BackupPC::Lib->new failed\n") if ( !(my $bpc = BackupPC::Lib->new) );
my $TopDir = $bpc->TopDir(); my $TopDir = $bpc->TopDir();
my $BinDir = $bpc->BinDir(); my $BinDir = $bpc->BinDir();
my %Conf = $bpc->Conf(); my %Conf = $bpc->Conf();
my $Hosts = $bpc->HostInfoRead(); my $Hosts = $bpc->HostInfoRead();
my $s = $bpc->{storage}; my $s = $bpc->{storage};
if ( !getopts("fns", \%opts) || @ARGV >= 1 ) { if ( !getopts("fns", \%opts) || @ARGV >= 1 ) {
print STDERR <<EOF; print STDERR <<EOF;
usage: $0 [options] usage: $0 [options]
Options: Options:
skipping to change at line 93 skipping to change at line 95
if ( !defined($Info) && ref($Status) ne "HASH" ) { if ( !defined($Info) && ref($Status) ne "HASH" ) {
print STDERR "$0: status.pl read failed: $Status\n"; print STDERR "$0: status.pl read failed: $Status\n";
$Info = {}; $Info = {};
$Status = {}; $Status = {};
} }
# #
# Zero out the statistics # Zero out the statistics
# #
for my $p ( qw(pool4 cpool4) ) { for my $p ( qw(pool4 cpool4) ) {
for ( my $i = 0 ; $i < 16 ; $i++ ) { for ( my $i = 0 ; $i < 16 ; $i++ ) {
$Info->{pool}{$p}[$i]{FileCnt} = 0; $Info->{pool}{$p}[$i]{FileCnt} = 0;
$Info->{pool}{$p}[$i]{DirCnt} = 0; $Info->{pool}{$p}[$i]{DirCnt} = 0;
$Info->{pool}{$p}[$i]{KbRm} = 0; $Info->{pool}{$p}[$i]{KbRm} = 0;
$Info->{pool}{$p}[$i]{Kb} = 0; $Info->{pool}{$p}[$i]{Kb} = 0;
$Info->{pool}{$p}[$i]{FileCntRm} = 0; $Info->{pool}{$p}[$i]{FileCntRm} = 0;
$Info->{pool}{$p}[$i]{FileCntRep} = 0; $Info->{pool}{$p}[$i]{FileCntRep} = 0;
$Info->{pool}{$p}[$i]{FileRepMax} = 0; $Info->{pool}{$p}[$i]{FileRepMax} = 0;
$Info->{pool}{$p}[$i]{FileLinkMax} = 0; $Info->{pool}{$p}[$i]{FileLinkMax} = 0;
$Info->{pool}{$p}[$i]{Time} = 0; $Info->{pool}{$p}[$i]{Time} = 0;
} }
} }
} }
if ( $opts{f} ) { if ( $opts{f} ) {
# #
# Rebuild host count database # Rebuild host count database
# #
foreach my $host ( sort(keys(%$Hosts)) ) { foreach my $host ( sort(keys(%$Hosts)) ) {
print("BackupPC_fsck: Rebuilding count database for host $host\n"); print("BackupPC_fsck: Rebuilding count database for host $host\n");
$ErrorCnt++ if ( system("$BinDir/BackupPC_refCountUpdate -h $host -f -p" ) ); $ErrorCnt++ if ( system("$BinDir/BackupPC_refCountUpdate -h $host -F -p" ) );
} }
} else { } else {
# #
# Make sure each host count database is up to date # Make sure each host count database is up to date
# (ie: process any delta files) # (ie: process any delta files)
# #
foreach my $host ( sort(keys(%$Hosts)) ) { foreach my $host ( sort(keys(%$Hosts)) ) {
$ErrorCnt++ if ( system("$BinDir/BackupPC_refCountUpdate -o 0 -h $host - p") ); $ErrorCnt++ if ( system("$BinDir/BackupPC_refCountUpdate -o 0 -h $host - p") );
} }
} }
skipping to change at line 147 skipping to change at line 149
} }
print("$0: got $ErrorCnt errors\n"); print("$0: got $ErrorCnt errors\n");
exit($ErrorCnt ? 1 : 0); exit($ErrorCnt ? 1 : 0);
sub poolCountUpdate sub poolCountUpdate
{ {
for ( my $compress = 0 ; $compress < 2 ; $compress++ ) { for ( my $compress = 0 ; $compress < 2 ; $compress++ ) {
my $poolName = $compress ? "cpool4" : "pool4"; my $poolName = $compress ? "cpool4" : "pool4";
for ( my $refCntFile = 0 ; $refCntFile < 128 ; $refCntFile++ ) { for ( my $refCntFile = 0 ; $refCntFile < 128 ; $refCntFile++ ) {
my $fileCnt = 0; # total number of pool files
my $dirCnt = 0; # total number of pool directories my $fileCnt = 0; # total number of pool files
my $blkCnt = 0; # total block size of pool files my $dirCnt = 0; # total number of pool directories
my $fileCntRm = 0; # total number of removed files my $blkCnt = 0; # total block size of pool files
my $blkCntRm = 0; # total block size of removed pool files my $fileCntRm = 0; # total number of removed files
my $fileCntRep = 0; # total number of pool files with repeated md my $blkCntRm = 0; # total block size of removed pool files
5 checksums my $fileCntRep = 0; # total number of pool files with repeated
# (ie: digest > 16 bytes; first instance isn' md5 checksums
t counted) # (ie: digest > 16 bytes; first instance i
my $fileRepMax = 0; # worse case chain length of pool files that sn't counted)
have repeated my $fileRepMax = 0; # worse case chain length of pool files th
# checksums (ie: max(NNN) for all digests xxx at have repeated
xxxxxxxxxxxxxNNN) # checksums (ie: max(NNN) for all digests
my $fileLinkMax = 0; # maximum number of links on a pool file xxxxxxxxxxxxxxxxNNN)
my $fileLinkTotal = 0; # total number of links on entire pool my $fileLinkMax = 0; # maximum number of links on a pool file
my $fileLinkTotal = 0; # total number of links on entire pool
my $poolDir = sprintf("%s/%02x",
$compress ? $bpc->{CPoolDir} : $bpc->{PoolDir} my $poolDir = sprintf("%s/%02x", $compress ? $bpc->{CPoolDir} : $bpc
, ->{PoolDir}, $refCntFile * 2);
$refCntFile * 2);
next if ( !-d $poolDir ); next if ( !-d $poolDir );
$dirCnt++; $dirCnt++;
my $count = BackupPC::XS::PoolRefCnt::new(); my $count = BackupPC::XS::PoolRefCnt::new();
my $dirty = 0; my $dirty = 0;
my $poolCntFile = "$poolDir/poolCnt"; my $poolCntFile = "$poolDir/poolCnt";
# #
# Count the number of pool directories # Count the number of pool directories
# #
skipping to change at line 204 skipping to change at line 206
my $subPoolDir = sprintf("%s/%02x", $poolDir, $subDir * 2); my $subPoolDir = sprintf("%s/%02x", $poolDir, $subDir * 2);
next if ( !-d $subPoolDir ); next if ( !-d $subPoolDir );
my $entries = BackupPC::DirOps::dirRead($bpc, $subPoolDir); my $entries = BackupPC::DirOps::dirRead($bpc, $subPoolDir);
next if ( !defined($entries) ); next if ( !defined($entries) );
# #
# traverse the files in reverse order, in case we can delete mul tiple files in # traverse the files in reverse order, in case we can delete mul tiple files in
# a single chain. # a single chain.
# #
foreach my $e ( sort {$b cmp $a} @$entries ) { foreach my $e ( sort { $b cmp $a } @$entries ) {
next if ( $e->{name} eq "." next if ( $e->{name} eq "." || $e->{name} eq ".." || $e->{na
|| $e->{name} eq ".." me} eq "LOCK" );
|| $e->{name} eq "LOCK" ); my $digest = pack("H*", $e->{name});
my $digest = pack("H*", $e->{name});
my $poolFile = "$subPoolDir/$e->{name}"; my $poolFile = "$subPoolDir/$e->{name}";
#printf("Got %s, digest = %s\n", $e->{name}, unpack("H*", $d igest)); #printf("Got %s, digest = %s\n", $e->{name}, unpack("H*", $d igest));
my($nBlks, @s); my($nBlks, @s);
if ( $opts{s} ) { if ( $opts{s} ) {
@s = stat($poolFile); @s = stat($poolFile);
$nBlks = $s[12]; $nBlks = $s[12];
$blkCnt += $nBlks; $blkCnt += $nBlks;
} }
next if ( $count->get($digest) != 0 ); next if ( $count->get($digest) != 0 );
# #
# figure out the next file in the chain to see how to # figure out the next file in the chain to see how to
# handle this one. # handle this one.
# #
@s = stat($poolFile) if ( !$opts{s} ); @s = stat($poolFile) if ( !$opts{s} );
my $ext = $bpc->digestExtGet($digest); my $ext = $bpc->digestExtGet($digest);
my($nextDigest, $nextPoolFile) = $bpc->digestConcat($digest, my($nextDigest, $nextPoolFile) = $bpc->digestConcat($digest,
$ext + 1 $ext + 1, $compress);
, $compress);
if ( !-f $nextPoolFile ) { if ( !-f $nextPoolFile ) {
# #
# last in the chain (or no chain) - just delete it # last in the chain (or no chain) - just delete it
# #
print("Removing pool file $poolFile\n") if ( $Conf{XferL ogLevel} >= 2 ); print("Removing pool file $poolFile\n") if ( $Conf{XferL ogLevel} >= 2 );
if ( !$opts{n} ) { if ( !$opts{n} ) {
if ( unlink($poolFile) != 1 ) { if ( unlink($poolFile) != 1 ) {
print("Can't remove $poolFile\n"); print("Can't remove $poolFile\n");
$ErrorCnt++; $ErrorCnt++;
next; next;
} }
$count->delete($digest); $count->delete($digest);
$fileCntRm++; $fileCntRm++;
$blkCntRm += $nBlks; $blkCntRm += $nBlks;
} }
} elsif ( $s[7] > 0 ) { } elsif ( $s[7] > 0 ) {
# #
# in the middle of a chain of pool files, so # in the middle of a chain of pool files, so
# we replace the file with an empty file. # we replace the file with an empty file.
# #
print("Zeroing pool file $poolFile (next $nextPoolFile e print("Zeroing pool file $poolFile (next $nextPoolFile e
xists)\n") if ( $Conf{XferLogLevel} >= 2 ); xists)\n")
if ( $Conf{XferLogLevel} >= 2 );
if ( !$opts{n} ) { if ( !$opts{n} ) {
if ( chmod(0644, $poolFile) != 1 ) { if ( chmod(0644, $poolFile) != 1 ) {
print("Can't chmod 0644 $poolFile\n"); print("Can't chmod 0644 $poolFile\n");
$ErrorCnt++; $ErrorCnt++;
} }
if ( open(my $fh, ">", $poolFile) ) { if ( open(my $fh, ">", $poolFile) ) {
close($fh); close($fh);
} else { } else {
print("Can't truncate $poolFile\n"); print("Can't truncate $poolFile\n");
$ErrorCnt++; $ErrorCnt++;
skipping to change at line 277 skipping to change at line 277
if ( $opts{s} ) { if ( $opts{s} ) {
my($digest, $cnt); my($digest, $cnt);
my $idx = 0; my $idx = 0;
while ( 1 ) { while ( 1 ) {
($digest, $cnt, $idx) = $count->iterate($idx); ($digest, $cnt, $idx) = $count->iterate($idx);
last if ( !defined($digest) ); last if ( !defined($digest) );
$fileCnt++; $fileCnt++;
$fileLinkTotal += $cnt; $fileLinkTotal += $cnt;
$fileLinkMax = $cnt if ( $cnt > $fileLinkMax && $digest n e $EmptyMD5 ); $fileLinkMax = $cnt if ( $cnt > $fileLinkMax && $digest ne $ EmptyMD5 );
next if ( length($digest) <= 16 ); next if ( length($digest) <= 16 );
my $ext = $bpc->digestExtGet($digest); my $ext = $bpc->digestExtGet($digest);
$fileCntRep += $ext; $fileCntRep += $ext;
$fileRepMax = $ext if ( $ext > $fileRepMax ); $fileRepMax = $ext if ( $ext > $fileRepMax );
} }
my $kb = int($blkCnt / 2 + 0.5); my $kb = int($blkCnt / 2 + 0.5);
my $kbRm = int($blkCntRm / 2 + 0.5); my $kbRm = int($blkCntRm / 2 + 0.5);
#print("BackupPC_stats4 $refCntFile = $poolName,$fileCnt,$dirCnt ,$kb,$kbRm," #print("BackupPC_stats4 $refCntFile = $poolName,$fileCnt,$dirCnt ,$kb,$kbRm,"
# . "$fileCntRm,$fileCntRep,$fileRepMax,$fileLinkMax,$fileL inkTotal\n"); # . "$fileCntRm,$fileCntRep,$fileRepMax,$fileLinkMax,$fileL inkTotal\n");
my $chunk = int($refCntFile / 8); my $chunk = int($refCntFile / 8);
$Info->{pool}{$poolName}[$chunk]{FileCnt} += $fileCnt; $Info->{pool}{$poolName}[$chunk]{FileCnt} += $fileCnt;
$Info->{pool}{$poolName}[$chunk]{DirCnt} += $dirCnt; $Info->{pool}{$poolName}[$chunk]{DirCnt} += $dirCnt;
$Info->{pool}{$poolName}[$chunk]{Kb} += $kb; $Info->{pool}{$poolName}[$chunk]{Kb} += $kb;
$Info->{pool}{$poolName}[$chunk]{KbRm} += $kbRm; $Info->{pool}{$poolName}[$chunk]{KbRm} += $kbRm;
$Info->{pool}{$poolName}[$chunk]{FileCntRm} += $fileCntRm; $Info->{pool}{$poolName}[$chunk]{FileCntRm} += $fileCntRm;
$Info->{pool}{$poolName}[$chunk]{FileCntRep} += $fileCntRep; $Info->{pool}{$poolName}[$chunk]{FileCntRep} += $fileCntRep;
$Info->{pool}{$poolName}[$chunk]{FileRepMax} = $fileRepMax $Info->{pool}{$poolName}[$chunk]{FileRepMax} = $fileRepMax
if ( $Info->{pool}{$poolName}[$chunk]{FileRepMax} < $fil if ( $Info->{pool}{$poolName}[$chunk]{FileRepMax} < $fileRepMa
eRepMax ); x );
$Info->{pool}{$poolName}[$chunk]{FileLinkMax} = $fileLinkMax $Info->{pool}{$poolName}[$chunk]{FileLinkMax} = $fileLinkMax
if ( $Info->{pool}{$poolName}[$chunk]{FileLinkMax} < $fi if ( $Info->{pool}{$poolName}[$chunk]{FileLinkMax} < $fileLink
leLinkMax ); Max );
$Info->{pool}{$poolName}[$chunk]{FileLinkTotal} += $fileLinkTota l; $Info->{pool}{$poolName}[$chunk]{FileLinkTotal} += $fileLinkTota l;
$Info->{pool}{$poolName}[$chunk]{Time} = time; $Info->{pool}{$poolName}[$chunk]{Time} = time;
} }
} }
} }
if ( $opts{s} ) { if ( $opts{s} ) {
# #
# Update the cumulative statistics for pool4 and cpool4 # Update the cumulative statistics for pool4 and cpool4
# #
for my $p ( qw(pool4 cpool4) ) { for my $p ( qw(pool4 cpool4) ) {
$Info->{"${p}FileCnt"} = 0; $Info->{"${p}FileCnt"} = 0;
$Info->{"${p}DirCnt"} = 0; $Info->{"${p}DirCnt"} = 0;
$Info->{"${p}Kb"} = 0; $Info->{"${p}Kb"} = 0;
$Info->{"${p}KbRm"} = 0; $Info->{"${p}KbRm"} = 0;
$Info->{"${p}FileCntRm"} = 0; $Info->{"${p}FileCntRm"} = 0;
$Info->{"${p}FileCntRep"} = 0; $Info->{"${p}FileCntRep"} = 0;
$Info->{"${p}FileRepMax"} = 0; $Info->{"${p}FileRepMax"} = 0;
$Info->{"${p}FileLinkMax"} = 0; $Info->{"${p}FileLinkMax"} = 0;
$Info->{"${p}Time"} = 0; $Info->{"${p}Time"} = 0;
delete $Info->{"${p}FileCntRename"}; delete $Info->{"${p}FileCntRename"};
for ( my $i = 0 ; $i < 16 ; $i++ ) { for ( my $i = 0 ; $i < 16 ; $i++ ) {
$Info->{"${p}FileCnt"} $Info->{"${p}FileCnt"} += $Info->{pool}{$p}[$i]{FileCnt};
+= $Info->{pool}{$p}[$i]{FileCnt}; $Info->{"${p}DirCnt"} += $Info->{pool}{$p}[$i]{DirCnt};
$Info->{"${p}DirCnt"} $Info->{"${p}Kb"} += $Info->{pool}{$p}[$i]{Kb};
+= $Info->{pool}{$p}[$i]{DirCnt}; $Info->{"${p}KbRm"} += $Info->{pool}{$p}[$i]{KbRm};
$Info->{"${p}Kb"} $Info->{"${p}FileCntRm"} += $Info->{pool}{$p}[$i]{FileCntRm};
+= $Info->{pool}{$p}[$i]{Kb}; $Info->{"${p}FileCntRep"} += $Info->{pool}{$p}[$i]{FileCntRep};
$Info->{"${p}KbRm"} $Info->{"${p}FileRepMax"} = $Info->{pool}{$p}[$i]{FileRepMax}
+= $Info->{pool}{$p}[$i]{KbRm}; if ( $Info->{"${p}FileRepMax"} < $Info->{pool}{$p}[$i]{FileRep
$Info->{"${p}FileCntRm"} Max} );
+= $Info->{pool}{$p}[$i]{FileCntRm}; $Info->{"${p}FileLinkMax"} = $Info->{pool}{$p}[$i]{FileLinkMax}
$Info->{"${p}FileCntRep"} if ( $Info->{"${p}FileLinkMax"} < $Info->{pool}{$p}[$i]{FileLi
+= $Info->{pool}{$p}[$i]{FileCntRep}; nkMax} );
$Info->{"${p}FileRepMax"}
= $Info->{pool}{$p}[$i]{FileRepMax}
if ( $Info->{"${p}FileRepMax"} <
$Info->{pool}{$p}[$i]{FileRepMax} );
$Info->{"${p}FileLinkMax"}
= $Info->{pool}{$p}[$i]{FileLinkMax}
if ( $Info->{"${p}FileLinkMax"} <
$Info->{pool}{$p}[$i]{FileLinkMax} );
$Info->{"${p}Time"} = $Info->{pool}{$p}[$i]{Time} $Info->{"${p}Time"} = $Info->{pool}{$p}[$i]{Time}
if ( $Info->{"${p}Time"} < if ( $Info->{"${p}Time"} < $Info->{pool}{$p}[$i]{Time} );
$Info->{pool}{$p}[$i]{Time} );
} }
printf("%s%s BackupPC_fsck removed %d files of" printf(
. " size %.2fGB\n", "%s%s BackupPC_fsck removed %d files of size %.2fGB\n",
$bpc->timeStamp, ucfirst($p), $bpc->timeStamp, ucfirst($p),
$Info->{"${p}FileCntRm"}, $Info->{"${p}FileCntRm"},
$Info->{"${p}KbRm"} / (1000 * 1024)); $Info->{"${p}KbRm"} / (1000 * 1024)
printf("%s%s is %.2fGB, %d files (%d repeated, " );
. "%d max chain, %d max links), %d directories\n", printf(
$bpc->timeStamp, ucfirst($p), "%s%s is %.2fGB, %d files (%d repeated, %d max chain, %d max lin
$Info->{"${p}Kb"} / (1000 * 1024), ks), %d directories\n",
$Info->{"${p}FileCnt"}, $Info->{"${p}FileCntRep"}, $bpc->timeStamp, ucfirst($p),
$Info->{"${p}FileRepMax"}, $Info->{"${p}Kb"} / (1000 * 1024),
$Info->{"${p}FileLinkMax"}, $Info->{"${p}DirCnt"}); $Info->{"${p}FileCnt"},
$Info->{"${p}FileCntRep"},
$Info->{"${p}FileRepMax"},
$Info->{"${p}FileLinkMax"},
$Info->{"${p}DirCnt"}
);
} }
} }
} }
sub CheckIfServerRunning sub CheckIfServerRunning
{ {
my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort}); my $err = $bpc->ServerConnect($Conf{ServerHost}, $Conf{ServerPort});
if ( !defined $err ) { if ( !defined $err ) {
print STDERR "$0: can't run since BackupPC is running\n"; print STDERR "$0: can't run since BackupPC is running\n";
exit(1); exit(1);
 End of changes. 19 change blocks. 
103 lines changed or deleted 101 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)