# HG changeset patch # User Heiko Schlittermann (JUMPER) # Date 1387224322 -3600 # Node ID 9ad262d8c301777cd3723c45710804f7714b97e4 # Parent 8231f7b0005201071f6d2f17c391cd00d2f935f0 validate and faster pass through diff -r 8231f7b00052 -r 9ad262d8c301 bin/amdumpext --- a/bin/amdumpext Mon Dec 16 16:36:15 2013 +0100 +++ b/bin/amdumpext Mon Dec 16 21:05:22 2013 +0100 @@ -37,6 +37,8 @@ use constant FD3 => 3; use constant FD4 => 4; +my $BS = 64 * 2**20; # 64 MB read size + $SIG{__DIE__} = sub { die $^S ? '' : "$ME: ", @_ }; my %SUPPORT = ( @@ -58,6 +60,7 @@ sub exec_selfcheck; sub exec_estimate; sub exec_backup; +sub exec_validate; # some helper functions @@ -92,19 +95,23 @@ ) or pod2usage; given ($command) { - when ("support") { exec_support } - when ("selfcheck") { + when ('support') { exec_support } + when ('selfcheck') { pod2usage if undef ~~ $opt_device; exec_selfcheck } - when ("estimate") { + when ('estimate') { pod2usage if undef ~~ [$opt_device, $opt_level[0]]; exec_estimate } - when ("backup") { + when ('backup') { pod2usage if undef ~~ [$opt_device, $opt_level[0]]; exec_backup } + when ('validate') { + exec_validate + } + default { pod2usage } } } @@ -133,11 +140,19 @@ "@gids (@groups)"; }; - foreach my $tool (qw(dump restore)) { - if ($_ = (grep { -x ($_ .= "/$tool") } split /:/ => $ENV{PATH})[0]) { - my ($version, undef) = `$_ 2>&1`; - chomp $version; - OK "$tool is $version"; + foreach my $tool (qw(dump restore cat)) { + if (my $path = + (grep { -x ($_ .= "/$tool") } split /:/ => $ENV{PATH})[0]) + { + + # not all tools understand --version, but fortunately they + # all output a line starting with the name of the tool and + # the version information + my ($version, undef) = + map { /^.*?\s+(.*)/ } + grep { /\A(?:$path|$tool)\s/ } `$path --version 2>&1`; + chomp $version; + OK "$tool is $path $version"; } else { ERROR "$tool not found in $ENV{PATH}"; @@ -257,18 +272,27 @@ die "Can't exec `restore -tvf -`: $!"; }; - # the restore may close it's input, we'll get - # a SIG{PIPE} because of this + # The restore may close it's input, we'll get + # a SIG{PIPE} because of this. + # But how can we be sure that it was the restore + # that just sent us the signal? Currently we write + # to two processes only, writing to STDOUT (the data + # stream up down to the server). If this fails we die. + # The other stream we write to is the 'restore'. + # If we got this SIGPIPE, we 'switch' to cat, since + # it's faster then our perl script. local $SIG{PIPE} = sub { close $restore; $restore = undef; $SIG{PIPE} = 'default'; + exec 'cat'; + die "Can't exec `cat': $!\n"; }; - local $/ = \(my $x = 64 * 1024); + local $/ = \$BS; while () { - print $_; - print $restore $_ if $restore; + print $_ or die "Can't send data to `dump': $!\n"; + print $restore $_; } close($restore) if $restore; exit 0; @@ -397,6 +421,27 @@ } +sub exec_validate { + + my $pid = fork // die "Can't fork: $!\n"; + + # the first part goes into restore + # but restore stops reading after the directory + if (not $pid) { + exec 'restore', '-tf', '-'; + die "Can't exec restore: $!\n"; + } + waitpid($pid, 0); + die $? if $?; + + # read the remaining dump via cat, I think, + # nobody is fast than cat + open(STDOUT, '>', '/dev/null') + or die "Can't redirect STDOUT to >/dev/null: $!\n"; + exec 'cat'; + die "Can't exec `cat': $!\n"; +} + sub device { my $_ = shift; return $_ if /^\//; @@ -419,8 +464,10 @@ =head1 SYNOPSIS amdumpext support - amdumpext selfcheck [options] [--level ] --device - amdumpext estimate [options] [--level ]... --device + amdumpext selfcheck [options] [--level ] --device + amdumpext backup [options] [--level ] --device + amdumpext estimate [options] [--level ]... --device + amdumpext validate =head1 DESCRIPTION @@ -489,6 +536,12 @@ mandatory options: device, level, ... +=head2 validate + +This checks if the data stream is readable and looks like a dump. +Actually it does not try to completly validate the stream, as B +does not have such an option. + =head1 PROPERTIES The properties may be set on the server side to tune the behaviour