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;
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 {
chomp $line;
$buffer = "";
$self->abort();
- return $params{'finished_cb'}->(undef, $line);
+ return $params{'request_cb'}->(undef, $line);
}
}
};
sub usage {
my ($msg) = @_;
print STDERR <<EOF;
-Usage: amfetchdump config [-c|-C|-l] [-p|-n] [-a]
- [-O directory] [-d device] [-o configoption]*
- [--header-file file] [--header-fd fd]
- hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]"));
+Usage: amfetchdump [-c|-C|-l] [-p|-n] [-a] [-O directory] [-d device]
+ [-h] [--header-file file] [--header-fd fd] [-o configoption]* config
+ hostname [diskname [datestamp [hostname [diskname [datestamp ... ]]]]]
EOF
print STDERR "ERROR: $msg\n" if $msg;
exit(1);
my ($opt_config, $opt_no_reassembly, $opt_compress, $opt_compress_best, $opt_pipe,
$opt_assume, $opt_leave, $opt_blocksize, $opt_device, $opt_chdir, $opt_header,
$opt_header_file, $opt_header_fd, @opt_dumpspecs);
+
+debug("Arguments: " . join(' ', @ARGV));
Getopt::Long::Configure(qw(bundling));
GetOptions(
'version' => \&Amanda::Util::version_opt,
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.")
}, $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) = @_;
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;
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) {
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(
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) {
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'});
return failure($err, $finished_cb) if $err;
- $finished_cb->();
+#do all filter are done reading stderr
+ $fetch_done = 1;
+ if (!%all_filter) {
+ $finished_cb->();
+ }
};
}