Imported Upstream version 3.3.1
[debian/amanda] / perl / Amanda / Recovery / Clerk.pm
index 7f193bc84d853bf8b2b0bec67f3784f139fb3f9e..7531421dd1c7b5a5aa259faded153a054eb1ee8a 100644 (file)
@@ -69,7 +69,7 @@ Amanda::Recovery::Clerk - handle assembling dumpfiles from multiple parts
 
 =head1 OVERVIEW
 
-This package is the counterpart to L<Amanda::Recovery::Scribe>, and handles
+This package is the counterpart to L<Amanda::Taper::Scribe>, and handles
 re-assembling dumpfiles from multiple parts, possibly distributed over several
 volumes.
 
@@ -179,10 +179,10 @@ user-defined feedback object should inherit from
 C<Amanda::Recovery::Clerk::Feedback>, which implements no-op versions of all of
 the methods.
 
-The C<notif_part> method is called just before each part is restored, and is
+The C<clerk_notif_part> method is called just before each part is restored, and is
 given the label, filenum, and header.  Its return value, if any, is ignored.
-Similarly, C<notif_holding> is called for a holding-disk recovery and is given
-the holding filename and its header.  Note that C<notif_holding> is called
+Similarly, C<clerk_notif_holding> is called for a holding-disk recovery and is given
+the holding filename and its header.  Note that C<clerk_notif_holding> is called
 before the C<xfer_src_cb>, since data will begin flowing from a holding disk
 immediately when the transfer is started.
 
@@ -190,7 +190,7 @@ A typical Clerk feedback class might look like:
 
     use base 'Amanda::Recovery::Clerk::Feedback';
 
-    sub part_notif {
+    sub clerk_notif_part {
        my $self = shift;
        my ($label, $filenum, $hdr) = @_;
        print "restoring part ", $hdr->{'partnum'},
@@ -228,7 +228,7 @@ sub get_xfer_src {
     my $self = shift;
     my %params = @_;
 
-    for my $rq_param qw(dump xfer_src_cb) {
+    for my $rq_param (qw(dump xfer_src_cb)) {
        croak "required parameter '$rq_param' missing"
            unless exists $params{$rq_param};
     }
@@ -262,7 +262,7 @@ sub start_recovery {
     my %params = @_;
 
     $self->dbg("starting recovery");
-    for my $rq_param qw(xfer recovery_cb) {
+    for my $rq_param (qw(xfer recovery_cb)) {
        croak "required parameter '$rq_param' missing"
            unless exists $params{$rq_param};
     }
@@ -300,18 +300,25 @@ sub handle_xmsg {
 sub quit {
     my $self = shift;
     my %params = @_;
+    my $finished_cb = $params{'finished_cb'};
 
     die "Cannot quit a Clerk while a transfer is in progress"
        if $self->{'xfer_state'};
 
-    # if we have a reservation, we need to release it; otherwise, we can
-    # just call finished_cb
-    if ($self->{'current_res'}) {
-       $self->{'current_dev'}->finish();
-       $self->{'current_res'}->release(finished_cb => $params{'finished_cb'});
-    } else {
-       $params{'finished_cb'}->();
-    }
+    my $steps = define_steps 
+       cb_ref => \$finished_cb,
+       finalize => sub { $self->{'scan'}->quit() if defined $self->{'scan'} };
+
+    step release => sub {
+       # if we have a reservation, we need to release it; otherwise, we can
+       # just call finished_cb
+       if ($self->{'current_res'}) {
+           $self->{'current_dev'}->finish();
+           $self->{'current_res'}->release(finished_cb => $finished_cb);
+       } else {
+           $finished_cb->();
+       }
+    };
 }
 
 sub _xmsg_ready {
@@ -551,7 +558,7 @@ sub _maybe_start_part {
 
        } else {
            # notify caller of the part
-           $self->{'feedback'}->notif_part($next_label, $next_filenum, $on_vol_hdr);
+           $self->{'feedback'}->clerk_notif_part($next_label, $next_filenum, $on_vol_hdr);
 
            # start the part
            $self->dbg("reading file $next_filenum on '$next_label'");
@@ -574,6 +581,9 @@ sub _maybe_start_part {
            return $steps->{'handle_error'}->();
        }
 
+       # remove CONT_FILENAME from the header, since it's not needed anymore
+       $on_disk_hdr->{'cont_filename'} = '';
+
        if (!$self->_header_expected($on_disk_hdr)) {
            # _header_expected already pushed an error message or two
            return $steps->{'handle_error'}->();
@@ -591,7 +601,7 @@ sub _maybe_start_part {
            $xfer_state->{'xfer_src_ready'} = 1;
 
            # notify caller of the part, *before* xfer_src_cb is called!
-           $self->{'feedback'}->notif_holding($next_filename, $on_disk_hdr);
+           $self->{'feedback'}->clerk_notif_holding($next_filename, $on_disk_hdr);
 
            $self->dbg("successfully located holding file for recovery");
            $cb->(undef, $on_disk_hdr, $xfer_state->{'xfer_src'}, 0);
@@ -622,6 +632,14 @@ sub _maybe_start_part {
     };
 }
 
+sub _zeropad {
+    my ($timestamp) = @_;
+    if (length($timestamp) == 8) {
+       return $timestamp."000000";
+    }
+    return $timestamp;
+}
+
 sub _header_expected {
     my $self = shift;
     my ($on_vol_hdr) = @_;
@@ -637,7 +655,10 @@ sub _header_expected {
        push @errs, "got disk '$on_vol_hdr->{disk}'; " .
                    "expected '$next_part->{dump}->{diskname}'";
     }
-    if ($on_vol_hdr->{'datestamp'} ne $next_part->{'dump'}->{'dump_timestamp'}) {
+    # zeropad the datestamps before comparing them, to avoid any compliations
+    # from usetimestamps=0
+    if (_zeropad($on_vol_hdr->{'datestamp'})
+       ne _zeropad($next_part->{'dump'}->{'dump_timestamp'})) {
        push @errs, "got datestamp '$on_vol_hdr->{datestamp}'; " .
                    "expected '$next_part->{dump}->{dump_timestamp}'";
     }
@@ -681,8 +702,8 @@ sub new {
     return bless {}, shift;
 }
 
-sub notif_part { }
+sub clerk_notif_part { }
 
-sub notif_holding { }
+sub clerk_notif_holding { }
 
 1;