diff --git a/bin/pg_backrest.pl b/bin/pg_backrest.pl index cb9754434..f6abb3754 100755 --- a/bin/pg_backrest.pl +++ b/bin/pg_backrest.pl @@ -130,24 +130,6 @@ eval { #################################################################################################################################### config_load(); -# Display version and exit if requested -if (param_get(PARAM_VERSION) || param_get(PARAM_HELP)) -{ - print 'pg_backrest ' . version_get() . "\n"; - - if (!param_get(PARAM_HELP)) - { - exit 0; - } -} - -# Display help and exit if requested -if (param_get(PARAM_HELP)) -{ - print "\n"; - pod2usage(); -} - #################################################################################################################################### # DETERMINE IF THERE IS A REMOTE #################################################################################################################################### diff --git a/bin/pg_backrest_remote.pl b/bin/pg_backrest_remote.pl index a31ddaff8..5936bf5b7 100755 --- a/bin/pg_backrest_remote.pl +++ b/bin/pg_backrest_remote.pl @@ -154,9 +154,10 @@ while ($strCommand ne OP_EXIT) { my %oManifestHash; - $oFile->manifest(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), \%oManifestHash); + $oFile->manifest(PATH_ABSOLUTE, param_get(\%oParamHash, 'path'), \%oManifestHash, + param_get(\%oParamHash, 'pause') eq 'y' ? true : false); - my $strOutput = "name\ttype\tuser\tgroup\tpermission\tmodification_time\tinode\tsize\tlink_destination"; + my $strOutput = "name\ttype\tuser\tgroup\tpermission\tmodification_time\tinode\tsize\tlink_destination\tfuture"; foreach my $strName (sort(keys $oManifestHash{name})) { @@ -170,7 +171,8 @@ while ($strCommand ne OP_EXIT) (defined($oManifestHash{name}{"${strName}"}{inode}) ? $oManifestHash{name}{"${strName}"}{inode} : "") . "\t" . (defined($oManifestHash{name}{"${strName}"}{size}) ? $oManifestHash{name}{"${strName}"}{size} : "") . "\t" . (defined($oManifestHash{name}{"${strName}"}{link_destination}) ? - $oManifestHash{name}{"${strName}"}{link_destination} : ""); + $oManifestHash{name}{"${strName}"}{link_destination} : "") . "\t" . + (defined($oManifestHash{name}{"${strName}"}{future}) ? $oManifestHash{name}{"${strName}"}{future} : ""); } $oRemote->output_write($strOutput); diff --git a/lib/BackRest/Backup.pm b/lib/BackRest/Backup.pm index 9e818f031..dfd349bcd 100644 --- a/lib/BackRest/Backup.pm +++ b/lib/BackRest/Backup.pm @@ -175,10 +175,6 @@ sub backup_thread_complete # Rejoin the threads while ($iThreadComplete < $iThreadLocalMax) { - # !!! This should be shorter - currently it is this to be sure that backups to not happen more than once a second and cause - # path naming conflicts - sleep(.1); - # If a timeout has been defined, make sure we have not been running longer than that if (defined($iTimeout)) { @@ -220,6 +216,9 @@ sub backup_thread_complete } } } + + # Sleep before trying again + sleep(.1); } &log(DEBUG, 'all threads exited'); diff --git a/lib/BackRest/Config.pm b/lib/BackRest/Config.pm index 625c7625a..a0b7651dc 100644 --- a/lib/BackRest/Config.pm +++ b/lib/BackRest/Config.pm @@ -7,6 +7,7 @@ use threads; use strict; use warnings; use Carp; +use Pod::Usage; use File::Basename; use Getopt::Long; @@ -171,6 +172,24 @@ sub config_load PARAM_TEST, PARAM_TEST_DELAY . '=s', PARAM_TEST_NO_FORK) or pod2usage(2); + # Display version and exit if requested + if (param_get(PARAM_VERSION) || param_get(PARAM_HELP)) + { + print 'pg_backrest ' . version_get() . "\n"; + + if (!param_get(PARAM_HELP)) + { + exit 0; + } + } + + # Display help and exit if requested + if (param_get(PARAM_HELP)) + { + print "\n"; + pod2usage(); + } + # Get and validate the operation $strOperation = $ARGV[0]; diff --git a/lib/BackRest/File.pm b/lib/BackRest/File.pm index c2f8f3e55..32b2a7cbc 100644 --- a/lib/BackRest/File.pm +++ b/lib/BackRest/File.pm @@ -8,9 +8,9 @@ use strict; use warnings; use Carp; -use POSIX; +use POSIX qw(ceil); use Net::OpenSSH; -use File::Basename; +use File::Basename qw(dirname); use File::Copy qw(cp); use File::Path qw(make_path remove_tree); use Digest::SHA; @@ -19,7 +19,7 @@ use Fcntl ':mode'; use IO::Compress::Gzip qw(gzip $GzipError); use IO::Uncompress::Gunzip qw(gunzip $GunzipError); use IO::String; -use Time::HiRes qw/gettimeofday usleep/; +use Time::HiRes qw(gettimeofday usleep); use lib dirname($0) . '/../lib'; use BackRest::Exception; @@ -983,6 +983,7 @@ sub manifest my %oParamHash; $oParamHash{path} = $strPathOp; + $oParamHash{pause} = $bPause ? 'y' : 'n'; # Add remote info to debug string my $strRemote = 'remote (' . $self->{oRemote}->command_param_string(\%oParamHash) . ')'; @@ -1010,7 +1011,18 @@ sub manifest usleep($lSleepMs * 1000); - &log(DEBUG, "slept ${lSleepMs}ms after manifest: begin ${lTimeBegin}, end " . gettimeofday()); + &log(TRACE, "${strOperation}: slept ${lSleepMs}ms after manifest: begin ${lTimeBegin}, end " . gettimeofday()); + + # Now we'll test and make sure that there are no files with modification times in the future. + foreach my $strName (sort(keys ${$oManifestHashRef}{name})) + { + if (defined(${$oManifestHashRef}{name}{$strName}{modification_time}) && + ${$oManifestHashRef}{name}{$strName}{modification_time} > int($lTimeBegin)) + { + ${$oManifestHashRef}{name}{$strName}{modification_time} = int($lTimeBegin); + ${$oManifestHashRef}{name}{$strName}{future} = 'y'; + } + } } } } diff --git a/test/lib/BackRestTest/FileTest.pm b/test/lib/BackRestTest/FileTest.pm index 51c375ea2..1ac1b135f 100755 --- a/test/lib/BackRestTest/FileTest.pm +++ b/test/lib/BackRestTest/FileTest.pm @@ -405,16 +405,16 @@ sub BackRestTestFile_Test &log(INFO, "Test File->manifest()\n"); my $strManifestCompare = - ".,d,${strUser},${strGroup},0770,,,,\n" . - "sub1,d,${strUser},${strGroup},0750,,,,\n" . - "sub1/sub2,d,${strUser},${strGroup},0750,,,,\n" . - "sub1/sub2/test,l,${strUser},${strGroup},,,,,../..\n" . - "sub1/sub2/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" . - "sub1/sub2/test-sub2.txt,f,${strUser},${strGroup},0666,1111111113,0,11,\n" . - "sub1/test,l,${strUser},${strGroup},,,,,..\n" . - "sub1/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,\n" . - "sub1/test-sub1.txt,f,${strUser},${strGroup},0646,1111111112,0,10,\n" . - "test.txt,f,${strUser},${strGroup},1640,1111111111,0,9,"; + ".,d,${strUser},${strGroup},0770,,,,,\n" . + "sub1,d,${strUser},${strGroup},0750,,,,,\n" . + "sub1/sub2,d,${strUser},${strGroup},0750,,,,,\n" . + "sub1/sub2/test,l,${strUser},${strGroup},,,,,../..,\n" . + "sub1/sub2/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,,\n" . + "sub1/sub2/test-sub2.txt,f,${strUser},${strGroup},0666,1111111113,0,11,,\n" . + "sub1/test,l,${strUser},${strGroup},,,,,..,\n" . + "sub1/test-hardlink.txt,f,${strUser},${strGroup},1640,1111111111,0,9,,\n" . + "sub1/test-sub1.txt,f,${strUser},${strGroup},0646,1111111112,0,10,,\n" . + "test.txt,f,${strUser},${strGroup},1640,1111111111,0,9,,"; for (my $bRemote = 0; $bRemote <= 1; $bRemote++) { @@ -430,9 +430,11 @@ sub BackRestTestFile_Test for (my $bError = 0; $bError <= 1; $bError++) { for (my $bExists = 0; $bExists <= 1; $bExists++) + { + for (my $bPause = false; $bPause <= $bExists && !$bError; $bPause++) { if (!BackRestTestCommon_Run(++$iRun, - "rmt ${bRemote}, exists ${bExists}, err ${bError}")) {next} + "rmt ${bRemote}, exists ${bExists}, pause ${bPause}, err ${bError}")) {next} # Setup test directory BackRestTestFile_Setup($bError); @@ -450,7 +452,7 @@ sub BackRestTestFile_Test system("chmod 0640 ${strTestPath}/sub1/test-sub1.txt"); system("echo 'TESTDATA__' > ${strTestPath}/sub1/sub2/test-sub2.txt"); - utime(1111111113, 1111111113, "${strTestPath}/sub1/sub2/test-sub2.txt"); + utime(1111111113, $bPause ? time() + 10 : 1111111113, "${strTestPath}/sub1/sub2/test-sub2.txt"); system("chmod 0646 ${strTestPath}/sub1/test-sub1.txt"); system("ln ${strTestPath}/test.txt ${strTestPath}/sub1/test-hardlink.txt"); @@ -481,7 +483,7 @@ sub BackRestTestFile_Test eval { - $oFile->manifest(PATH_BACKUP_ABSOLUTE, $strPath, \%oManifestHash); + $oFile->manifest(PATH_BACKUP_ABSOLUTE, $strPath, \%oManifestHash, $bPause); }; # Check for an error @@ -520,6 +522,23 @@ sub BackRestTestFile_Test $oManifestHash{name}{"${strName}"}{inode} = 0; } + if ($bPause && $strName eq 'sub1/sub2/test-sub2.txt') + { + if (!(defined($oManifestHash{name}{$strName}{future}) && + $oManifestHash{name}{$strName}{future} eq 'y')) + { + confess "${strName} is not marked as future"; + } + + if ($oManifestHash{name}{$strName}{modification_time} != time() - 1) + { + confess "${strName} does not have future time reset to past"; + } + + delete($oManifestHash{name}{$strName}{future}); + $oManifestHash{name}{$strName}{modification_time} = 1111111113; + } + $strManifest .= "${strName}," . $oManifestHash{name}{"${strName}"}{type} . ',' . @@ -536,7 +555,9 @@ sub BackRestTestFile_Test (defined($oManifestHash{name}{"${strName}"}{size}) ? $oManifestHash{name}{"${strName}"}{size} : '') . ',' . (defined($oManifestHash{name}{"${strName}"}{link_destination}) ? - $oManifestHash{name}{"${strName}"}{link_destination} : ''); + $oManifestHash{name}{"${strName}"}{link_destination} : '') . ',' . + (defined($oManifestHash{name}{"${strName}"}{future}) ? + $oManifestHash{name}{"${strName}"}{future} : ''); } if ($strManifest ne $strManifestCompare) @@ -545,6 +566,7 @@ sub BackRestTestFile_Test } } } + } } }