#! @PERL@
-# Copyright (c) 2009, 2010 Zmanda, Inc. All Rights Reserved.
+# Copyright (c) 2009-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
});
});
-subcommand("show", "show", "scan all slots in the changer, starting with the current slot",
+subcommand("show", "show [<slots>]", "scan all slots (or listed slots) in the changer, starting with the current slot",
sub {
my ($finished_cb, @args) = @_;
my $last_slot;
my %seen_slots;
my $chg;
- if (@args != 0) {
+ if (@args > 1) {
return usage($finished_cb);
}
+ my $what = $args[0];
+ my @slots;
+
+ if (defined $what) {
+ my @what1 = split /,/, $what;
+ foreach my $what1 (@what1) {
+ if ($what1 =~ /^(\d*)-(\d*)$/) {
+ my $begin = $1;
+ my $end = $2;
+ $end = $begin if $begin > $end;
+ while ($begin <= $end) {
+ push @slots, $begin;
+ $begin++;
+ }
+ } else {
+ push @slots, $what1;
+ }
+ }
+ }
+
+ my $use_slots = @slots > 0;
+
$chg = load_changer($finished_cb) or return;
my $steps = define_steps
my ($err, %info) = @_;
return failure($err, $finished_cb) if $err;
- print STDERR "amtape: scanning all $info{num_slots} slots in changer:\n";
+ if ($use_slots) {
+ my $slot = shift @slots;
+ $chg->load(slot => $slot,
+ mode => "read",
+ res_cb => $steps->{'loaded'});
- $steps->{'load_current'}->();
- };
+ } else {
+ print STDERR "amtape: scanning all $info{num_slots} slots in changer:\n";
- step load_current => sub {
- $chg->load(relative_slot => 'current', mode => "read", res_cb => $steps->{'loaded'});
+ $chg->load(relative_slot => 'current',
+ mode => "read",
+ res_cb => $steps->{'loaded'});
+ }
};
step loaded => sub {
return;
} elsif ($err->volinuse and defined $err->{'slot'}) {
$last_slot = $err->{'slot'};
+ print STDERR sprintf("slot %3s: in use\n", $last_slot);
+ } elsif ($err->empty and defined $err->{'slot'}) {
+ $last_slot = $err->{'slot'};
+ print STDERR sprintf("slot %3s: empty\n", $last_slot);
} else {
return failure($err, $finished_cb) if $err;
}
} else {
print STDERR sprintf("slot %3s: %s\n", $last_slot, $dev->error_or_status());
}
- } else {
- print STDERR sprintf("slot %3s: in use\n", $last_slot);
}
if ($res) {
};
step released => sub {
- $chg->load(relative_slot => 'next', slot => $last_slot,
- except_slots => { %seen_slots }, res_cb => $steps->{'loaded'});
+ if ($use_slots) {
+ return $finished_cb->() if @slots == 0;
+ my $slot = shift @slots;
+ $chg->load(slot => $slot,
+ mode => "read",
+ res_cb => $steps->{'loaded'});
+
+ } else {
+ $chg->load(relative_slot => 'next',
+ slot => $last_slot,
+ except_slots => { %seen_slots },
+ res_cb => $steps->{'loaded'});
+ }
};
});
for my $sl (@$inv) {
my $line = "slot $sl->{slot}:";
+ my $tle;
if (!defined($sl->{device_status}) && !defined($sl->{label})) {
$line .= " unknown state";
} elsif ($sl->{'state'} == Amanda::Changer::SLOT_EMPTY) {
} else {
if (defined $sl->{label}) {
$line .= " label $sl->{label}";
- my $tle = $tl->lookup_tapelabel($sl->{label});
- if ($tle->{'meta'}) {
- $line .= " ($tle->{'meta'})";
+ $tle = $tl->lookup_tapelabel($sl->{label});
+ if (defined $tle) {
+ if ($tle->{'meta'}) {
+ $line .= " ($tle->{'meta'})";
+ }
}
} elsif ($sl->{'device_status'} == $DEVICE_STATUS_VOLUME_UNLABELED) {
$line .= " blank";
} elsif ($sl->{'device_status'} != $DEVICE_STATUS_SUCCESS) {
- $line .= "device error";
+ if (defined $sl->{'device_error'}) {
+ $line .= " " . $sl->{'device_error'};
+ } else {
+ $line .= "device error";
+ }
} elsif ($sl->{'f_type'} != $Amanda::Header::F_TAPESTART) {
$line .= " blank";
} else {
if ($sl->{'current'}) {
$line .= " (current)";
}
+ if (defined $tle) {
+ if (defined $sl->{'barcode'} and
+ defined $tle->{'barcode'} and
+ $sl->{'barcode'} ne $tle->{'barcode'}) {
+ $line .= " MISTMATCH barcode in tapelist: $tle->{'barcode'}";
+ }
+ }
# note that inventory goes to stdout
print "$line\n";
} elsif ($dev->status & $DEVICE_STATUS_VOLUME_UNLABELED and
$dev->volume_header and
$dev->volume_header->{'type'} == $Amanda::Header::F_WEIRD) {
- print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+ my $autolabel = getconf($CNF_AUTOLABEL);
+ if ($autolabel->{'non_amanda'}) {
+ print STDERR " contains a non-Amanda volume\n";
+ } else {
+ print STDERR " contains a non-Amanda volume; check and relabel it with 'amlabel -f'\n";
+ }
} elsif ($dev->status & $DEVICE_STATUS_VOLUME_ERROR) {
my $message = $dev->error_or_status();
print STDERR " can't read label: $message\n";
my $result_cb = make_cb(result_cb => sub {
my ($err, $res, $label, $mode) = @_;
if ($err) {
- $taperscan->quit() if defined $taperscan;
- return failure($err, $finished_cb);
+ if ($res) {
+ $res->release(finished_cb => sub {
+ $taperscan->quit() if defined $taperscan;
+ return failure($err, $finished_cb);
+ });
+ return;
+ } else {
+ $taperscan->quit() if defined $taperscan;
+ return failure($err, $finished_cb);
+ }
}
my $modestr = ($mode == $ACCESS_APPEND)? "append" : "write";
my $slot = $res->{'this_slot'};
- print STDERR "Will $modestr to volume $label in slot $slot.\n";
+ if (defined $res->{'device'} and defined $res->{'device'}->volume_label()) {
+ print STDERR "Will $modestr to volume '$label' in slot $slot.\n";
+ } else {
+ my $header = $res->{'device'}->volume_header();
+ if ($header->{'type'} == $Amanda::Header::F_WEIRD) {
+ print STDERR "Will $modestr label '$label' to non-Amanda volume in slot $slot.\n";
+ } else {
+ print STDERR "Will $modestr label '$label' to new volume in slot $slot.\n";
+ }
+ }
$res->release(finished_cb => sub {
my ($err) = @_;
die "$err" if $err;
},
finished_cb => sub {
my ($err) = @_;
+ $chg->quit();
return failure($err, $finished_cb) if $err;
print STDERR "update complete\n";
- $chg->quit();
$finished_cb->();
});
});
sub failure {
my ($msg, $finished_cb) = @_;
- print STDERR "ERROR: $msg\n";
+ if ($msg->isa("Amanda::Changer::Error") and defined $msg->{'slot'}) {
+ print STDERR "ERROR: Slot: $msg->{'slot'}: $msg\n";
+ } else {
+ print STDERR "ERROR: $msg\n";
+ }
$exit_status = 1;
$finished_cb->();
}
my $config_overrides = new_config_overrides($#ARGV+1);
+debug("Arguments: " . join(' ', @ARGV));
Getopt::Long::Configure(qw(bundling));
GetOptions(
+ 'version' => \&Amanda::Util::version_opt,
'help|usage|?' => \&usage,
'o=s' => sub { add_config_override_opt($config_overrides, $_[1]); },
) or usage();