-# 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
use strict;
use warnings;
+use Carp;
use vars qw( @ISA );
@ISA = qw( Amanda::Changer );
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);
};
step locked => sub {
+ my $err = shift;
+ return $cb->($err) if $err;
$self->with_locked_state($self->{'state_filename'},
sub { my @args = @_;
$self->try_unlock();
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");
}
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'}) {
}
}
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;
}
}
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;
!$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'}'");
$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 {