X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=blobdiff_plain;f=lib%2FBackupPC%2FXfer%2FRsyncFileIO.pm;h=83b9db968f08f8d7b1c7f1a3994813141c6123cd;hp=2d2f0b2773fa6cc54739ae061b34e1d032639c65;hb=f6fbcc3682d2bc9e7dfdc26e95bd5fcdb359496d;hpb=31a7aca27ffd75e0aee9836704599cdb95dc2421 diff --git a/lib/BackupPC/Xfer/RsyncFileIO.pm b/lib/BackupPC/Xfer/RsyncFileIO.pm index 2d2f0b2..83b9db9 100644 --- a/lib/BackupPC/Xfer/RsyncFileIO.pm +++ b/lib/BackupPC/Xfer/RsyncFileIO.pm @@ -8,11 +8,11 @@ # Craig Barratt # # COPYRIGHT -# Copyright (C) 2002-2003 Craig Barratt +# Copyright (C) 2002-2007 Craig Barratt # #======================================================================== # -# Version 3.0.0beta2, released 11 Nov 2006. +# Version 3.2.0beta0, released 5 April 2009. # # See http://backuppc.sourceforge.net. # @@ -162,6 +162,12 @@ sub csumStart $defBlkSize, $fio->{checksumSeed}, 0, $attr->{compress}, 0, $fio->{protocol_version}); + if ( $err ) { + $fio->log("Can't get rsync digests from $attr->{fullPath}" + . " (err=$err, name=$f->{name})"); + $fio->{stats}{errorCnt}++; + return -1; + } my($isCached, $isInvalid) = $d->isCached; if ( $fio->{logLevel} >= 5 ) { $fio->log("$attr->{fullPath} verify; cached = $isCached," @@ -170,7 +176,8 @@ sub csumStart if ( $isCached || $isInvalid ) { my $ret = BackupPC::Xfer::RsyncDigest->digestAdd( $attr->{fullPath}, $blkSize, - $fio->{checksumSeed}, 1 # verify + $fio->{checksumSeed}, 1, # verify + $fio->{protocol_version} ); if ( $ret != 1 ) { $fio->log("Bad cached digest for $attr->{fullPath} ($ret);" @@ -186,19 +193,18 @@ sub csumStart (my $err, $fio->{csum}, my $blkSize) = BackupPC::Xfer::RsyncDigest->digestStart($attr->{fullPath}, $attr->{size}, 0, $defBlkSize, $fio->{checksumSeed}, - $needMD4, $attr->{compress}, 1, - $fio->{protocol_version}); - if ( $fio->{logLevel} >= 5 ) { - my($isCached, $invalid) = $fio->{csum}->isCached; - $fio->log("$attr->{fullPath} cache = $isCached," - . " invalid = $invalid, phase = $phase"); - } + $needMD4, $attr->{compress}, 1, $fio->{protocol_version}); if ( $err ) { $fio->log("Can't get rsync digests from $attr->{fullPath}" . " (err=$err, name=$f->{name})"); $fio->{stats}{errorCnt}++; return -1; } + if ( $fio->{logLevel} >= 5 ) { + my($isCached, $invalid) = $fio->{csum}->isCached; + $fio->log("$attr->{fullPath} cache = $isCached," + . " invalid = $invalid, phase = $phase"); + } return $blkSize; } @@ -323,12 +329,14 @@ sub viewCacheDir sub attribGetWhere { - my($fio, $f, $noCache) = @_; - my($dir, $fname, $share, $shareM, $partial, $attr); + my($fio, $f, $noCache, $fname) = @_; + my($dir, $share, $shareM, $partial, $attr); - $fname = $f->{name}; - $fname = "$fio->{xfer}{pathHdrSrc}/$fname" + if ( !defined($fname) ) { + $fname = $f->{name}; + $fname = "$fio->{xfer}{pathHdrSrc}/$fname" if ( defined($fio->{xfer}{pathHdrSrc}) ); + } $fname =~ s{//+}{/}g; if ( $fname =~ m{(.*)/(.*)}s ) { $shareM = $fio->{shareM}; @@ -388,15 +396,10 @@ sub attribGet return $attr; } $target = "/$target" if ( $target !~ /^\// ); - $fio->log("$attr->{fullPath}: redirecting to $target (will trim " - . "$fio->{xfer}{pathHdrSrc})") if ( $fio->{logLevel} >= 4 ); - $target =~ s/^\Q$fio->{xfer}{pathHdrSrc}//; + $fio->log("$attr->{fullPath}: redirecting to $target") + if ( $fio->{logLevel} >= 4 ); $target =~ s{^/+}{}; - # - # Note: overwrites name to point to real file - # - $f->{name} = $target; - ($attr) = $fio->attribGetWhere($f, 1); + ($attr) = $fio->attribGetWhere($f, 1, $target); $fio->log(" ... now got $attr->{fullPath}") if ( $fio->{logLevel} >= 4 ); } @@ -439,6 +442,8 @@ sub attribSet my($fio, $f, $placeHolder) = @_; my($dir, $file); + return if ( $placeHolder && $fio->{phase} > 0 ); + if ( $f->{name} =~ m{(.*)/(.*)}s ) { $file = $2; $dir = "$fio->{shareM}/" . $1; @@ -450,10 +455,13 @@ sub attribSet $file = $f->{name}; } - if ( !defined($fio->{attribLastDir}) || $fio->{attribLastDir} ne $dir ) { + if ( $dir ne "" + && (!defined($fio->{attribLastDir}) || $fio->{attribLastDir} ne $dir) ) { # # Flush any directories that don't match the first part - # of the new directory + # of the new directory. Don't flush the top-level directory + # (ie: $dir eq "") since the "." might get sorted in the middle + # of other top-level directories or files. # foreach my $d ( keys(%{$fio->{attrib}}) ) { next if ( $d eq "" || "$dir/" =~ m{^\Q$d/} ); @@ -462,17 +470,29 @@ sub attribSet $fio->{attribLastDir} = $dir; } if ( !exists($fio->{attrib}{$dir}) ) { + $fio->log("attribSet: dir=$dir not found") if ( $fio->{logLevel} >= 4 ); $fio->{attrib}{$dir} = BackupPC::Attrib->new({ compress => $fio->{xfer}{compress}, }); - my $path = $fio->{outDir} . $dir; - if ( -f $fio->{attrib}{$dir}->fileName($path) - && !$fio->{attrib}{$dir}->read($path) ) { - $fio->log(sprintf("Unable to read attribute file %s", + my $dirM = $dir; + $dirM = $1 . "/" . $fio->{bpc}->fileNameMangle($2) + if ( $dirM =~ m{(.*?)/(.*)}s ); + my $path = $fio->{outDir} . $dirM; + if ( -f $fio->{attrib}{$dir}->fileName($path) ) { + if ( !$fio->{attrib}{$dir}->read($path) ) { + $fio->log(sprintf("Unable to read attribute file %s", $fio->{attrib}{$dir}->fileName($path))); + } else { + $fio->log(sprintf("attribRead file %s", + $fio->{attrib}{$dir}->fileName($path))) + if ( $fio->{logLevel} >= 4 ); + } } + } else { + $fio->log("attribSet: dir=$dir exists") if ( $fio->{logLevel} >= 4 ); } - $fio->log("attribSet(dir=$dir, file=$file)") if ( $fio->{logLevel} >= 4 ); + $fio->log("attribSet(dir=$dir, file=$file, size=$f->{size}, placeholder=$placeHolder)") + if ( $fio->{logLevel} >= 4 ); my $mode = $f->{mode}; @@ -493,11 +513,6 @@ sub attribWrite my($fio, $d) = @_; my($poolWrite); - # - # Don't write attributes on 2nd phase - they're already - # taken care of during the first phase. - # - return if ( $fio->{phase} > 0 ); if ( !defined($d) ) { # # flush all entries (in reverse order) @@ -508,6 +523,7 @@ sub attribWrite return; } return if ( !defined($fio->{attrib}{$d}) ); + # # Set deleted files in the attributes. Any file in the view # that doesn't have attributes is flagged as deleted for @@ -544,7 +560,7 @@ sub attribWrite }) if ( $fio->{logLevel} >= 2 && $a->{type} == BPC_FTYPE_FILE ); } - } elsif ( !$fio->{full} ) { + } elsif ( $fio->{phase} == 0 && !$fio->{full} ) { ##print("Delete file $f\n"); $fio->logFileAction("delete", { %{$fio->{viewCache}{$d}{$f}}, @@ -562,7 +578,7 @@ sub attribWrite } } } - if ( $fio->{attrib}{$d}->fileCount ) { + if ( $fio->{attrib}{$d}->fileCount || $fio->{phase} > 0 ) { my $data = $fio->{attrib}{$d}->writeData; my $dirM = $d; @@ -586,7 +602,10 @@ sub processClose my($exists, $digest, $outSize, $errs) = $poolWrite->close; $fileName =~ s{^/+}{}; - $fio->log(@$errs) if ( defined($errs) && @$errs ); + if ( defined($errs) && @$errs ) { + $fio->log(@$errs); + $fio->{stats}{errorCnt} += @$errs; + } if ( $doStats ) { $fio->{stats}{TotalFileCnt}++; $fio->{stats}{TotalFileSize} += $origSize; @@ -628,7 +647,7 @@ sub makePath $fio->logFileAction("create", $f) if ( $fio->{logLevel} >= 1 ); $fio->log("makePath($path, 0777)") if ( $fio->{logLevel} >= 5 ); $path = $1 if ( $path =~ /(.*)/s ); - File::Path::mkpath($path, 0, 0777) if ( !-d $path ); + eval { File::Path::mkpath($path, 0, 0777) } if ( !-d $path ); return $fio->attribSet($f) if ( -d $path ); $fio->log("Can't create directory $path"); $fio->{stats}{errorCnt}++; @@ -1145,11 +1164,11 @@ sub fileDeltaRxDone if ( $phase > 0 ) { $fio->log("$name: fatal error: md4 doesn't match on retry;" . " file removed"); + $fio->{stats}{errorCnt}++; } else { $fio->log("$name: md4 doesn't match: will retry in phase 1;" . " file removed"); } - $fio->{stats}{errorCnt}++; if ( defined($fio->{rxOutFd}) ) { $fio->{rxOutFd}->close; unlink($fio->{rxOutFile});