& eval 'exec @PERL@ -S $0 $argv:q'
if 0;
-require "newgetopt.pl";
use warnings;
use lib '@amperldir@';
use Time::Local;
use Text::ParseWords;
use Amanda::Util;
use Amanda::Process;
+use Getopt::Long;
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
$ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; # force known path
$STATUS_TAPE = 16;
$exit_status = 0;
-$USE_VERSION_SUFFIXES='@USE_VERSION_SUFFIXES@';
-$suf = '';
-if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
- $suf='-@VERSION@';
-}
+my $opt_summary;
+my $opt_stats;
+my $opt_dumping;
+my $opt_waitdumping;
+my $opt_waittaper;
+my $opt_dumpingtape;
+my $opt_writingtape;
+my $opt_finished;
+my $opt_failed;
+my $opt_estimate;
+my $opt_gestimate;
+my $opt_date;
+my $opt_config;
+my $opt_file;
+my $opt_locale_independent_date_format;
-$result = &NGetOpt ( "summary",
- "stats|statistics",
- "dumping|d",
- "waitdumping|wdumping",
- "waittaper|wtaper",
- "dumpingtape|dtape",
- "writingtape|wtape",
- "finished",
- "failed|error",
- "estimate",
- "gestimate|gettingestimate",
- "date",
- "config|c:s",
- "file:s",
- "locale-independent-date-format",
- );
-if($result !=1 ) {
- &usage();
+sub usage() {
+ print "amstatus [--file amdump_file]\n";
+ print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
+ print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
+ print " [--estimate] [--gestimate] [--stats] [--date]\n";
+ print " [--locale-independent-date-format]\n";
+ print " [--config] <config>\n";
+ exit 0;
}
+Getopt::Long::Configure(qw{ bundling });
+GetOptions(
+ 'summary' => \$opt_summary,
+ 'stats|statistics' => \$opt_stats,
+ 'dumping|d' => \$opt_dumping,
+ 'waitdumping|wdumping' => \$opt_waitdumping,
+ 'waittaper|wtaper' => \$opt_waittaper,
+ 'dumpingtape|dtape' => \$opt_dumpingtape,
+ 'writingtape|wtape' => \$opt_writingtape,
+ 'finished' => \$opt_finished,
+ 'failed|error' => \$opt_failed,
+ 'estimate' => \$opt_estimate,
+ 'gestimate|gettingestimate' => \$opt_gestimate,
+ 'date' => \$opt_date,
+ 'config|c:s' => \$opt_config,
+ 'file:s' => \$opt_file,
+ 'locale-independent-date-format' => \$opt_locale_independent_date_format,
+ ) or usage();
+
+
if( defined $opt_config ) {
$conf = $opt_config;
}
chomp $pwd;
chdir "$confdir/$conf";
-$logdir=`$sbindir/amgetconf$suf logdir`;
+$logdir=`$sbindir/amgetconf logdir`;
exit 1 if $? != 0;
chomp $logdir;
$errfile="$logdir/amdump";
$opt_estimate = 1;
}
-$unit=`$sbindir/amgetconf$suf displayunit`;
+$unit=`$sbindir/amgetconf displayunit`;
chomp($unit);
$unit =~ tr/A-Z/a-z/;
$unitdivisor=1;
open(AMDUMP,"<$errfile") || die("$errfile: $!");
print "Using $errfile\n";
+my $taper_status_file;
+
$start_degraded_mode = 0;
$label = ""; # -w fodder
$origsize = 0; # -w fodder
$idle_dumpers = 0;
$status_driver = "";
-$status_taper = 0;
+$status_taper = "Searching for a new tape";
$estimate_done = 0;
$holding_space = 0;
$start_time = 0;
$holding_file = $line[5];
$hostpart=&make_hostpart($host,$partition,$datestamp);
$flush{$hostpart}=0;
+ $dump_finished{$hostpart}=0;
$holding_file{$hostpart}=$holding_file;
$level{$hostpart}=$level;
} elsif($line[0] eq "driver") {
#$chunk_started{$hostpart}=1;
$chunk_time{$hostpart}=$current_time;
#$chunk_finished{$hostpart}=0;
+ $size{$hostpart} = 0;
}
elsif($line[6] eq "CONTINUE") {
#7:handle 8:filename 9:chunksize 10:use
}
elsif($line[5] =~ /taper/) {
if($line[6] eq "START-TAPER") {
- #7:timestamp
- $gdatestamp=$line[7];
+ #7:name 8:timestamp
+ $gdatestamp=$line[8];
if(!defined $datestamp{$gdatestamp}) {
$datestamp{$gdatestamp} = 1;
push @datestamp, $gdatestamp;
}
+ $status_taper = "Searching for a new tape";
+ }
+ elsif($line[6] eq "NEW-TAPE") {
+ #7:name 8:handle
+ $status_taper = "Searching for a new tape";
+ }
+ elsif($line[6] eq "NO-NEW-TAPE") {
+ #7:name 8:handle 9:errmsg
+ $serial=$line[8];
+ $error=$line[9];
+ $status_taper = $error;
}
elsif($line[6] eq "FILE-WRITE") {
- #7:handle 8:filename 9:host 10:disk 11:level 12:datestamp 13:splitsize
- $serial=$line[7];
- $host=$line[9];
- $partition=$line[10];
- $level=$line[11];
- $ldatestamp=$line[12];
+ #7:name 8:handle 9:filename 10:host 11:disk 12:level 13:datestamp 14:splitsize
+ $serial=$line[8];
+ $host=$line[10];
+ $partition=$line[11];
+ $level=$line[12];
+ $ldatestamp=$line[13];
+ $status_taper = "Writing $host:$partition";
if(!defined $datestamp{$ldatestamp}) {
$datestamp{$ldatestamp} = 1;
push @datestamp, $ldatestamp;
$ntchunk_size = 0;
}
elsif($line[6] eq "PORT-WRITE") {
- #7:handle 8:host 9:disk 10:level 11:datestamp 12:splitsize 13:diskbuffer 14:fallback_splitsize
- $serial=$line[7];
- $host=$line[8];
- $partition=$line[9];
- $level=$line[10];
- $ldatestamp=$line[11];
+ #7:name 8:handle 9:host 10:disk 11:level 12:datestamp 13:splitsize 14:diskbuffer 15:fallback_splitsize
+ $serial=$line[8];
+ $host=$line[9];
+ $partition=$line[10];
+ $level=$line[11];
+ $ldatestamp=$line[12];
+ $status_taper = "Writing $host:$partition";
$hostpart=&make_hostpart($host,$partition,$ldatestamp);
$serial{$serial}=$hostpart;
$taper_started{$hostpart}=1;
$taper_finished{$hostpart}=0;
$taper_time{$hostpart}=$current_time;
+ $size{$hostpart} = 0;
$ntchunk_size = 0;
}
}
$serial = $line[7];
$error = $line[8];
$hostpart=$serial{$serial};
- $dump_finished{$hostpart}=-1;
+ if ($taper_started{$hostpart} == 1) {
+ $dump_finished{$hostpart}=-1;
+ } else {
+ $dump_finished{$hostpart}=-3;
+ }
$busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
$running_dumper{$line[5]} = "0";
$dump_time{$hostpart}=$current_time;
$serial=$line[7];
$hostpart=$serial{$serial};
$dump_started{$hostpart}=0;
- $dump_finished{$hostpart}=0;
+ if ($taper_started{$hostpart} == 1) {
+ $dump_finished{$hostpart}=-1;
+ } else {
+ $dump_finished{$hostpart}=-3;
+ }
$busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
$running_dumper{$line[5]} = "0";
$dump_time{$hostpart}=$current_time;
$outputsize=$line[8] / $unitdivisor;
$hostpart=$serial{$serial};
$size{$hostpart}=$outputsize;
- $dump_finished{$hostpart}=1;
+ if ($line[6] eq "DONE") {
+ $dump_finished{$hostpart}=1;
+ } else {
+ $dump_finished{$hostpart}=-3;
+ }
$busy_time{$line[5]}+=($current_time-$chunk_time{$hostpart});
$running_dumper{$line[5]} = "0";
$chunk_time{$hostpart}=$current_time;
- $error{$hostpart}="";
if ($line[6] eq "PARTIAL") {
$partial{$hostpart} = 1;
}
else {
$partial{$hostpart} = 0;
+ $error{$hostpart}="";
}
}
elsif($line[6] eq "FAILED") {
#7:handle 8:label 9:filenum 10:errstr
$serial=$line[7];
$label=$line[8];
+ $status_taper = "Idle";
$hostpart=$serial{$serial};
- $line[10] =~ /sec (\S+) kb (\d+) kps/;
- $size=$2 / $unitdivisor;
+ $line[10] =~ /sec (\S+) (kb|bytes) (\d+) kps/;
+ if ($2 eq 'kb') {
+ $size=$3 / $unitdivisor;
+ } else {
+ $size=$3 / ( $unitdivisor * 1024);
+ }
$taper_finished{$hostpart}=1;
$busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
$taper_time{$hostpart}=$current_time;
if ($ntchunk_size > 0) {
$ntchunk{$nb_tape}++;
}
+ undef $taper_status_file;
}
elsif($line[6] eq "PARTDONE") {
#7:handle 8:label 9:filenum 10:ksize 11:errstr
elsif($line[6] eq "REQUEST-NEW-TAPE") {
#7:serial
$serial=$line[7];
+ $old_status_taper = $status_taper;
+ $status_taper = "Asking for a new tape";
$hostpart=$serial{$serial};
if (defined $hostpart) {
+ $olderror{$hostpart} = $error{$hostpart};
$error{$hostpart} = "waiting for a new tape";
}
}
elsif($line[6] eq "NEW-TAPE") {
#7:serial #8:label
$serial=$line[7];
+ $status_taper = $old_status_taper;
$hostpart=$serial{$serial};
if (defined $hostpart) {
- $error{$hostpart} = "";
+ $error{$hostpart} = $olderror{$hostpart};
}
}
- elsif($line[6] eq "TRY-AGAIN" || $line[6] eq "TAPE-ERROR") {
- #7:handle 8:errstr
- $serial=$line[7];
+ elsif($line[6] eq "TAPER-OK") {
+ #7:name #8:label
+ $status_taper = "Idle";
+ }
+ elsif($line[6] eq "TAPE-ERROR") {
+ #7:name 8:errstr
$error=$line[8];
- $hostpart=$serial{$serial};
- if(defined $hostpart) {
- $taper_finished{$hostpart}= $line[6] eq 'TAPE-ERROR' ? -2 : -1;
- $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
- $taper_time{$hostpart}=$current_time;
- $error{$hostpart}="taper: $error";
- }
+ $status_taper = $error;
+ $exit_status |= $STATUS_TAPE;
+ undef $taper_status_file;
}
elsif($line[6] eq "FAILED") {
#7:handle 8:INPUT- 9:TAPE- 10:input_message 11:tape_message
if($line[9] eq "TAPE-ERROR") {
$error=$line[11];
$taper_finished{$hostpart} = -2;
+ $status_taper = $error;
}
else {
$error=$line[10];
$taper_finished{$hostpart} = -1;
+ $status_taper = "Idle";
}
$busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
$taper_time{$hostpart}=$current_time;
$error{$hostpart}="$error";
}
+ undef $taper_status_file;
}
}
}
elsif($line[1] eq "state" && $line[2] eq "time") {
#3:time 4:"free" 5:"kps" 6:free 7:"space" 8:space 9:"taper" 10:taper 11:"idle-dumpers" 12:idle-dumpers 13:"qlen" 14:"tapeq" 15:tapeq 16:"runq" 17:runq 18:"roomq" 19:roomq 20:"wakeup" 21:wakeup 22:"driver-idle" 23:driver-idle
$current_time=$line[3];
- $status_taper=$line[10];
$idle_dumpers=$line[12];
$free{"kps"} = $line[6];
}
$state_time_prev=$current_time;
$dumpers_active_prev=$dumpers_active;
- $status_driver=$line[16];
+ $status_driver=$line[23];
if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
$dumpers_held[$dumpers_active]{$status_driver}=0;
}
}
}
elsif($line[0] eq "taper") {
- if($line[1] eq "slot") {
- #2:slot 3:"wrote" 4:"label" 5:corrupted...
+ if($line[1] eq "wrote") {
+ #1:"wrote" 2:"label" 3:label
$nb_tape++;
- $lineX =~ /wrote label `(\S*)'/;
- $label = $1;
+ $label = $line[3];
$ntlabel{$nb_tape} = $label;
$ntpartition{$nb_tape} = 0;
$ntsize{$nb_tape} = 0;
$ntesize{$nb_tape} = 0;
}
- elsif($line[1] eq "wrote") {
- #1:"wrote" 2:"label" 3:corrupted
- $nb_tape++;
- $lineX =~ /wrote label `(\S*)'/;
- $label = $1;
- $ntlabel{$nb_tape} = $label;
- $ntpartition{$nb_tape} = 0;
- $ntsize{$nb_tape} = 0;
- $ntesize{$nb_tape} = 0;
- }
- elsif($line[1] eq "using") {
- #1:"using" #2:"label" #3:`label' #4:date #5 `timestamp'
- $nb_tape++;
- $lineX =~ /using label `(\S*)'/;
- $label = $1;
- $ntlabel{$nb_tape} = $label;
- $ntpartition{$nb_tape} = 0;
- $ntsize{$nb_tape} = 0;
- $ntesize{$nb_tape} = 0;
+ elsif($line[1] eq "status" && $line[2] eq "file") {
+ #1:"status" #2:"file:" #3:hostname #4:diskname #5:filename
+ $taper_status_file = $line[5];
}
}
- elsif($line[0] eq "splitting" &&
+ elsif($line[0] eq "splitting" &&
$line[1] eq "chunk" &&
$line[2] eq "that" &&
$line[3] eq "started" &&
$line[7] =~ /(\d*)kb/;
$size = $1;
$ntchunk{$nb_tape}++;
- $ntsize{$nb_tape} += $size / $unitdivisor;
+ $ntsize{$nb_tape} += $size / $unitdivisor;
$ntesize{$nb_tape} += $size / $unitdivisor;
$ntchunk_size += $size / $unitdivisor;
}
$in_flush=1;
}
if(defined $taper_started{$hostpart} &&
- $taper_started{$hostpart}==1) {
+ $taper_started{$hostpart}==1 &&
+ $dump_finished{$hostpart}!=-3) {
if(defined $dump_started{$hostpart} &&
$dump_started{$hostpart} == 1 &&
$dump_finished{$hostpart} == -1) {
$exit_status |= $STATUS_FAILED;
}
print " dumping to tape";
- if(defined($tapedsize{$hostpart})) {
- printf " (%d$unit done)", $tapedsize{$hostpart};
- $dtsize += $tapedsize{$hostpart};
+ $size = $tapedsize{$hostpart};
+ if ($taper_status_file && -f $taper_status_file &&
+ open FF, "<$taper_status_file") {
+ $line = <FF>;
+ if (defined $line) {
+ chomp $line;
+ $value = $line / ($unitdivisor * 1024);
+ if ($value) {
+ $size = $value if (!defined($size) || $value > $size);
+ }
+ }
+ close FF;
+ }
+ if(defined($size)) {
+ printf " (%d$unit done (%0.2f%%))", $size, 100.0 * $size/$esize{$hostpart};
+ $dtsize += $size;
}
if( defined $starttime ) {
print " (", &showtime($taper_time{$hostpart}), ")";
else {
print " flushing to tape";
}
- if(defined($tapedsize{$hostpart})) {
- printf " (%d$unit done)", $tapedsize{$hostpart};
+ $size = $tapedsize{$hostpart};
+ if ($taper_status_file && -f $taper_status_file &&
+ open FF, "<$taper_status_file") {
+ $line = <FF>;
+ if (defined $line) {
+ chomp $line;
+ $value = $line / ($unitdivisor * 1024);
+ if ($value) {
+ $size = $value if (!defined($size) || $value > $size);
+ }
+ }
+ close FF;
+ }
+ if(defined($size)) {
+ printf " (%d$unit done (%0.2f%%))", $size, 100.0 * $size/$size{$hostpart};
}
if( defined $starttime ) {
print " (", &showtime($taper_time{$hostpart}), ")";
}
- print ", ", $error{$hostpart} if defined($error{$hostpart} &&
- $error{$hostpart} ne "");
+ print ", ", $error{$hostpart} if (defined($error{$hostpart}) &&
+ $error{$hostpart} ne "");
print "\n";
}
$tapartition++;
else {
$taesize += $size{$hostpart};
}
+ if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
+ $dpartition++;
+ $dsize += $size{$hostpart};
+ if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
+ $desize += $esize{$hostpart};
+ } else {
+ $desize += $size{$hostpart};
+ }
+ }
}
elsif($taper_finished{$hostpart} < 0) {
$wfpartition++;
$wfsize += $xsize;
}
+ if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
+ $dpartition++;
+ $dsize += $size{$hostpart};
+ if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
+ $desize += $esize{$hostpart};
+ } else {
+ $desize += $size{$hostpart};
+ }
+ }
}
elsif($taper_finished{$hostpart} == 1) {
if( defined $opt_finished ) {
}
print "\n";
}
- $dpartition++;
+ if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
+ $dpartition++;
+ $dsize += $size{$hostpart};
+ if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
+ $desize += $esize{$hostpart};
+ } else {
+ $desize += $size{$hostpart};
+ }
+ }
$tpartition++;
- $dsize += $size{$hostpart};
$tsize += $size{$hostpart};
- $desize += $esize{$hostpart};
if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
- $desize += $esize{$hostpart};
$tesize += $esize{$hostpart};
}
else {
- $desize += $size{$hostpart};
$tesize += $size{$hostpart};
}
}
if( defined $opt_failed ) {
printf "%8s ", $datestamp if defined $opt_date;
printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
- printf " " . $error{$hostpart} . "\n";
+ printf "failed: " . $error{$hostpart} . "\n";
}
$exit_status |= $STATUS_FAILED;
printf "%8s ", $datestamp if defined $opt_date;
printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
printf "%9d$unit", $esize{$hostpart};
- print " wait for dumping $error{$hostpart}\n";
+ if ($dead_run) {
+ print " failed: process terminated while";
+ $exit_status |= $STATUS_FAILED;
+ }
+ print " waiting for dumping $error{$hostpart}\n";
}
if($driver_finished == 1) {
$exit_status |= $STATUS_MISSING;
}
}
elsif($dump_started{$hostpart} == 1 &&
- $dump_finished{$hostpart} == -1) {
+ ($dump_finished{$hostpart} == -1 ||
+ $dump_finished{$hostpart} == -3)) {
if( defined $opt_failed ) {
printf "%8s ", $datestamp if defined $opt_date;
printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
- print " ", $error{$hostpart};
+ print "backup failed: ", $error{$hostpart};
if( defined $starttime ) {
print " (", &showtime($dump_time{$hostpart}), ")";
}
$fsize+=$esize{$hostpart};
}
elsif($dump_started{$hostpart} == 1 &&
- $dump_finished{$hostpart} != 1) {
+ $dump_finished{$hostpart} == 0) {
if( defined $opt_dumping ||
defined $opt_failed && $dead_run != 0) {
printf "%8s ", $datestamp if defined $opt_date;
if( defined $starttime ) {
print " (", &showtime($dump_time{$hostpart}), ")";
}
- print ", wait for writing to tape";
+ print ",";
+ if ($dead_run) {
+ print " process terminated while";
+ }
+ print " waiting for writing to tape";
if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
print ", PARTIAL";
$exit_status |= $STATUS_FAILED;
printf "%8s ", $datestamp if defined $opt_date;
printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
printf "%9d$unit", $size{$hostpart};
+ if ($dead_run) {
+ print " process terminated while";
+ }
print " waiting to flush";
if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
print ", PARTIAL";
$c3 = ($idle_dumpers == 1) ? " " : "";
printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
}
- if($status_taper eq "writing" && defined($qlen{"tapeq"})) {
- printf "taper writing, tapeq: %d\n", $qlen{"tapeq"};
- }
- else {
- printf "taper idle\n";
+
+ printf "taper status: $status_taper\n";
+ if (defined $qlen{"tapeq"}) {
+ printf "taper qlen: %d\n", $qlen{"tapeq"};
}
if (defined ($free{"kps"})) {
printf "network free kps: %9d\n", $free{"kps"};
return $result;
}
-sub usage() {
- print "amstatus [--config] config [--file amdump_file]\n";
- print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
- print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
- print " [--estimate] [--gestimate] [--stats] [--date] [--locale-independent-date-format]\n";
- exit 0;
-}