lintian doesn't like orphan packages with uploaders...
[debian/amanda] / server-src / amrmtape.pl
index 05a1fb635d5e0e43035d6590447e1f2e4843b4f3..2f9ec576cfab3517e7632407439a3138fab86ca0 100644 (file)
@@ -1,10 +1,11 @@
 #!@PERL@
 #
-# Copyright (c) 2008,2009 Zmanda, Inc.  All Rights Reserved.
+# Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
 #
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 as published
-# by the Free Software Foundation.
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -33,6 +34,7 @@ use Amanda::MainLoop;
 use Amanda::Tapelist;
 use Amanda::Util qw( :constants );
 use File::Copy;
+use File::Basename;
 use Getopt::Long;
 
 my $amadmin = "$sbindir/amadmin";
@@ -46,26 +48,6 @@ my $changer_name;
 my $keep_label;
 my $verbose = 1;
 my $help;
-my $logdir;
-my $log_file;
-my $log_created = 0;
-
-sub die_handler {
-    if ($log_created == 1) {
-        unlink $log_file;
-        $log_created = 0;
-    }
-}
-$SIG{__DIE__} = \&die_handler;
-
-sub int_handler {
-    if ($log_created == 1) {
-        unlink $log_file;
-        $log_created = 0;
-    }
-    die "Interrupted\n";
-}
-$SIG{INT} = \&int_handler;
 
 sub usage() {
     print <<EOF
@@ -106,7 +88,10 @@ Amanda::Util::setup_application("amrmtape", "server", $CONTEXT_CMDLINE);
 
 my $config_overrides = new_config_overrides( scalar(@ARGV) + 1 );
 
+debug("Arguments: " . join(' ', @ARGV));
+Getopt::Long::Configure(qw{ bundling });
 my $opts_ok = GetOptions(
+    'version' => \&Amanda::Util::version_opt,
     "changer=s" => \$changer_name,
     "cleanup" => \$cleanup,
     "dryrun|n" => \$dry_run,
@@ -145,26 +130,6 @@ if ($cfgerr_level >= $CFGERR_WARNINGS) {
 }
 
 Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER);
-$logdir = config_dir_relative(getconf($CNF_LOGDIR));
-$log_file = "$logdir/log";
-
-if ($erase) {
-    # Check for log file existance
-    if (-e $log_file) {
-        `amcleanup -p $config_name`;
-    }
-
-    if (-e $log_file) {
-        local *LOG;
-        open(LOG,  $log_file);
-        my $info_line = <LOG>;
-        close LOG;
-        $info_line =~ /^INFO (.*) .* pid .*$/;
-        my $process_name = $1;
-        print "$process_name is running, or you must run amcleanup\n";
-        exit 1;
-    }
-}
 
 # amadmin may later try to load this and will die if it has errors
 # load it now to catch the problem sooner (before we might erase data)
@@ -174,37 +139,42 @@ if ($cfgerr_level >= $CFGERR_ERRORS) {
     die "Errors processing disklist";
 }
 
-my $scrub_db = sub {
-    my $tapelist_file = config_dir_relative(getconf($CNF_TAPELIST));
-    my $tapelist = Amanda::Tapelist::read_tapelist($tapelist_file);
-    unless ($tapelist) {
-        die "Could not read the tapelist";
-    }
+my $tapelist_file = config_dir_relative(getconf($CNF_TAPELIST));
+my $tapelist = Amanda::Tapelist->new($tapelist_file, !$dry_run);
+unless ($tapelist) {
+    die "Could not read the tapelist";
+}
+
 
+my $scrub_db = sub {
+    my $t = $tapelist->lookup_tapelabel($label);
     if ($keep_label) {
-        my $t = $tapelist->lookup_tapelabel($label);
         $t->{'datestamp'} = 0 if $t;
+    } elsif (!defined $t) {
+       print "label '$label' not found in $tapelist_file\n";
+       exit 0;
     } else {
         $tapelist->remove_tapelabel($label);
     }
-    my $tmp_tapelist_file = "$AMANDA_TMPDIR/tapelist-amrmtape-" . time();
-    my $backup_tapelist_file = "$AMANDA_TMPDIR/tapelist-backup-amrmtape-" . time();
-    unless (copy($tapelist_file, $backup_tapelist_file)) {
-        die "Failed to copy/backup $tapelist_file to $backup_tapelist_file";
+
+    #take a copy in case we roolback
+    my $backup_tapelist_file = dirname($tapelist_file) . "-backup-amrmtape-" . time();
+    if (-x $tapelist_file) {
+       unless (copy($tapelist_file, $backup_tapelist_file)) {
+           die "Failed to copy/backup $tapelist_file to $backup_tapelist_file";
+       }
     }
-    # writing to temp and then moving is generally safer than writing directly
+
     unless ($dry_run) {
-        $tapelist->write($tmp_tapelist_file);
-        unless (move($tmp_tapelist_file, $tapelist_file)) {
-            die "Failed to replace old tapelist  with new tapelist.";
-        }
+        $tapelist->write();
     }
 
-    my $tmp_curinfo_file = "$AMANDA_TMPDIR/curinfo-amrmtape-" . time();
+    my $tmp_curinfo_file = "$AMANDA_TMPDIR/curinfo-amrmtape-" . time() . "-" . $$;
     unless (open(AMADMIN, "$amadmin $config_name export |")) {
         die "Failed to execute $amadmin: $! $?";
     }
-    open(CURINFO, ">$tmp_curinfo_file");
+    open(CURINFO, ">$tmp_curinfo_file") or
+        die "Failed to open $tmp_curinfo_file for writing: $! $?";
 
     sub info_line($) {
         print CURINFO "$_[0]";
@@ -234,7 +204,7 @@ my $scrub_db = sub {
             }
             my $level = $parts[1];
             my $cur_label = $parts[7];
-            if ($cur_label eq $label) {
+            if (defined $cur_label and $cur_label eq $label) {
                 $dead_level = $level;
                 vlog "Discarding Host: $host, Disk: $disk, Level: $level\n";
             } elsif ( $level > $dead_level ) {
@@ -286,12 +256,7 @@ my $scrub_db = sub {
 
 my $erase_volume = make_cb('erase_volume' => sub {
     if ($erase) {
-        $log_created = 1;
-        local *LOG;
-        open(LOG, ">$log_file");
-        print LOG "INFO amrmtape amrmtape pid $$\n";
-        close LOG;
-       my $chg = Amanda::Changer->new($changer_name);
+       my $chg = Amanda::Changer->new($changer_name, tapelist => $tapelist);
        $chg->load(
            'label' => $label,
            'res_cb' => sub {
@@ -301,24 +266,36 @@ my $erase_volume = make_cb('erase_volume' => sub {
                 my $dev = $resv->{'device'};
                 die "Can not erase $label because the device doesn't support this feature"
                     unless $dev->property_get('full_deletion');
-                if (!$dry_run) {
-                    $dev->erase()
-                        or die "Failed to erase volume";
-                    $dev->finish();
 
-                    # label the tape with the same label it had
-                    if ($keep_label) {
-                        $dev->start($ACCESS_WRITE, $label, undef)
-                            or die "Failed to write tape label";
-                    }
-                }
+               my $rel_cb = make_cb('rel_cb' => sub {
+                   $resv->release(finished_cb => sub {
+                       my ($err) = @_;
 
-               $resv->release(finished_cb => sub {
-                   my ($err) = @_;
-                   die $err if $err;
+                       $chg->quit();
+                       die $err if $err;
 
-                   $scrub_db->();
+                       $scrub_db->();
+                   });
                });
+
+                if (!$dry_run) {
+                    $dev->erase()
+                        or die "Failed to erase volume";
+                   $resv->set_label(finished_cb => sub {
+                       $dev->finish();
+
+                       # label the tape with the same label it had
+                       if ($keep_label) {
+                           $dev->start($ACCESS_WRITE, $label, undef)
+                               or die "Failed to write tape label";
+                           return $resv->set_label(label => $label, finished_cb => $rel_cb);
+                       }
+                       $rel_cb->();
+                   });
+               } else {
+                   $rel_cb->();
+               }
+
             });
     } else {
         $scrub_db->();
@@ -329,9 +306,4 @@ my $erase_volume = make_cb('erase_volume' => sub {
 $erase_volume->();
 Amanda::MainLoop::run();
 
-if ($log_created == 1) {
-    unlink $log_file;
-    $log_created = 0;
-}
-
 Amanda::Util::finish_application();