changed $opt_* to %o
authorroot@weber.ctq.de
Mon, 01 Aug 2011 15:18:30 +0200
changeset 120 e3df82a62762
parent 119 a1a962c17ef3
child 121 7234011fd0e6
changed $opt_* to %o
bin/ftbackup
--- a/bin/ftbackup	Mon Aug 01 14:11:04 2011 +0200
+++ b/bin/ftbackup	Mon Aug 01 15:18:30 2011 +0200
@@ -17,6 +17,7 @@
 use File::Temp;
 use Log::Log4perl qw(:easy);
 use Data::Dumper;
+use Hash::Util qw(lock_keys);
 
 $ENV{LC_ALL} = "C";
 
@@ -35,17 +36,19 @@
 
 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);
 
-my $opt_level     = undef;
-my $opt_debug     = 0;
-my $opt_verbose   = 0;
-my $opt_dry       = 0;
-my $opt_force     = 0;
-my $opt_label     = "daily";
-my $opt_info      = 0;
-my $opt_config    = "";
-my $opt_clean     = 1;
-my $opt_dumpdates = "/var/lib/dumpdates";
 
 sub slurp($);
 sub get_configs(@);
@@ -81,20 +84,20 @@
 
     Getopt::Long::Configure("bundling");
     GetOptions(
-        "l|level=i" => \$opt_level,
-        "L|label=s" => \$opt_label,
-        "d|debug!"  => \$opt_debug,
-        "v|verbose" => \$opt_verbose,
-        "i|info"    => \$opt_info,
-        "dry"       => sub { $opt_dry = 1; $opt_verbose = 1 },
+        "l|level=i" => \$o{level},
+        "L|label=s" => \$o{label},
+        "d|debug!"  => \$o{debug},
+        "v|verbose" => \$o{verbose},
+        "i|info"    => \$o{info},
+        "dry"       => sub { $o{dry} = 1; $o{verbose} = 1 },
 
-        #"f|force"   => \$opt_force,
+        #"f|force"   => \$o{force},
         "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) },
         "m|man"  => sub { pod2usage(-exit => 0, -verbose => 3) },
         "C|config=s" => sub { @CONFIGS = ($_[1]) },
         "V|version" => sub { print "$ME: $VERSION\n"; exit 0 },
-        "c|clean!" => \$opt_clean,
-        "D|dumpdates=s" => \$opt_dumpdates,
+        "c|clean!" => \$o{clean},
+        "D|dumpdates=s" => \$o{dumpdates},
     ) or pod2usage;
 
     $started = time;
@@ -103,7 +106,7 @@
 
     my %cf = (%CONFIG, get_configs(@CONFIGS));
     $cf{FTP_DIR} =~ s/<HOSTNAME>/$HOSTNAME/g;
-    $cf{FTP_DIR} =~ s/<LABEL>/$opt_label/g;
+    $cf{FTP_DIR} =~ s/<LABEL>/$o{label}/g;
 
     # get the backup candiates -> all file systems from /etc/fstab
     # with a dump frequence > 0
@@ -129,13 +132,13 @@
 
     my $ftp;
 
-    # get_history the situation - we rely on $opt_dumpdates
+    # get_history the situation - we rely on $o{dumpdates}
     @devs = get_history(@devs);
     @devs = calculate_level($cf{FULL_CYCLE}, @devs);
 
     ### @devs
 
