--- a/bin/ftbackup Tue Aug 02 11:26:26 2011 +0200
+++ b/bin/ftbackup Tue Aug 02 11:26:49 2011 +0200
@@ -21,34 +21,36 @@
$ENV{LC_ALL} = "C";
-my $ME = basename $0;
+my $ME = basename $0;
-my $VERSION = "1.8";
+my $VERSION = "1.8";
my $LOG_LEVEL = $ALL;
my @CONFIGS = ("/etc/$ME.conf", "$ENV{HOME}/.$ME.conf", "$ME.conf");
-Log::Log4perl->easy_init({
- level => $ALL,
- file => -t STDERR ? "STDERR" : ">/var/log/ftbackup/log",
- layout => "[%-6p{1} - %d] %m%n"
- });
+Log::Log4perl->easy_init(
+ {
+ level => $ALL,
+ file => -t STDERR ? "STDERR" : ">/var/log/ftbackup/log",
+ layout => "[%-6p{1} - %d] %m%n"
+ }
+);
my $HOSTNAME = hostname;
my %o = (
- level => undef,
- debug => 0,
- verbose => 0,
- dry => 0,
- force => 0,
- label => "daily",
- info => 0,
- config => "",
- clean => 1,
- dumpdates => "/var/lib/dumpdates",
-); lock_keys(%o);
-
+ level => undef,
+ debug => 0,
+ verbose => 0,
+ dry => 0,
+ force => 0,
+ label => "daily",
+ info => 0,
+ config => "",
+ clean => 1,
+ dumpdates => "/var/lib/dumpdates",
+);
+lock_keys(%o);
sub slurp($);
sub get_configs(@);
@@ -79,7 +81,6 @@
my $started;
END { ALWAYS "STOP" if $started; }
-
MAIN: {
Getopt::Long::Configure("bundling");
@@ -175,9 +176,9 @@
}
$ftp = new FTP(
- $cf{FTP_HOST},
- Passive => $cf{FTP_PASSIVE},
- Debug => $o{debug},
+ $cf{FTP_HOST},
+ Passive => $cf{FTP_PASSIVE},
+ Debug => $o{debug},
) or LOGDIE $@;
$ftp->login or LOGDIE $ftp->message;
$ftp->home($ftp->try(pwd => ()));
@@ -185,7 +186,6 @@
$ftp->try(mkpath => $cf{FTP_DIR});
$ftp->try(cwd => $cf{FTP_DIR});
-
# and now we can start doing something with our filesystems
DEVICE: foreach my $dev (@devs) {
my $dir = $dev->{mountpoint};
@@ -206,13 +206,13 @@
# FIXME: currently we simply run a full dump every FULL_CYCLE
# days, the intermediate dumps are level 1
foreach (reverse sort $ftp->ls) {
- next if /\.tmp-\d+$/;
+ next if /\.tmp-\d+$/;
next if not /^(?<date>.*)\.(?<level>\d+)$/;
- next if not $ftp->size($_) and str2time($+{date}) < $^T;
+ next if not $ftp->size($_) and str2time($+{date}) < $^T;
$last[$+{level}] = str2time $+{date};
}
}
- ### @last
+ ### @last
# for safety we check if there is really a full dump not older than xxx days
if ($dev->{level} > 0) {
@@ -257,8 +257,7 @@
(grep /lv name/i, `lvdisplay $snap`)[0] =~ /(\S+)\s*$/;
for (my $retries = 3 ; $retries ; $retries--) {
- system($_ =
- "fsck -f @{[$o{verbose} ? '-C0' : '']} -y $device");
+ system($_ = "fsck -f @{[$o{verbose} ? '-C0' : '']} -y $device");
last if not $?;
INFO "fsck on $device (using: $_) failed"
. ($retries > 1 ? ", retrying…\n" : "") . "\n";
@@ -325,8 +324,8 @@
if ($ftp) {
verbose("sending dump to " . $ftp->pwd . "/$file.tmp-$^T\n");
- $ftp->try(put => $dump, "$file.tmp-$^T");
- $ftp->try(rename => "$file.tmp-$^T", $file);
+ $ftp->try(put => $dump, "$file.tmp-$^T");
+ $ftp->try(rename => "$file.tmp-$^T", $file);
}
else {
print while <$dump>;
@@ -351,44 +350,47 @@
}
sub get_excludes($@) {
- my $cf = shift;
+ my $cf = shift;
my @devs = @_;
foreach my $dev (@devs) {
- my $exclude_files0 = File::Temp->new;
- my $exclude_inodes = File::Temp->new;
+ my $exclude_files0 = File::Temp->new;
+ my $exclude_inodes = File::Temp->new;
+
+ if (my $excludelist = $cf->{EXCLUDE}{ $dev->{dev} }) {
+ my (%files, %inodes);
+ if (-x $excludelist) {
- if (my $excludelist = $cf->{EXCLUDE}{$dev->{dev}}) {
- my (%files, %inodes);
- if (-x $excludelist) {
- # executable exclude list
- # <inum><space><filename><NULL>
- local $/ = "\0";
- open(my $ex, "-|", "$excludelist") or LOGDIE "Can't open $excludelist: $!\n";
- while (<$ex>) {
- chomp;
- my ($i, $f) = split " ", $_;
- $inodes{$i} = undef;
- $files{$f} = undef;
- }
- }
- else {
- open(my $ex, "<", $excludelist) or LOGDIE "Can't open $excludelist: $!\n";
- while (<$ex>) { chomp; @files{(glob)} = () }
- @inodes{ map { (stat)[1] } keys %files} = ();
+ # executable exclude list
+ # <inum><space><filename><NULL>
+ local $/ = "\0";
+ open(my $ex, "-|", "$excludelist")
+ or LOGDIE "Can't open $excludelist: $!\n";
+ while (<$ex>) {
+ chomp;
+ my ($i, $f) = split " ", $_;
+ $inodes{$i} = undef;
+ $files{$f} = undef;
+ }
+ }
+ else {
+ open(my $ex, "<", $excludelist)
+ or LOGDIE "Can't open $excludelist: $!\n";
+ while (<$ex>) { chomp; @files{ (glob) } = () }
+ @inodes{ map { (stat)[1] } keys %files } = ();
- }
+ }
- foreach (keys %files) { print {$exclude_files0} $_, "\0" }
- foreach (keys %inodes) { say {$exclude_inodes} $_ }
- }
- $exclude_files0->flush;
- $exclude_inodes->flush;
+ foreach (keys %files) { print {$exclude_files0} $_, "\0" }
+ foreach (keys %inodes) { say {$exclude_inodes} $_ }
+ }
+ $exclude_files0->flush;
+ $exclude_inodes->flush;
- # keep the FH to avoid removing the tmp files
- $dev->{exclude}{files0} = $exclude_files0;
- $dev->{exclude}{inodes} = $exclude_inodes;
+ # keep the FH to avoid removing the tmp files
+ $dev->{exclude}{files0} = $exclude_files0;
+ $dev->{exclude}{inodes} = $exclude_inodes;
}
return;
}
@@ -459,8 +461,8 @@
%r = (%r, %h);
}
foreach (grep /^EXCLUDE:/ => keys %r) {
- /^EXCLUDE:(\S+)/;
- $r{EXCLUDE}{$1} = delete $r{$_};
+ /^EXCLUDE:(\S+)/;
+ $r{EXCLUDE}{$1} = delete $r{$_};
}
### %r
return %r;
@@ -536,7 +538,7 @@
$rdev = `blkid -c /dev/null -o device -t '$dev'`;
}
else {
- $rdev = `blkid -c /dev/null -o device '$dev'`;
+ $rdev = `blkid -c /dev/null -o device '$dev'`;
}
chomp $rdev if $rdev;
return $rdev;
@@ -610,29 +612,30 @@
sub calculate_level($@) {
my ($cycle, @devs) = @_;
-
foreach my $dev (@devs) {
- if (!$dev->{last}
+ if ( !$dev->{last}
or not $dev->{last}[0]
or $^T - $dev->{last}[0] > ($cycle * 86_400))
{
$dev->{level} = 0;
}
- elsif (defined $o{level}) {
- $dev->{level} = $o{level}
- }
- else {
- my @estimates;
- for (my $l = 0; $l < 9; ++$l) {
- $estimates[$l] //= get_estimate($dev, $l);
- $estimates[$l + 1] //= get_estimate($dev, $l + 1);
- if (($estimates[$l] - $estimates[$l + 1]) / $estimates[$l] < 0.1) {
- $dev->{level} = $l;
- last;
- }
- }
+ elsif (defined $o{level}) {
+ $dev->{level} = $o{level};
}
- INFO "$dev->{dev} will use level $dev->{level}\n";
+ else {
+ my @estimates;
+ for (my $l = 0 ; $l < 9 ; ++$l) {
+ $estimates[$l] //= get_estimate($dev, $l);
+ $estimates[$l + 1] //= get_estimate($dev, $l + 1);
+ if (($estimates[$l] - $estimates[$l + 1]) / $estimates[$l] <
+ 0.1)
+ {
+ $dev->{level} = $l;
+ last;
+ }
+ }
+ }
+ INFO "$dev->{dev} will use level $dev->{level}\n";
}
return @devs;
@@ -649,16 +652,16 @@
my @dumps;
foreach ($ftp->ls) {
- if (/\.tmp-(?<timestamp>\d+)$/ and $+{timestamp} < $^T) {
- INFO "removing old tmp file $_";
- $ftp->delete($_);
- next;
- };
+ if (/\.tmp-(?<timestamp>\d+)$/ and $+{timestamp} < $^T) {
+ INFO "removing old tmp file $_";
+ $ftp->delete($_);
+ next;
+ }
/^(?<date>.*)\.(?<level>\d+)$/ or next;
- if (not $ftp->size($_) and str2time($+{date}) < $^T) {
- INFO "removing old zero size backup $_";
- $ftp->delete($_);
- next;
+ if (not $ftp->size($_) and str2time($+{date}) < $^T) {
+ INFO "removing old zero size backup $_";
+ $ftp->delete($_);
+ next;
}
push @{ $dumps[$+{level}] } =>
{ file => $_, date => $+{date}, stamp => str2time($+{date}) };
@@ -671,30 +674,32 @@
my @unlink;
if ($dumps[0]) {
- @{ $dumps[0] } = sort { $a->{stamp} <=> $b->{stamp} } @{ $dumps[0] };
+ @{ $dumps[0] } = sort { $a->{stamp} <=> $b->{stamp} } @{ $dumps[0] };
- if ($keep =~ /^\d+$/) {
- $keep += $extra;
- @unlink = splice(@{ $dumps[0] }, 0, -$keep);
- }
- elsif (my ($n, $u) = ($keep =~ /^(\d+)([mhdw])$/i)) {
- given($u) {
- when(/m/i) { $keep = $n * 60 };
- when(/h/i) { $keep = $n * 3600 };
- when(/d/i) { $keep = $n * 86400 };
- when(/w/i) { $keep = $n * 604800 };
- }
- while (@{$dumps[0]} and $dumps[0][0]->{stamp} < (time - $keep)) {
- push @unlink, shift @{$dumps[0]};
- }
- }
- else { LOGDIE "Can't parse the keep time ``$keep''" }
+ if ($keep =~ /^\d+$/) {
+ $keep += $extra;
+ @unlink = splice(@{ $dumps[0] }, 0, -$keep);
+ }
+ elsif (my ($n, $u) = ($keep =~ /^(\d+)([mhdw])$/i)) {
+ given ($u) {
+ when (/m/i) { $keep = $n * 60 };
+ when (/h/i) { $keep = $n * 3600 };
+ when (/d/i) { $keep = $n * 86400 };
+ when (/w/i) { $keep = $n * 604800 };
+ }
+ while (@{ $dumps[0] } and $dumps[0][0]->{stamp} < (time - $keep)) {
+ push @unlink, shift @{ $dumps[0] };
+ }
+ }
+ else { LOGDIE "Can't parse the keep time ``$keep''" }
}
### @dumps
- if (@dumps[1..$#dumps]) {
- if (!$dumps[0] or !@{ $dumps[0] }) { push @unlink, @{ @dumps[1 .. $#dumps] } }
+ if (@dumps[1 .. $#dumps]) {
+ if (!$dumps[0] or !@{ $dumps[0] }) {
+ push @unlink, @{ @dumps[1 .. $#dumps] };
+ }
else {
push @unlink => grep { $_->{stamp} <= $dumps[0][0]{stamp} }
@{ @dumps[1 .. $#dumps] };