--- 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 (<STDIN>) {
- 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 <level>] --device <device>
- amdumpext estimate [options] [--level <level>]... --device <device>
+ amdumpext selfcheck [options] [--level <level>] --device <device>
+ amdumpext backup [options] [--level <level>] --device <device>
+ amdumpext estimate [options] [--level <level>]... --device <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<restore>
+does not have such an option.
+
=head1 PROPERTIES
The properties may be set on the server side to tune the behaviour