X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=perl%2FAmanda%2FChanger%2Frobot.pm;h=38a10b7a777e53d3687c5f1db6c91ee9a4330993;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=00822452887965e6220ba83191dca18dd4ddebb1;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/perl/Amanda/Changer/robot.pm b/perl/Amanda/Changer/robot.pm index 0082245..38a10b7 100644 --- a/perl/Amanda/Changer/robot.pm +++ b/perl/Amanda/Changer/robot.pm @@ -453,7 +453,7 @@ sub load_unlocked { } # otherwise, we can jump all the way to the end of this process - return $steps->{'check_device'}->(); + return $steps->{'start_polling'}->(); } # here is where we implement each of the drive-selection algorithms @@ -637,8 +637,8 @@ sub load_unlocked { # update metadata with this new information $state->{'slots'}->{$slot}->{'state'} = Amanda::Changer::SLOT_FULL; $state->{'slots'}->{$slot}->{'device_status'} = $device->status; - if (defined $device->{'header'}) { - $state->{'slots'}->{$slot}->{'f_type'} = $device->{'header'}->{type}; + if (defined $device->{'volume_header'}) { + $state->{'slots'}->{$slot}->{'f_type'} = $device->{'volume_header'}->{type}; } else { $state->{'slots'}->{$slot}->{'f_type'} = undef; } @@ -659,8 +659,8 @@ sub load_unlocked { # update metadata with this new information $state->{'slots'}->{$slot}->{'state'} = Amanda::Changer::SLOT_FULL; $state->{'slots'}->{$slot}->{'device_status'} = $device->status; - if (defined $device->{'header'}) { - $state->{'slots'}->{$slot}->{'f_type'} = $device->{'header'}->{type}; + if (defined $device->{'volume_header'}) { + $state->{'slots'}->{$slot}->{'f_type'} = $device->{'volume_header'}->{type}; } else { $state->{'slots'}->{$slot}->{'f_type'} = undef; } @@ -728,7 +728,8 @@ sub info_key_vendor_string { $self->{'interface'}->inquiry(make_cb(inquiry_cb => sub { my ($err, $info) = @_; - return $params{'info_cb'}->($err) if $err; + return $self->make_error("fatal", $params{'info_cb'}, + message => "$err") if $err; my $vendor_string = sprintf "%s %s", ($info->{'vendor id'} or ""), @@ -790,13 +791,13 @@ sub get_device { # (overridden by subclasses) my $device = Amanda::Device->new($device_name); if ($device->status != $DEVICE_STATUS_SUCCESS) { return $self->make_error("failed", undef, - reason => "device", + reason => "unknown", message => "opening '$device_name': " . $device->error_or_status()); } if (my $err = $self->{'config'}->configure_device($device)) { return $self->make_error("failed", undef, - reason => "device", + reason => "unknown", message => $err); } @@ -1285,10 +1286,14 @@ sub move_unlocked { message => "slot $from_slot is empty"); } - if (defined $state->{'slots'}->{$from_slot}->{'loaded_in'}) { - return $self->make_error("failed", $params{'finished_cb'}, - reason => "invalid", - message => "slot $from_slot is currently loaded"); + my $in_drive = $state->{'slots'}->{$from_slot}->{'loaded_in'}; + if (defined $in_drive) { + my $info = $state->{'drives'}->{$in_drive}; + if ($info->{'res_info'} and $self->_res_info_verify($info->{'res_info'})) { + return $self->make_error("failed", $params{'finished_cb'}, + reason => "invalid", + message => "slot $from_slot is currently loaded and reserved"); + } } if ($state->{'slots'}->{$to_slot}->{'state'} == Amanda::Changer::SLOT_FULL) { @@ -1305,17 +1310,49 @@ sub move_unlocked { return $params{'finished_cb'}->($err) if $err; # update metadata - $state->{'slots'}->{$to_slot} = { %{ $state->{'slots'}->{$from_slot} } }; - $state->{'slots'}->{$from_slot}->{'state'} = - Amanda::Changer::SLOT_EMPTY; - $state->{'slots'}->{$from_slot}->{'device_status'} = undef; - $state->{'slots'}->{$from_slot}->{'f_type'} = undef; - $state->{'slots'}->{$from_slot}->{'label'} = undef; - $state->{'slots'}->{$from_slot}->{'barcode'} = undef; + if ($from_slot ne $to_slot) { + my $f = $state->{'slots'}->{$from_slot}; + my $t = $state->{'slots'}->{$to_slot}; + + $t->{'device_status'} = $f->{'device_status'}; + $f->{'device_status'} = undef; + + $t->{'state'} = $f->{'state'}; + $f->{'state'} = Amanda::Changer::SLOT_EMPTY; + + $t->{'f_type'} = $f->{'f_type'}; + $f->{'f_type'} = undef; + + $t->{'label'} = $f->{'label'}; + $f->{'label'} = undef; + + $t->{'barcode'} = $f->{'barcode'}; + $f->{'barcode'} = undef; + } + + # properly represent the unload operation, if it was performed + if (defined $in_drive) { + $state->{'slots'}->{$from_slot}->{'loaded_in'} = undef; + $state->{'slots'}->{$to_slot}->{'loaded_in'} = undef; + + $state->{'drives'}->{$in_drive}->{'state'} = + Amanda::Changer::SLOT_EMPTY; + $state->{'drives'}->{$in_drive}->{'label'} = undef; + $state->{'drives'}->{$in_drive}->{'barcode'} = undef; + $state->{'drives'}->{$in_drive}->{'orig_slot'} = undef; + } $params{'finished_cb'}->(); }); - $self->{'interface'}->transfer($from_slot, $to_slot, $transfer_complete); + + # if the source slot is loaded, then this is just a directed unload operation; + # otherwise, it's a transfer. + if (defined $in_drive) { + Amanda::Debug::debug("move(): unloading drive $in_drive to slot $to_slot"); + $self->{'interface'}->unload($in_drive, $to_slot, $transfer_complete); + } else { + $self->{'interface'}->transfer($from_slot, $to_slot, $transfer_complete); + } } ##