Imported Upstream version 3.3.3
[debian/amanda] / perl / Amanda / Changer / disk.pm
index 5b5b3b9416aa895069d2e4ae15ec9ba9b83e7a00..3ff28b688d904e1d56906088c4b46cf9074be7a6 100644 (file)
@@ -1,8 +1,9 @@
-# Copyright (c) 2008,2009,2010 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
@@ -20,6 +21,7 @@ package Amanda::Changer::disk;
 
 use strict;
 use warnings;
+use Carp;
 use vars qw( @ISA );
 @ISA = qw( Amanda::Changer );
 
@@ -100,6 +102,11 @@ sub new {
 
     bless ($self, $class);
 
+    if ($config->{'changerfile'}) {
+       $self->{'state_filename'} = Amanda::Config::config_dir_relative($config->{'changerfile'});
+    }
+    $self->{'lock-timeout'} = $config->get_property('lock-timeout');
+
     $self->{'num-slot'} = $config->get_property('num-slot');
     $self->{'auto-create-slot'} = $config->get_boolean_property(
                                        'auto-create-slot', 0);
@@ -267,6 +274,8 @@ sub with_disk_locked_state {
     };
 
     step locked => sub {
+       my $err = shift;
+       return $cb->($err) if $err;
        $self->with_locked_state($self->{'state_filename'},
            sub { my @args = @_;
                  $self->try_unlock();
@@ -495,7 +504,7 @@ sub _get_slot_label {
 sub _load_drive {
     my ($self, $drive, $slot) = @_;
 
-    die "'$drive' does not exist" unless (-d $drive);
+    confess "'$drive' does not exist" unless (-d $drive);
     if (-e "$drive/data") {
        unlink("$drive/data");
     }
@@ -595,9 +604,8 @@ sub _validate() {
     my $dir = $self->{'dir'};
 
     unless (-d $dir) {
-       $self->{'fatal_error'} = Amanda::Changer->make_error("fatal", undef,
+       return $self->make_error("fatal", undef,
            message => "directory '$dir' does not exist");
-       return;
     }
 
     if ($self->{'removable'}) {
@@ -611,9 +619,9 @@ sub _validate() {
            }
        }
        if ($dev == $pdev) {
-           $self->{'fatal_error'} = Amanda::Changer->make_error("fatal", undef,
+           return $self->make_error("failed", undef,
+               reason => "notfound",
                message => "No removable disk mounted on '$dir'");
-           return;
        }
     }
 
@@ -623,30 +631,36 @@ sub _validate() {
            if (!-e $slot_dir) {
                if ($self->{'auto-create-slot'}) {
                    if (!mkdir ($slot_dir)) {
-                       $self->{'fatal_error'} = Amanda::Changer->make_error("fatal", undef,
+                       return $self->make_error("fatal", undef,
                            message => "Can't create '$slot_dir': $!");
-                       return;
                    }
                } else {
-                   $self->{'fatal_error'} = Amanda::Changer->make_error("fatal", undef,
+                   return $self->make_error("fatal", undef,
                        message => "slot $i doesn't exists '$slot_dir'");
-                   return;
                }
            }
        }
     } else {
        if ($self->{'auto-create-slot'}) {
-           $self->{'fatal_error'} = Amanda::Changer->make_error("fatal", undef,
+           return $self->make_error("fatal", undef,
                message => "property 'auto-create-slot' set but property 'num-slot' is not set");
-           return;
        }
     }
+    return undef;
 }
 
 sub try_lock {
     my $self = shift;
     my $cb = shift;
     my $poll = 0; # first delay will be 0.1s; see below
+    my $time;
+
+    if (defined $self->{'lock-timeout'}) {
+       $time = time() + $self->{'lock-timeout'};
+    } else {
+       $time = time() + 1000;
+    }
+
 
     my $steps = define_steps
        cb_ref => \$cb;
@@ -656,15 +670,18 @@ sub try_lock {
            !$self->{'fl'}->locked()) {
            return $steps->{'lock'}->();
        }
-       $steps->{'done'}->();
+       $steps->{'lock_done'}->();
     };
 
     step lock => sub {
        my $rv = $self->{'fl'}->lock_rd();
-       if ($rv == 1) {
+       if ($rv == 1 && time() < $time) {
            # loop until we get the lock, increasing $poll to 10s
            $poll += 100 unless $poll >= 10000;
            return Amanda::MainLoop::call_after($poll, $steps->{'lock'});
+       } elsif ($rv == 1) {
+           return $self->make_error("fatal", $cb,
+               message => "Timeout trying to lock '$self->{'umount_lockfile'}'");
        } elsif ($rv == -1) {
            return $self->make_error("fatal", $cb,
                message => "Error locking '$self->{'umount_lockfile'}'");
@@ -673,15 +690,14 @@ sub try_lock {
                $self->{'umount_src'}->remove();
                $self->{'umount_src'} = undef;
            }
-           return $steps->{'done'}->();
+           return $steps->{'lock_done'}->();
        }
     };
 
-    step done => sub {
-       $self->_validate();
-       $cb->();
+    step lock_done => sub {
+       my $err = $self->_validate();
+       $cb->($err);
     };
-
 }
 
 sub try_umount {