allow exclude lists in the config file
authorHeiko Schlittermann (CTQ.kx.schlittermann.de) <hs@schlittermann.de>
Mon, 02 May 2011 14:28:18 +0200
changeset 67 4dd23211874a
parent 66 e0bf36e68caf
child 68 73e32571b22f
allow exclude lists in the config file
bin/ftbackup
ftbackup.conf.example
--- 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>