X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famcheckdump.pl;fp=server-src%2Famcheckdump.pl;h=d8042bc9294d0f62df571419fb4fea096c6f0c6c;hb=cd0b924f27312d57bd42f6c4fae2b795139e2d0b;hp=95c7fa3426f00ac5b3dfaf20eda15562fb65d163;hpb=011a59f5a54864108a16af570a6b287410597cc2;p=debian%2Famanda diff --git a/server-src/amcheckdump.pl b/server-src/amcheckdump.pl index 95c7fa3..d8042bc 100644 --- a/server-src/amcheckdump.pl +++ b/server-src/amcheckdump.pl @@ -95,12 +95,12 @@ if ($cfgerr_level >= $CFGERR_WARNINGS) { Amanda::Util::finish_setup($RUNNING_AS_DUMPUSER); -# Interactive package -package Amanda::Interactive::amcheckdump; +# Interactivity package +package Amanda::Interactivity::amcheckdump; use POSIX qw( :errno_h ); use Amanda::MainLoop qw( :GIOCondition ); use vars qw( @ISA ); -@ISA = qw( Amanda::Interactive ); +@ISA = qw( Amanda::Interactivity ); sub new { my $class = shift; @@ -135,12 +135,12 @@ sub user_request { if (!defined $n_read) { return if ($! == EINTR); $self->abort(); - return $params{'finished_cb'}->( + return $params{'request_cb'}->( Amanda::Changer::Error->new('fatal', message => "Fail to read from stdin")); } elsif ($n_read == 0) { $self->abort(); - return $params{'finished_cb'}->( + return $params{'request_cb'}->( Amanda::Changer::Error->new('fatal', message => "Aborted by user")); } else { @@ -150,7 +150,7 @@ sub user_request { chomp $line; $buffer = ""; $self->abort(); - return $params{'finished_cb'}->(undef, $line); + return $params{'request_cb'}->(undef, $line); } } }; @@ -196,6 +196,8 @@ sub clerk_notif_holding { package main; +use Amanda::MainLoop qw( :GIOCondition ); + # Given a dumpfile_t, figure out the command line to validate, specified # as an argv array sub find_validation_command { @@ -249,16 +251,20 @@ sub main { my $tapelist; my $chg; - my $interactive; + my $interactivity; my $scan; my $clerk; my $plan; my $timestamp; my $all_success = 1; my @xfer_errs; + my %all_filter; + my $check_done; my $steps = define_steps - cb_ref => \$finished_cb; + cb_ref => \$finished_cb, + finalize => sub { $scan->quit() if defined $scan; + $chg->quit() if defined $chg }; step start => sub { # set up the tapelist @@ -271,17 +277,17 @@ sub main { unless defined $opt_timestamp; # make an interactivity plugin - $interactive = Amanda::Interactive::amcheckdump->new(); + $interactivity = Amanda::Interactivity::amcheckdump->new(); # make a changer - $chg = Amanda::Changer->new(); + $chg = Amanda::Changer->new(undef, tapelist => $tapelist); return $steps->{'quit'}->($chg) if $chg->isa("Amanda::Changer::Error"); # make a scan $scan = Amanda::Recovery::Scan->new( chg => $chg, - interactive => $interactive); + interactivity => $interactivity); return $steps->{'quit'}->($scan) if $scan->isa("Amanda::Changer::Error"); @@ -357,11 +363,11 @@ sub main { if ($hdr->{'srv_encrypt'}) { push @filters, Amanda::Xfer::Filter::Process->new( - [ $hdr->{'srv_encrypt'}, $hdr->{'srv_decrypt_opt'} ], 0, 0); + [ $hdr->{'srv_encrypt'}, $hdr->{'srv_decrypt_opt'} ], 0); } elsif ($hdr->{'clnt_encrypt'}) { push @filters, Amanda::Xfer::Filter::Process->new( - [ $hdr->{'clnt_encrypt'}, $hdr->{'clnt_decrypt_opt'} ], 0, 0); + [ $hdr->{'clnt_encrypt'}, $hdr->{'clnt_decrypt_opt'} ], 0); } else { return failure("could not decrypt encrypted dump: no program specified", $finished_cb); @@ -382,17 +388,17 @@ sub main { # TODO: this assumes that srvcompprog takes "-d" to decrypt push @filters, Amanda::Xfer::Filter::Process->new( - [ $hdr->{'srvcompprog'}, "-d" ], 0, 0); + [ $hdr->{'srvcompprog'}, "-d" ], 0); } elsif ($hdr->{'clntcompprog'}) { # TODO: this assumes that clntcompprog takes "-d" to decrypt push @filters, Amanda::Xfer::Filter::Process->new( - [ $hdr->{'clntcompprog'}, "-d" ], 0, 0); + [ $hdr->{'clntcompprog'}, "-d" ], 0); } else { push @filters, Amanda::Xfer::Filter::Process->new( [ $Amanda::Constants::UNCOMPRESS_PATH, - $Amanda::Constants::UNCOMPRESS_OPT ], 0, 0); + $Amanda::Constants::UNCOMPRESS_OPT ], 0); } # adjust the header @@ -404,12 +410,46 @@ sub main { # we need to throw out its stdout my $argv = find_validation_command($hdr); if (defined $argv) { - push @filters, Amanda::Xfer::Filter::Process->new($argv, 0, 0); + push @filters, Amanda::Xfer::Filter::Process->new($argv, 0); } # we always throw out stdout my $xfer_dest = Amanda::Xfer::Dest::Null->new(0); + # start reading all filter stderr + foreach my $filter (@filters) { + my $fd = $filter->get_stderr_fd(); + $fd.=""; + $fd = int($fd); + my $src = Amanda::MainLoop::fd_source($fd, + $G_IO_IN|$G_IO_HUP|$G_IO_ERR); + my $buffer = ""; + $all_filter{$src} = 1; + $src->set_callback( sub { + my $b; + my $n_read = POSIX::read($fd, $b, 1); + if (!defined $n_read) { + return; + } elsif ($n_read == 0) { + delete $all_filter{$src}; + $src->remove(); + POSIX::close($fd); + if (!%all_filter and $check_done) { + $finished_cb->(); + } + } else { + $buffer .= $b; + if ($b eq "\n") { + my $line = $buffer; + print STDERR "filter stderr: $line"; + chomp $line; + debug("filter stderr: $line"); + $buffer = ""; + } + } + }); + } + my $xfer = Amanda::Xfer->new([ $xfer_src, @filters, $xfer_dest ]); $xfer->start($steps->{'handle_xmsg'}); $clerk->start_recovery( @@ -458,7 +498,8 @@ sub main { if ($err) { $exit_code = 1; print STDERR $err, "\n"; - return $clerk->quit(finished_cb => $finished_cb); + return $clerk->quit(finished_cb => $steps->{'quit1'}) if defined $clerk;; + return $steps->{'quit1'}->(); } if ($all_success) { @@ -468,8 +509,16 @@ sub main { $exit_code = 1; } - return $clerk->quit(finished_cb => $finished_cb); + return $clerk->quit(finished_cb => $steps->{'quit1'}); }; + + step quit1 => sub { + $check_done = 1; + + if (!%all_filter) { + $finished_cb->(); + } + } } main(sub { Amanda::MainLoop::quit(); });