X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famtape.pl;h=dec31ea6e62c7fad61f3913a009f95689b72a2d0;hb=4f0b86f7a23848c16cfe82fae81e639917fcff27;hp=df7b176d5025d2f11255b686fc06c7cece0ce1b0;hpb=011a59f5a54864108a16af570a6b287410597cc2;p=debian%2Famanda diff --git a/server-src/amtape.pl b/server-src/amtape.pl index df7b176..dec31ea 100644 --- a/server-src/amtape.pl +++ b/server-src/amtape.pl @@ -1,5 +1,5 @@ #! @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 @@ -34,9 +34,11 @@ use Amanda::Constants; use Amanda::MainLoop; use Amanda::Taper::Scan; use Amanda::Recovery::Scan; -use Amanda::Interactive; +use Amanda::Interactivity; +use Amanda::Tapelist; my $exit_status = 0; +my $tl; ## # Subcommand handling @@ -93,6 +95,7 @@ sub { $chg->reset(finished_cb => sub { my ($err) = @_; + $chg->quit(); return failure($err, $finished_cb) if $err; print STDERR "changer is reset\n"; @@ -113,6 +116,7 @@ sub { $chg->eject(@drive_args, finished_cb => sub { my ($err) = @_; + $chg->quit(); return failure($err, $finished_cb) if $err; print STDERR "drive ejected\n"; @@ -136,6 +140,7 @@ sub { $chg->clean(@drive_args, finished_cb => sub { my ($err) = @_; + $chg->quit(); return failure($err, $finished_cb) if $err; print STDERR "drive cleaned\n"; @@ -143,21 +148,44 @@ sub { }); }); -subcommand("show", "show", "scan all slots in the changer, starting with the current slot", +subcommand("show", "show []", "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 $gres; + my $chg; - my $steps = define_steps - cb_ref => \$finished_cb; - - if (@args != 0) { + if (@args > 1) { return usage($finished_cb); } - my $chg = load_changer($finished_cb) or return; + 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 + cb_ref => \$finished_cb, + finalize => sub { $chg->quit() if defined $chg }; step start => sub { $chg->info(info => [ 'num_slots' ], info_cb => $steps->{'info_cb'}); @@ -167,13 +195,19 @@ sub { 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 { @@ -201,9 +235,6 @@ sub { print STDERR sprintf("slot %3s: date %-14s label %s\n", $last_slot, $dev->volume_time(), $dev->volume_label()); - $gres = $res; - return $res->set_label(label => $dev->volume_label(), - finished_cb => $steps->{'set_labeled'}); } elsif ($st == $DEVICE_STATUS_VOLUME_UNLABELED) { print STDERR sprintf("slot %3s: unlabeled volume\n", $last_slot); } else { @@ -220,13 +251,20 @@ sub { } }; - step set_labeled => sub { - $gres->release(finished_cb => $steps->{'released'}); - }; - 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'}); + } }; }); @@ -246,11 +284,16 @@ sub { my ($err, $inv) = @_; if ($err) { if ($err->notimpl) { - print STDERR "inventory not supported by this changer\n"; + if ($err->{'message'}) { + print STDERR "inventory not supported by this changer: $err->{'message'}\n"; + } else { + print STDERR "inventory not supported by this changer\n"; + } } else { print STDERR "$err\n"; } + $chg->quit(); return $finished_cb->(); } @@ -263,10 +306,18 @@ sub { } else { if (defined $sl->{label}) { $line .= " label $sl->{label}"; + my $tle = $tl->lookup_tapelabel($sl->{label}); + 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 { @@ -285,11 +336,15 @@ sub { if ($sl->{'import_export'}) { $line .= " (import/export slot)"; } + if ($sl->{'current'}) { + $line .= " (current)"; + } # note that inventory goes to stdout print "$line\n"; } + $chg->quit(); $finished_cb->(); }); $chg->inventory(inventory_cb => $inventory_cb); @@ -310,10 +365,11 @@ subcommand("slot", "slot ", sub { my ($finished_cb, @args) = @_; my @slotarg; - my $gres; + my $chg; my $steps = define_steps - cb_ref => \$finished_cb; + cb_ref => \$finished_cb, + finalize => sub { $chg->quit() if defined $chg }; # NOTE: the syntax of this subcommand precludes actual slots named # 'current' or 'next' .. when we have a changer using such slot names, @@ -322,7 +378,7 @@ sub { return usage($finished_cb) unless (@args == 1); my $slot = shift @args; - my $chg = load_changer($finished_cb) or return; + $chg = load_changer($finished_cb) or return; step get_slot => sub { if ($slot eq 'current' or $slot eq 'next') { @@ -368,17 +424,7 @@ sub { my $gotslot = $res->{'this_slot'}; print STDERR "changed to slot $gotslot\n"; - if ($res->{device}->volume_label) { - $gres = $res; - $res->set_label(label => $res->{device}->volume_label(), - finished_cb => $steps->{'set_labeled'}); - } else { - $res->release(finished_cb => $steps->{'released'}); - } - }; - - step set_labeled => sub { - $gres->release(finished_cb => $steps->{'released'}); + $res->release(finished_cb => $steps->{'released'}); }; step released => sub { @@ -392,15 +438,17 @@ sub { subcommand("label", "label