# HG changeset patch # User Heiko Schlittermann (CTQ.kx.schlittermann.de) # Date 1304339298 -7200 # Node ID 4dd23211874a4571b303417a4cc9ec67b7e88e3d # Parent e0bf36e68caf28269cf4cd61ea2f2daacb807634 allow exclude lists in the config file diff -r e0bf36e68caf -r 4dd23211874a bin/ftbackup --- 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 + # + 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: = =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> diff -r e0bf36e68caf -r 4dd23211874a ftbackup.conf.example --- 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: =