--- a/bin/ftbackup Fri Apr 29 17:41:13 2011 +0200
+++ b/bin/ftbackup Mon May 02 14:28:18 2011 +0200
@@ -14,6 +14,7 @@
use Cwd qw(realpath);
use English qw(-no_match_vars);
use if $ENV{DEBUG} => qw(Smart::Comments);
+use File::Temp;
$ENV{LC_ALL} = "C";
@@ -40,6 +41,7 @@
sub slurp($);
sub get_configs(@);
sub get_candidates();
+sub get_excludes($@);
sub verbose(@);
sub update_devnames($$$);
sub get_history(@);
@@ -94,9 +96,11 @@
# get the backup candiates -> all file systems from /etc/fstab
# with a dump frequence > 0
my @devs = get_candidates();
+ get_excludes(\%cf, @devs);
### %cf
### @devs
+ ### x: exit
verbose +(map { "candidate: $_->{dev} as $_->{rdev}\n" } @devs), "\n";
@@ -175,7 +179,6 @@
$dir =~ s/_/__/g;
$dir =~ s/\//_/g;
$dir = "$cf{FTP_DIR}/$dir";
-
my @last;
if ($ftp) {
$ftp->home();
@@ -299,7 +302,7 @@
if $opt_dumpdates;
exec
-"dump -$dev->{level} -L $label -f- -u -z$cf{COMPRESSION_LEVEL} $dev->{dump}"
+"dump -$dev->{level} -L $label -f- -u -z$cf{COMPRESSION_LEVEL} -E $dev->{exclude}{inodes} $dev->{dump}"
. "| openssl enc -pass env:key -salt -blowfish";
die "Can't exec dumper\n";
};
@@ -330,6 +333,49 @@
print STDERR @_;
}
+sub get_excludes($@) {
+ my $cf = shift;
+ my @devs = @_;
+
+ foreach my $dev (@devs) {
+
+ 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) {
+ # executable exclude list
+ # <inum><space><filename><NULL>
+ local $/ = "\0";
+ open(my $ex, "-|", "$excludelist") or die "Can't open $excludelist: $!\n";
+ while (<$ex>) {
+ chomp;
+ my ($i, $f) = split " ", $_;
+ $inodes{$i} = undef;
+ $files{$f} = undef;
+ }
+ }
+ else {
+ open(my $ex, "<", $excludelist) or die "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;
+
+ # keep the FH to avoid removing the tmp files
+ $dev->{exclude}{files0} = $exclude_files0;
+ $dev->{exclude}{inodes} = $exclude_inodes;
+ }
+ return;
+}
+
sub get_candidates() {
# return the list of backup candidates
@@ -395,6 +441,11 @@
map { chomp } values %h;
%r = (%r, %h);
}
+ foreach (grep /^EXCLUDE:/ => keys %r) {
+ /^EXCLUDE:(\S+)/;
+ $r{EXCLUDE}{$1} = delete $r{$_};
+ }
+ ### %r
return %r;
}
@@ -528,7 +579,7 @@
sub get_estimate($$) {
my ($dev, $level) = @_;
print STDERR "% estimating $dev->{rdev} at level $level: ";
- chomp(my $_ = `dump -S -$level $dev->{rdev}`);
+ chomp(my $_ = `dump -S -$level -E $dev->{exclude}{inodes} $dev->{rdev}`);
print STDERR human_number($_) . "Byte\n";
return $_;
}
@@ -719,6 +770,7 @@
COMPRESSION_LEVEL = 6
FULL_CYCLE = 7
KEEP = 2
+ EXCLUDE:<devpath> = <exclude file>
=over
@@ -754,6 +806,19 @@
normally you'll get KEEP backups in your backup directory. Useless
incremental backups are deleted automgically.
+=item EXCLUDE
+
+Here you may configure a list of files to be excluded on a per file system base
+
+ EXCLUDE:/dev/md1 = /etc/ftbackup.d/md1.exclude
+
+This file should contain a list (line by line) of files to be excluded from the
+backup. The file may be executable (similiar to the automounter executable maps),
+in that case, the file is expected to print a list of records. Each record contains of
+two space separated fields, inode number and the file name. The records are delimited by
+a NULL character.
+
+
=back
=head2 F<.netrc>
--- a/ftbackup.conf.example Fri Apr 29 17:41:13 2011 +0200
+++ b/ftbackup.conf.example Mon May 02 14:28:18 2011 +0200
@@ -26,3 +26,5 @@
# Always keep this number of (full) backups
# (including the current one)
# KEEP = 2
+
+# EXCLUDE:<fs> = <name of exclude list>