-    if ($opt_info) {
+    if ($o{info}) {
         my $lr =
           (reverse sort { $a <=> $b } map { length $_->{rdev} } @devs)[0];
         my $ld = (reverse sort { $a <=> $b } map { length $_->{dev} } @devs)[0];
@@ -174,7 +177,7 @@
     $ftp = new FTP(
 	$cf{FTP_HOST},
 	Passive => $cf{FTP_PASSIVE},
-	Debug   => $opt_debug,
+	Debug   => $o{debug},
     ) or LOGDIE $@;
     $ftp->login or LOGDIE $ftp->message;
     $ftp->home($ftp->try(pwd => ()));
@@ -197,13 +200,14 @@
 
             #verbose "Now in @{[$ftp->pwd]}.\n" if $ftp;
             unlink_old_dumps($ftp, $cf{KEEP}, 1)
-              if $opt_clean;
+              if $o{clean};
 
             # examine the situation and decide about the level
             # FIXME: currently we simply run a full dump every FULL_CYCLE
             # days, the intermediate dumps are level 1
             foreach (reverse sort $ftp->ls) {
-                /^(?<date>.*)\.(?<level>\d+)$/ or next;
+                next if not /^(?<date>.*)\.(?<level>\d+)$/;
+		next if not $ftp->size(0) and str2time($+{date}) < $^T;
                 $last[$+{level}] = str2time $+{date};
             }
         }
@@ -226,7 +230,7 @@
         my $label = basename($dev->{rdev});
         verbose
 "> $dev->{dev} ($dev->{rdev}\@$dev->{mountpoint}) to @{[$ftp->pwd]}/$file\n";
-        next if $opt_dry;
+        next if $o{dry};
 
         # For LVM do a snapshot, for regular partitions
         # do nothing. But anyway the device to dump is named in $dev->{dump}
@@ -234,7 +238,7 @@
 
             # we can do a snapshot
             # FIXME: check the snapshot name is not used already
-            my $snap = "$dev->{lvm}{path}-snap.0";
+            my $snap = "$dev->{lvm}{path}-snap." . time;
 
             verbose "Creating snapshot $snap\n";
             system($_ =
@@ -252,7 +256,7 @@
 
             for (my $retries = 3 ; $retries ; $retries--) {
                 system($_ =
-                      "fsck -f @{[$opt_verbose ? '-C0' : '']} -y $device");
+                      "fsck -f @{[$o{verbose} ? '-C0' : '']} -y $device");
                 last if not $?;
                 INFO "fsck on $device (using: $_) failed"
                   . ($retries > 1 ? ", retrying…\n" : "") . "\n";
@@ -308,8 +312,8 @@
 #-- START
 __HEAD
 
-            update_devnames($opt_dumpdates, $dev->{rdev} => $dev->{dump})
-              if $opt_dumpdates;
+            update_devnames($o{dumpdates}, $dev->{rdev} => $dev->{dump})
+              if $o{dumpdates};
 
             exec
 "dump -$dev->{level} -L $label -f- -u -z$cf{COMPRESSION_LEVEL} -E $dev->{exclude}{inodes} $dev->{dump}"
@@ -329,17 +333,17 @@
         $dev->{cleanup}->() if $dev->{cleanup};
         verbose "Done.\n";
 
-        update_devnames($opt_dumpdates, $dev->{dump} => $dev->{rdev})
-          if $opt_dumpdates;
+        update_devnames($o{dumpdates}, $dev->{dump} => $dev->{rdev})
+          if $o{dumpdates};
 
         unlink_old_dumps($ftp, $cf{KEEP}, 0)
-          if $ftp and $opt_clean;
+          if $ftp and $o{clean};
     }
 
 }
 
 sub verbose(@) {
-    return if not $opt_verbose;
+    return if not $o{verbose};
     print STDERR @_;
 }
 
@@ -537,16 +541,16 @@
 }
 
 # put the last dump information (level and date) into
-# the device structure - information is obtained from $opt_dumpdates
+# the device structure - information is obtained from $o{dumpdates}
 sub get_history(@) {
     my @devs = @_;
     my %dd;
 
-    open(my $dd, "+>>", $opt_dumpdates);
+    open(my $dd, "+>>", $o{dumpdates});
     seek($dd, 0, 0);
     while (<$dd>) {
         my ($dev, $level, $date) = /^(\S+)\s+(\d+)\s+(.{30})/
-          or LOGDIE "Can't parse $opt_dumpdates: `$_'\n";
+          or LOGDIE "Can't parse $o{dumpdates}: `$_'\n";
         my $rdev  = real_device($dev);
         my $devno = devno($rdev);
 
@@ -606,8 +610,8 @@
         {
             $dev->{level} = 0;
         }
-	elsif (defined $opt_level) {
-	    $dev->{level} = $opt_level
+	elsif (defined $o{level}) {
+	    $dev->{level} = $o{level}
 	}
 	else {
 	    my @estimates;
@@ -638,11 +642,15 @@
 
     foreach ($ftp->ls) {
         /^(?<date>.*)\.(?<level>\d+)$/ or 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}) };
     }
 
-
     # sort the level 0 dumps by date and remove all but the last $keep
     # ones.
     # if we found level 0 dumps, we remove all level 1+ dumps older than
@@ -684,9 +692,10 @@
     TRACE("UNLINK:\n", Dumper \@unlink);
 
     foreach (@unlink) {
-        next if $opt_dry;
+        next if $o{dry};
         $ftp->delete($_->{file});
     }
+exit 0;
 }
 
 #/dev/vda1 0 Thu Apr 14 12:54:31 2011 +0200