X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famfetchdump.pl;h=b1e1fb904d638a454c199a1b52981a5749c2d262;hb=3f2539260c201b5e594bf8ce89b583ebde6a63d1;hp=11a6bc1b924e44c2db4dec11119569c5aa63d696;hpb=d5853102f67d85d8e169f9dbe973ad573306c215;p=debian%2Famanda diff --git a/server-src/amfetchdump.pl b/server-src/amfetchdump.pl index 11a6bc1..b1e1fb9 100644 --- a/server-src/amfetchdump.pl +++ b/server-src/amfetchdump.pl @@ -38,12 +38,12 @@ use Amanda::Recovery::Planner; use Amanda::Recovery::Clerk; use Amanda::Recovery::Scan; -# Interactive package -package Amanda::Interactive::amfetchdump; +# Interactivity package +package Amanda::Interactivity::amfetchdump; 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; @@ -78,12 +78,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 { @@ -93,7 +93,7 @@ sub user_request { chomp $line; $buffer = ""; $self->abort(); - return $params{'finished_cb'}->(undef, $line); + return $params{'request_cb'}->(undef, $line); } } }; @@ -112,10 +112,9 @@ package main; sub usage { my ($msg) = @_; print STDERR < \&Amanda::Util::version_opt, @@ -156,7 +157,7 @@ $opt_compress = 1 if $opt_compress_best; usage("must specify at least a hostname") unless @ARGV; @opt_dumpspecs = Amanda::Cmdline::parse_dumpspecs([@ARGV], - $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP); + $Amanda::Cmdline::CMDLINE_PARSE_DATESTAMP | $Amanda::Cmdline::CMDLINE_PARSE_LEVEL); usage("The -b option is no longer supported; set readblocksize in the tapetype section\n" . "of amanda.conf instead.") @@ -212,14 +213,14 @@ sub new { }, $class; } -sub notif_part { +sub clerk_notif_part { my $self = shift; my ($label, $filenum, $header) = @_; print STDERR "amfetchdump: $filenum: restoring ", $header->summary(), "\n"; } -sub notif_holding { +sub clerk_notif_holding { my $self = shift; my ($filename, $header) = @_; @@ -229,11 +230,14 @@ sub notif_holding { package main; +use Amanda::MainLoop qw( :GIOCondition ); sub main { my ($finished_cb) = @_; my $current_dump; my $plan; my @xfer_errs; + my %all_filter; + my $fetch_done; my $steps = define_steps cb_ref => \$finished_cb; @@ -248,7 +252,7 @@ sub main { return failure("Cannot chdir to $destdir: $!", $finished_cb); } - my $interactive = Amanda::Interactive::amfetchdump->new(); + my $interactivity = Amanda::Interactivity::amfetchdump->new(); # if we have an explicit device, then the clerk doesn't get a changer -- # we operate the changer via Amanda::Recovery::Scan if (defined $opt_device) { @@ -256,14 +260,14 @@ sub main { return failure($chg, $finished_cb) if $chg->isa("Amanda::Changer::Error"); my $scan = Amanda::Recovery::Scan->new( chg => $chg, - interactive => $interactive); + interactivity => $interactivity); return failure($scan, $finished_cb) if $scan->isa("Amanda::Changer::Error"); $clerk = Amanda::Recovery::Clerk->new( feedback => main::Feedback->new($chg, $opt_device), scan => $scan); } else { my $scan = Amanda::Recovery::Scan->new( - interactive => $interactive); + interactivity => $interactivity); return failure($scan, $finished_cb) if $scan->isa("Amanda::Changer::Error"); $clerk = Amanda::Recovery::Clerk->new( @@ -288,6 +292,11 @@ sub main { return failure("No matching dumps found", $finished_cb); } + # if we are doing a -p operation, only keep the first dump + if ($opt_pipe) { + @{$plan->{'dumps'}} = ($plan->{'dumps'}[0]); + } + my @needed_labels = $plan->get_volume_list(); my @needed_holding = $plan->get_holding_file_list(); if (@needed_labels) { @@ -431,8 +440,42 @@ sub main { syswrite $hdr_fh, $hdr->to_string(32768, 32768), 32768; } + # 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 $fetch_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'}); + $xfer->start($steps->{'handle_xmsg'}, 0, $current_dump->{'bytes'}); $clerk->start_recovery( xfer => $xfer, recovery_cb => $steps->{'recovery_cb'}); @@ -475,7 +518,11 @@ sub main { return failure($err, $finished_cb) if $err; - $finished_cb->(); +#do all filter are done reading stderr + $fetch_done = 1; + if (!%all_filter) { + $finished_cb->(); + } }; }