5 eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
6 & eval 'exec @PERL@ -S $0 $argv:q'
9 require "newgetopt.pl";
12 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
13 $ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin";
15 $confdir="@CONFIG_DIR@";
17 $prefix=$prefix; # avoid warnings about possible typo
18 $exec_prefix="@exec_prefix@";
19 $exec_prefix=$exec_prefix; # ditto
28 $USE_VERSION_SUFFIXES='@USE_VERSION_SUFFIXES@';
30 if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
34 $result = &NGetOpt ( "summary",
37 "waitdumping|wdumping",
44 "gestimate|gettingestimate",
53 if( defined $opt_config ) {
65 #untaint user input $ARGV[0]
67 if ($conf =~ /^([\w.-]+)$/) { # $1 is untainted
70 die "filename '$conf' has invalid characters.\n";
74 if ( ! -e "$confdir/$conf" ) {
75 print "Configuration directory '" . $confdir/$conf . "' doesn't exist\n";
78 if ( ! -d "$confdir/$conf" ) {
79 print "Configuration directory '" . $confdir/$conf . "' is not a directory\n";
85 chdir "$confdir/$conf";
87 $logdir=`$sbindir/amgetconf$suf logdir`;
90 $errfile="$logdir/amdump";
92 $nb_options = defined( $opt_summary ) +
93 defined( $opt_stats ) +
94 defined( $opt_dumping ) +
95 defined( $opt_waitdumping ) +
96 defined( $opt_waittaper ) +
97 defined( $opt_dumpingtape ) +
98 defined( $opt_writingtape ) +
99 defined( $opt_finished ) +
100 defined( $opt_estimate ) +
101 defined( $opt_gestimate ) +
102 defined( $opt_failed );
104 if($nb_options == 0 ) {
108 $opt_waitdumping = 1;
110 $opt_dumpingtape = 1;
111 $opt_writingtape = 1;
118 $unit=`$sbindir/amgetconf$suf displayunit`;
125 elsif($unit eq 'M') {
129 elsif($unit eq 'G') {
130 $unitdivisor = 1024*1024;
133 elsif($unit eq 'T') {
134 $unitdivisor = 1024*1024*1024;
139 if( defined $opt_file) {
140 if( $opt_file =~ m,^/, ) {
141 $errfile = $opt_file;
143 $errfile = "$pwd/$opt_file";
144 $errfile = "$logdir/$opt_file" if ( ! (-f $errfile ));
148 $errfile="$logdir/amflush" if(! (-f $errfile));
150 if (-f "$logdir/amflush.1" && -f "$logdir/amdump.1" &&
151 -M "$logdir/amflush.1" < -M "$logdir/amdump.1") {
152 $errfile="$logdir/amflush.1";
154 $errfile="$logdir/amdump.1";
159 open(AMDUMP,"<$errfile") || die("$errfile: $!");
160 print "Using $errfile";
162 $start_degraded_mode = 0;
164 $label = ""; # -w fodder
165 $origsize = 0; # -w fodder
172 @dumpers_active = ();
174 $ntpartition{$nb_tape} = 0;
175 $ntsize{$nb_tape} = 0;
176 $ntesize{$nb_tape} = 0;
178 $driver_finished = 0;
182 if(/(amdump|amflush): start at (.*)/) {
185 elsif(/(amdump|amflush): datestamp (\S+)/) {
187 if(!defined $datestamp{$gdatestamp}) {
188 $datestamp{$gdatestamp} = 1;
189 push @datestamp, $gdatestamp;
191 $starttime=&set_starttime($2);
193 elsif(/(amdump|amflush): starttime (\S+)/) {
194 $starttime=&set_starttime($2);
196 elsif(/planner: timestamp (\S+)/) {
198 if(!defined $datestamp{$gdatestamp}) {
199 $datestamp{$gdatestamp} = 1;
200 push @datestamp, $gdatestamp;
203 elsif(/setup_estimate: ([_\-\d\.A-Za-z]*):(\S+): command .*, options: *(\S+) *last_level -?\d+ next_level0 -?\d+ level_days \d+ *getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
206 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
207 $estimate{$hostpart}=0;
210 $dump_started{$hostpart}=0;
211 $dump_finished{$hostpart}=0;
212 $taper_started{$hostpart}=0;
213 $taper_finished{$hostpart}=0;
214 $partialestimate{$hostpart}=0;
215 $error{$hostpart}="";
216 if($4 != -1) { $getest{$hostpart} .= ":$4:" };
217 if($5 != -1) { $getest{$hostpart} .= ":$5:" };
218 if($6 != -1) { $getest{$hostpart} .= ":$6:" };
220 elsif(/setup_estimate: (\S+):(\S+): command .*, options:/) {
223 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
224 $estimate{$hostpart}=0;
227 $dump_started{$hostpart}=0;
228 $dump_finished{$hostpart}=0;
229 $taper_started{$hostpart}=0;
230 $taper_finished{$hostpart}=0;
231 $partialestimate{$hostpart}=0;
232 $error{$hostpart}="";
234 while (! /getting estimates/) { $_ = <AMDUMP>; }
236 if(/getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
237 if($1 != -1) { $getest{$hostpart} .= ":$1:" };
238 if($2 != -1) { $getest{$hostpart} .= ":$2:" };
239 if($3 != -1) { $getest{$hostpart} .= ":$3:" };
245 elsif(/got result for host (\S+) disk (\S+): (\d+) -> (\d+)K,/) {
248 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
249 $estimate{$hostpart}=1;
250 $level{$hostpart}=$3;
251 $esize{$hostpart}=$4 / $unitdivisor;
252 $partialestimate{$hostpart}=0;
253 $getest{$hostpart} = "";
255 elsif(/got partial result for host (\S+) disk (\S+): (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K/) {
258 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
259 if($4 > 0 || $6 > 0 || $8 > 0) {
260 $estimate{$hostpart}=1;
261 $level{$hostpart}=$3;
262 $esize{$hostpart}=$4 / $unitdivisor;
263 $partialestimate{$hostpart}=1;
264 if($4 > 0) { $getest{$hostpart} =~ s/:$3://; }
265 if($6 > 0) { $getest{$hostpart} =~ s/:$5://; }
266 if($8 > 0) { $getest{$hostpart} =~ s/:$7://; }
268 if($getest{$hostpart} eq "") { $partialestimate{$hostpart}=0; }
271 elsif(/getting estimates took/) {
277 elsif(/GENERATING SCHEDULE:/) {
278 $generating_schedule=1;
280 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
281 if($generating_schedule == 1 ) {
284 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
285 $level{"$hostpart"}=$4;
287 $esize=32 if $esize<32;
288 $esize{$hostpart}=$esize / $unitdivisor;
289 $degr_level{$hostpart}=-1;
292 elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
293 if($generating_schedule == 1 ) {
297 $hostpart=&make_hostpart($host,$partition,$datestamp);
298 $level{"$hostpart"}=$5;
300 $esize=32 if $esize<32;
301 $esize{$hostpart}=$esize / $unitdivisor;
302 $degr_level{$hostpart}=-1;
305 elsif(/^DUMP (\S+) (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ \d+ (\d+) \d+/) {
306 if($generating_schedule == 1 ) {
312 $hostpart=&make_hostpart($host,$partition,$datestamp);
313 $level{"$hostpart"}=$6;
315 $esize=32 if $esize<32;
316 $esize{$hostpart}=$esize / $unitdivisor;
317 $degr_level{$hostpart}=-1;
320 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
321 if($generating_schedule == 1 ) {
324 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
325 $level{$hostpart}=$4;
327 $esize=32 if $esize<32;
328 $esize{$hostpart}=$esize / $unitdivisor;
329 $degr_level{$hostpart}=$6;
330 $degr_size{$hostpart}=$7 / $unitdivisor;
331 $degr_size{$hostpart}=32 if ($7 < 32);
334 elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ \d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ [-]*\d+ ([-]*\d+) \d+/) {
335 if($generating_schedule == 1 ) {
339 $hostpart=&make_hostpart($host,$partition,$datestamp);
340 $level{$hostpart}=$5;
342 $esize=32 if $esize<32;
343 $esize{$hostpart}=$esize / $unitdivisor;
344 $degr_level{$hostpart}=$7;
345 $degr_size{$hostpart}=$8 / $unitdivisor;
346 $degr_size{$hostpart}=32 if ($8 < 32);
349 elsif(/^FLUSH (\S+) (\S+) (\S+) (\d+) (\S+)/) {
355 $hostpart=&make_hostpart($host,$partition,$datestamp);
357 $holding_file{$hostpart}=$holding_file;
358 $level{$hostpart}=$level;
360 elsif(/^driver: start time (\S+)/) {
363 $dumpers_active[0]=0;
367 elsif(/^driver: tape size (\d+)/) {
368 $tape_size = $1 / $unitdivisor;
370 elsif(/^driver: adding holding disk \d+ dir \S+ size (\d+)/) {
371 $holding_space += $1;
373 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
377 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
379 $serial{$serial}=$hostpart;
380 $dump_started{$hostpart}=1;
381 $dump_time{$hostpart}=$1;
382 $dump_finished{$hostpart}=0;
383 if( $level{$hostpart} != $8 &&
384 $degr_level{$hostpart} == $8) {
385 $level{$hostpart}=$degr_level{$hostpart};
386 $esize{$hostpart}=$degr_size{$hostpart};
388 if(! defined($busy_time{$2})) {
391 $running_dumper{$2} = $hostpart;
392 $error{$hostpart}="";
393 $size{$hostpart} = 0;
395 if(! defined($dumpers_active[$dumpers_active])) {
396 $dumpers_active[$dumpers_active]=0;
398 if(! defined($dumpers_held[$dumpers_active])) {
399 $dumpers_held[$dumpers_active]={};
402 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
406 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
408 $serial{$serial}=$hostpart;
409 #$chunk_started{$hostpart}=1;
410 $chunk_time{$hostpart}=$1;
411 #$chunk_finished{$hostpart}=0;
412 $holding_file{$hostpart}=$5;
414 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
420 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
422 $serial{$serial}=$hostpart;
423 #$chunk_started{$hostpart}=1;
424 $chunk_time{$hostpart}=$1;
425 #$chunk_finished{$hostpart}=0;
426 $holding_file{$hostpart}=$5;
428 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
434 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
436 $serial{$serial}=$hostpart;
437 $dump_started{$hostpart}=1;
438 $dump_time{$hostpart}=$1;
439 $dump_finished{$hostpart}=0;
440 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
441 if( $level{$hostpart} != $9 &&
442 $degr_level{$hostpart} == $9) {
443 $level{$hostpart}=$degr_level{$hostpart};
444 $esize{$hostpart}=$degr_size{$hostpart};
446 if(! defined($busy_time{$2})) {
449 $running_dumper{$2} = $hostpart;
450 $error{$hostpart}="";
451 $size{$hostpart} = 0;
453 if(! defined($dumpers_active[$dumpers_active])) {
454 $dumpers_active[$dumpers_active]=0;
456 if(! defined($dumpers_held[$dumpers_active])) {
457 $dumpers_held[$dumpers_active]={};
460 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
468 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
470 $serial{$serial}=$hostpart;
471 $dump_started{$hostpart}=1;
472 $dump_time{$hostpart}=$1;
473 $dump_finished{$hostpart}=0;
474 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
475 if( $level{$hostpart} != $10 &&
476 $degr_level{$hostpart} == $10) {
477 $level{$hostpart}=$degr_level{$hostpart};
478 $esize{$hostpart}=$degr_size{$hostpart};
480 if(! defined($busy_time{$2})) {
483 $running_dumper{$2} = $hostpart;
484 $error{$hostpart}="";
485 $size{$hostpart} = 0;
487 if(! defined($dumpers_active[$dumpers_active])) {
488 $dumpers_active[$dumpers_active]=0;
490 if(! defined($dumpers_held[$dumpers_active])) {
491 $dumpers_held[$dumpers_active]={};
494 elsif(/driver: send-cmd time (\S+) to (chunker\d*): CONTINUE (\d+-\d+) (\S+) (\d+) (\d+)/) {
497 $hostpart=$serial{$serial};
498 if($hostpart ne "") {
499 $dump_roomq{$hostpart}=undef;
500 $error{$hostpart}="";
503 elsif(/driver: result time (\S+) from (dumper\d+): FAILED (\d+-\d+) (.*)/) {
507 $hostpart=$serial{$serial};
508 $dump_finished{$hostpart}=-1;
509 $busy_time{$2}+=($1-$dump_time{$hostpart});
510 $running_dumper{$2} = "0";
511 $dump_time{$hostpart}=$1;
512 $error{$hostpart}="driver: $error";
515 elsif(/driver: result time (\S+) from (dumper\d+): TRY-AGAIN (\d+-\d+) (.*)/) {
519 $hostpart=$serial{$serial};
520 $dump_started{$hostpart}=0;
521 $dump_finished{$hostpart}=0;
522 $busy_time{$2}+=($1-$dump_time{$hostpart});
523 $running_dumper{$2} = "0";
524 $dump_time{$hostpart}=$1;
525 $error{$hostpart}="driver: (aborted:$error)";
528 elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) "?\[.*\]"?/) {
531 $origsize=$5 / $unitdivisor;
532 $outputsize=$6 / $unitdivisor;
533 $hostpart=$serial{$serial};
534 $size{$hostpart}=$outputsize;
535 $dump_finished{$hostpart}=1;
536 $busy_time{$2}+=($1-$dump_time{$hostpart});
537 $running_dumper{$2} = "0";
538 $dump_time{$hostpart}=$1;
539 $error{$hostpart}="";
541 if ($3 eq "PARTIAL") {
542 $partial{$hostpart} = 1;
545 $partial{$hostpart} = 0;
548 elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) "?\[.*\]"?/) {
551 $outputsize=$5 / $unitdivisor;
552 $hostpart=$serial{$serial};
553 $size{$hostpart}=$outputsize;
554 $dump_finished{$hostpart}=1;
555 $busy_time{$2}+=($1-$chunk_time{$hostpart});
556 $running_dumper{$2} = "0";
557 $chunk_time{$hostpart}=$1;
558 $error{$hostpart}="";
559 if ($3 eq "PARTIAL") {
560 $partial{$hostpart} = 1;
563 $partial{$hostpart} = 0;
566 elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
569 $hostpart=$serial{$serial};
570 $dump_started{$hostpart}=0;
571 $dump_finished{$hostpart}=0;
572 $busy_time{$2}+=($1-$dump_time{$hostpart});
573 $running_dumper{$2} = "0";
574 $dump_time{$hostpart}=$1;
575 $error{$hostpart}="driver: (aborted)";
578 elsif(/driver: result time (\S+) from (chunker\d+): RQ-MORE-DISK (\d+-\d+)/) {
581 $hostpart=$serial{$serial};
582 $dump_roomq{$hostpart}=1;
583 $error{$hostpart}="(waiting for holding disk space)";
585 elsif(/driver: finished-cmd time (\S+) dumper\d+ dumped (\S+):(\S+)/){
588 elsif(/driver: send-cmd time (\S+) to taper: START-TAPER (\S+)/) {
589 if(!defined $gdatestamp) {
591 if(!defined $datestamp{$gdatestamp}) {
592 $datestamp{$gdatestamp} = 1;
593 push @datestamp, $gdatestamp;
597 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S+) (\d*) (\S+)/){
604 if(!defined $datestamp{$ldatestamp}) {
605 $datestamp{$ldatestamp} = 1;
606 push @datestamp, $ldatestamp;
608 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
609 $serial{$serial}=$hostpart;
610 if(!defined $level{$hostpart}) {
611 $level{$hostpart} = $level;
613 $taper_started{$hostpart}=1;
614 $taper_finished{$hostpart}=0;
615 $taper_time{$hostpart}=$1;
618 #features (maybe missing features)
619 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S*) (\S+) (\d*) (\S+)/){
628 if(!defined $datestamp{$ldatestamp}) {
629 $datestamp{$ldatestamp} = 1;
630 push @datestamp, $ldatestamp;
632 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
633 $serial{$serial}=$hostpart;
634 if(!defined $level{$hostpart}) {
635 $level{$hostpart} = $level;
637 $taper_started{$hostpart}=1;
638 $taper_finished{$hostpart}=0;
639 $taper_time{$hostpart}=$1;
642 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) \d+( \d+|)/){
647 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
648 $serial{$serial}=$hostpart;
649 $taper_started{$hostpart}=1;
650 $taper_finished{$hostpart}=0;
651 $taper_time{$hostpart}=$1;
654 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) (\S+) \d+ \d+/){
660 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
661 $serial{$serial}=$hostpart;
662 $taper_started{$hostpart}=1;
663 $taper_finished{$hostpart}=0;
664 $taper_time{$hostpart}=$1;
667 elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) "?\[sec (\S+) kb (\d+) kps/) {
671 $size=$7 / $unitdivisor;
672 $hostpart=$serial{$serial};
673 $taper_finished{$hostpart}=1;
674 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
675 $taper_time{$hostpart}=$1;
676 if(!defined $size{$hostpart}) {
677 $size{$hostpart}=$size;
679 $ntpartition{$nb_tape}++;
680 $ntsize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
681 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
682 $ntesize{$nb_tape} += $esize{$hostpart} - $ntchunk_size;
685 $ntesize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
687 if ($3 eq "PARTIAL") {
688 $partial{$hostpart} = 1;
691 $partial{$hostpart} = 0;
693 if($ntchunk_size > 0) {
694 $ntchunk{$nb_tape}++;
697 elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
701 $hostpart=$serial{$serial};
702 $taper_finished{$hostpart}= $2 eq 'TAPE-ERROR' ? -2 : -1;
703 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
704 $taper_time{$hostpart}=$1;
705 $error{$hostpart}="driver: $error";
707 elsif(/driver: dump failed (\S+) (\S+) (\S+), too many dumper retry/) {
709 $hostpart=$serial{$serial};
710 $dump_started{$hostpart}=-1;
711 $dump_finished{$hostpart}=-2;
712 $error{$hostpart} .= "(too many dumper retry)";
714 elsif(/driver: tape failed (\S+) (\S+) (\S+), too many taper retry/) {
716 $hostpart=$serial{$serial};
717 $taper_started{$hostpart}=-1;
718 $taper_finished{$hostpart}=-2;
719 $error{$hostpart} .= "(too many taper retry)";
721 elsif(/planner: FAILED (\S+) (\S+) (\S+) (-?\d+) (.*)/) {
725 $hostpart=&make_hostpart($host,$partition,$datestamp);
726 $dump_started{$hostpart}=-1;
727 $level{$hostpart}=$4;
728 $error{$hostpart}="planner: $5";
730 elsif(/dump of driver schedule after start degraded mode:/) {
731 $start_degraded_mode=1;
733 elsif(/driver: state time (\S+) free (.*) taper: (\S+) idle-dumpers: (\d+) qlen (.*) driver-idle: (\S+)/) {
738 %free = split (/ +/, $2);
739 %qlen = split (/ +/, $5);
741 if(defined($dumpers_active)) {
742 if($status_driver ne "") {
743 $dumpers_active[$dumpers_active_prev]
744 +=$current_time-$state_time_prev;
745 $dumpers_held[$dumpers_active_prev]{$status_driver}
746 +=$current_time-$state_time_prev;
748 $state_time_prev=$current_time;
749 $dumpers_active_prev=$dumpers_active;
751 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
752 $dumpers_held[$dumpers_active]{$status_driver}=0;
756 elsif(/taper: .*wrote label `(\S*)'/) {
758 $ntlabel{$nb_tape} = $1;
759 $ntpartition{$nb_tape} = 0;
760 $ntsize{$nb_tape} = 0;
761 $ntesize{$nb_tape} = 0;
762 $ntchunk{$nb_tape} = 0;
764 elsif(/splitting chunk that started at \d*kb after (\d*)kb/) {
765 $ntchunk{$nb_tape}++;
766 $ntsize{$nb_tape} += $1 / $unitdivisor;
767 $ntesize{$nb_tape} += $1 / $unitdivisor;
768 $ntchunk_size += $1 / $unitdivisor;
770 elsif(/driver: FINISHED/) {
771 $driver_finished = 1;
774 #print "Ignoring: $_\n";
780 if(defined $current_time) {
781 for ($d = 0; $d < $#dumpers_active; $d++) {
782 $the_dumper = "dumper$d";
783 if(defined($running_dumper{$the_dumper}) &&
784 $running_dumper{$the_dumper} ne "0") {
785 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
829 foreach $host (sort @hosts) {
830 foreach $partition (sort @$host) {
831 foreach $datestamp (sort @datestamp) {
832 $hostpart=&make_hostpart($host,$partition,$datestamp);
833 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
834 if(length("$host:$partition") > $maxnamelength) {
835 $maxnamelength = length("$host:$partition");
841 foreach $host (sort @hosts) {
842 foreach $partition (sort @$host) {
843 foreach $datestamp (sort @datestamp) {
844 $hostpart=&make_hostpart($host,$partition,$datestamp);
845 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
847 if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
848 defined $holding_file{$hostpart}) {
849 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
852 if($estimate_done != 1 && !defined $flush{$hostpart}) {
853 if(defined $estimate{$hostpart}) {
854 if($estimate{$hostpart} != 1) {
855 if( defined $opt_gestimate) {
856 printf "%8s ", $datestamp if defined $opt_date;
857 printf "%-${maxnamelength}s", "$host:$partition";
858 print " getting estimate\n";
862 if(defined $opt_estimate ||
863 (defined $opt_gestimate && $partialestimate{$hostpart} == 1)) {
864 printf "%8s ", $datestamp if defined $opt_date;
865 printf "%-${maxnamelength}s", "$host:$partition";
866 printf "%2d ", $level{$hostpart};
867 printf "%9d$unit", $esize{$hostpart};
868 if($partialestimate{$hostpart} == 1) {
871 print " estimate done\n";
874 $estsize += $esize{$hostpart};
879 if(defined $estimate{$hostpart}) {
880 if($estimate{$hostpart} == 1) {
882 $estsize += $esize{$hostpart};
884 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
885 if( defined $opt_failed) {
886 printf "%8s ", $datestamp if defined $opt_date;
887 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
888 printf " no estimate\n";
890 $exit_status |= $STATUS_FAILED;
892 $fsize+=$esize{$hostpart};
897 $flsize += $size{$hostpart};
900 if(defined $taper_started{$hostpart} &&
901 $taper_started{$hostpart}==1) {
902 if(defined $dump_started{$hostpart}) {
904 if(defined($size{$hostpart})) {
905 $dsize += $size{$hostpart};
908 $dsize += $esize{$hostpart};
910 $desize += $esize{$hostpart};
912 if(defined $dump_started{$hostpart} &&
913 $dump_started{$hostpart} == 1 &&
914 $dump_finished{$hostpart} == -1) {
915 if(defined $opt_failed) {
916 printf "%8s ", $datestamp if defined $opt_date;
917 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
918 printf "%9d$unit", $esize{$hostpart};
919 print " dump to tape failed: " . $error{$hostpart};
922 $exit_status |= $STATUS_FAILED;
924 $fsize+=$esize{$hostpart};
926 elsif(defined $dump_started{$hostpart} &&
927 $dump_started{$hostpart} == 1 &&
928 $dump_finished{$hostpart} == 0 &&
929 $taper_started{$hostpart} == 1) {
930 if( defined $opt_dumpingtape ) {
931 printf "%8s ", $datestamp if defined $opt_date;
932 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
933 printf "%9d$unit", $esize{$hostpart};
934 print " dumping to tape";
935 if( defined $starttime ) {
936 print " (", &showtime($taper_time{$hostpart}), ")";
941 $dtesize += $esize{$hostpart};
943 elsif($taper_finished{$hostpart} == 0) {
944 if( defined $opt_writingtape ) {
945 printf "%8s ", $datestamp if defined $opt_date;
946 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
947 printf "%9d$unit", $size{$hostpart};
949 print " writing to tape";
952 print " flushing to tape";
954 if( defined $starttime ) {
955 print " (", &showtime($taper_time{$hostpart}), ")";
960 $tasize += $size{$hostpart};
961 if(defined $esize{$hostpart}) {
962 $taesize += $esize{$hostpart};
965 $taesize += $size{$hostpart};
968 elsif($taper_finished{$hostpart} < 0) {
970 if(defined $size{$hostpart}) {
971 $xsize = $size{$hostpart};
973 elsif(defined $esize{$hostpart}) {
974 $xsize = $esize{$hostpart};
980 if(defined $esize{$hostpart}) {
981 $exsize += $esize{$hostpart};
987 if( defined $opt_failed ||
988 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
989 printf "%8s ", $datestamp if defined $opt_date;
990 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
991 printf "%9d$unit", $xsize;
993 print " failed to tape";
996 print " failed to flush";
998 print " (will retry)" unless $taper_finished{$hostpart} < -1;
999 if( defined $starttime ) {
1000 print " (", &showtime($taper_time{$hostpart}), ")";
1004 $exit_status |= $STATUS_TAPE;
1008 $tfesize += $exsize;
1010 if($in_flush == 0) {
1013 $twesize += $exsize;
1020 elsif($taper_finished{$hostpart} == 1) {
1021 if( defined $opt_finished ) {
1022 printf "%8s ", $datestamp if defined $opt_date;
1023 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1024 printf "%9d$unit", $size{$hostpart};
1025 if($in_flush == 0) {
1031 if( defined $starttime ) {
1032 print " (", &showtime($taper_time{$hostpart}), ")";
1034 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1036 $exit_status |= $STATUS_FAILED;
1041 $tsize += $size{$hostpart};
1042 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1043 $tesize += $esize{$hostpart};
1046 $tesize += $size{$hostpart};
1050 printf "%8s ", $datestamp if defined $opt_date;
1051 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1052 print " unknown state TAPER\n";
1055 elsif(defined $dump_started{$hostpart}) {
1056 if($dump_started{$hostpart} == -1) {
1057 if( defined $opt_failed ) {
1058 printf "%8s ", $datestamp if defined $opt_date;
1059 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1060 printf " " . $error{$hostpart} . "\n";
1062 $exit_status |= $STATUS_FAILED;
1065 $fsize+=$esize{$hostpart};
1067 elsif($dump_started{$hostpart} == 0) {
1068 if($estimate{$hostpart} == 1) {
1069 if( defined $opt_waitdumping ) {
1070 printf "%8s ", $datestamp if defined $opt_date;
1071 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1072 printf "%9d$unit", $esize{$hostpart};
1073 print " wait for dumping $error{$hostpart}\n";
1075 if($driver_finished == 1) {
1076 $exit_status |= $STATUS_MISSING;
1079 $wsize += $esize{$hostpart};
1082 elsif($dump_started{$hostpart} == 1 &&
1083 $dump_finished{$hostpart} == -1) {
1084 if( defined $opt_failed ) {
1085 printf "%8s ", $datestamp if defined $opt_date;
1086 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1087 print " ", $error{$hostpart};
1088 if( defined $starttime ) {
1089 print " (", &showtime($dump_time{$hostpart}), ")";
1093 $exit_status |= $STATUS_FAILED;
1095 $fsize+=$esize{$hostpart};
1097 elsif($dump_started{$hostpart} == 1 &&
1098 $dump_finished{$hostpart} != 1) {
1099 if( defined $opt_dumping ) {
1100 printf "%8s ", $datestamp if defined $opt_date;
1101 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1102 printf "%9d$unit", $esize{$hostpart};
1103 printf " dumping %8d$unit", $size{$hostpart};
1104 if($size{$hostpart} != 0) {
1105 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1107 if( defined $starttime ) {
1108 print " (", &showtime($dump_time{$hostpart}), ")";
1110 if(defined $dump_roomq{$hostpart}) {
1111 print " " . $error{$hostpart};
1116 $dusize += $size{$hostpart};
1117 $duesize += $esize{$hostpart};
1119 elsif($dump_finished{$hostpart} == 1 &&
1120 $taper_started{$hostpart} != 1) {
1121 if( defined $opt_waittaper ) {
1122 printf "%8s ", $datestamp if defined $opt_date;
1123 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1124 printf "%9d$unit", $size{$hostpart};
1126 if( defined $starttime ) {
1127 print " (", &showtime($dump_time{$hostpart}), ")";
1129 print ", wait for writing to tape";
1130 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1132 $exit_status |= $STATUS_FAILED;
1137 $dsize += $size{$hostpart};
1138 $desize += $esize{$hostpart};
1140 $twsize += $size{$hostpart};
1141 $twesize += $esize{$hostpart};
1144 printf "%8s ", $datestamp if defined $opt_date;
1145 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1146 print " unknown state DUMPER\n";
1149 elsif(defined $flush{$hostpart}) {
1150 if( defined $opt_waittaper ) {
1151 printf "%8s ", $datestamp if defined $opt_date;
1152 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1153 printf "%9d$unit", $size{$hostpart};
1154 print " waiting to flush";
1155 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1157 $exit_status |= $STATUS_FAILED;
1162 $wfsize += $size{$hostpart};
1164 elsif(defined $level{$hostpart}) {
1165 printf "%8s ", $datestamp if defined $opt_date;
1166 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1167 print " unknown state\n";
1174 if (defined $opt_summary) {
1176 print "SUMMARY part real estimated\n";
1177 print " size size\n";
1178 printf "partition : %3d\n", $nb_partition;
1179 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1180 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1181 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1182 $fpartition , $fsize,
1183 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1184 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1185 $wpartition , $wsize,
1186 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1187 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1188 $dtpartition, $dtesize,
1189 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1190 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1191 $dupartition, $dusize, $duesize,
1192 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1193 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1194 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1195 $dpartition , $dsize , $desize,
1196 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1197 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1198 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1199 $twpartition, $twsize, $twesize,
1200 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1201 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1202 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1203 $wfpartition, $wfsize, $wfsize, 100, 0;
1204 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1205 $tapartition, $tasize, $taesize,
1206 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1207 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1208 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1209 $tfpartition, $tfsize, $tfesize,
1210 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1211 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1212 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1213 $tpartition , $tsize , $tesize,
1214 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1215 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1216 if($nb_tape > 1 || $tape_size != 0) {
1217 for($i=1; $i <= $nb_tape; $i++) {
1218 if($tape_size != 0) {
1219 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s",
1220 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1221 if($ntchunk{$i} > 0) {
1222 printf " (%d chunks)", $ntchunk{$i};
1227 printf " tape %-3d : %3d %9d$unit %9d$unit %s\n",
1228 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1232 if($idle_dumpers ==0) {
1233 printf "all dumpers active\n";
1236 $c1 = ($idle_dumpers == 1) ? "" : "s";
1237 $c2 = ($idle_dumpers < 10) ? " " : "";
1238 $c3 = ($idle_dumpers == 1) ? " " : "";
1239 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1241 if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
1242 printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
1245 printf "taper idle\n";
1247 if (defined ($free{"kps:"})) {
1248 printf "network free kps: %9d\n", $free{"kps:"};
1250 if (defined ($free{"space:"})) {
1251 if ($holding_space) {
1252 $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
1256 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space:"}/$unitdivisor), $hs;
1260 if(defined $opt_stats) {
1261 if(defined($current_time) && $current_time != $start_time) {
1262 $total_time=$current_time-$start_time;
1263 foreach $key (sort byprocess keys %busy_time) {
1264 printf "%8s busy : %8s (%6.2f%%)\n",
1265 $key, &busytime($busy_time{$key}),
1266 ($busy_time{$key} * 1.0 / $total_time) * 100;
1268 for ($d = 0; $d <= $#dumpers_active; $d++) {
1269 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1270 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1271 &busytime($dumpers_active[$d]),
1272 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1275 $s2 = " " x length($l);
1276 $r = $dumpers_held[$d];
1277 foreach $key (sort valuesort keys %$r) {
1279 unless $dumpers_held[$d]{$key} >= 1;
1280 printf "%s%20s: %8s (%6.2f%%)\n",
1283 &busytime($dumpers_held[$d]{$key}),
1284 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1296 sub make_hostpart() {
1297 local($host,$partition,$datestamp) = @_;
1299 if(! defined($hosts{$host})) {
1304 foreach $pp (sort @$host) {
1305 $new_part = 0 if ($pp eq $partition);
1307 push @$host, $partition if $new_part==1;
1309 my($hostpart) = "$host$partition$datestamp";
1310 if(!defined $datestamp{$datestamp}) {
1311 $datestamp{$datestamp} = 1;
1312 push @datestamp, $datestamp;
1318 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1319 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1320 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1324 $r->{$b} <=> $r->{$a};
1328 local($filename) = @_;
1331 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1332 $atime,$mtime,$ctime,$blksize,$blocks);
1333 while ($filename ne "") {
1334 $filename = "$filename.tmp" if (!(-e "$filename"));
1335 $filename = "/dev/null" if (!(-e "$filename"));
1336 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1337 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1338 $size=$size-32768 if $size > 32768;
1340 open(DUMP,$filename);
1343 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1344 last if /^To restore, position tape at start of file and run/;
1359 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1360 'Jul','Aug','Sep','Oct','Nov','Dec');
1362 # Preset an array of values in case some parts are not passed as
1363 # arguments. This lets the date, etc, be omitted and default to
1372 # See if this argument looks like a month name.
1378 $month = $month + 1;
1385 # See if this is a day of the month.
1387 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1392 # See if the next argument looks like a time.
1394 if ($a =~ /^(\d+):(\d+)/) {
1397 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1403 # See if this is a year.
1405 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1411 $time = &timelocal (@tl);
1416 sub set_starttime() {
1421 # Preset an array of values in case some parts are not passed as
1422 # arguments. This lets the date, etc, be omitted and default to
1428 $tl[5] = substr($date, 0, 4) if(length($date) >= 4);
1429 $tl[4] = substr($date, 4, 2)-1 if(length($date) >= 6);
1430 $tl[3] = substr($date, 6, 2) if(length($date) >= 8);
1431 $tl[2] = substr($date, 8, 2) if(length($date) >= 10);
1432 $tl[1] = substr($date, 10, 2) if(length($date) >= 12);
1433 $tl[0] = substr($date, 12, 2) if(length($date) >= 14);
1435 $time = &timelocal (@tl);
1442 my($oneday)=24*60*60;
1444 @now=localtime($starttime+$delta);
1445 if($delta > $oneday) {
1446 $result=sprintf("%d+",$delta/$oneday);
1450 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1456 my($oneday)=24*60*60;
1458 if($busy > $oneday) {
1459 $days=int($busy/$oneday);
1460 $result=sprintf("%d+",$busy/$oneday);
1461 $busy-=$days*$oneday;
1465 $hours=int($busy/60/60);
1466 $busy-=$hours*60*60;
1467 $minutes=int($busy/60);
1470 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1475 print "amstatus [--config] config [--file amdump_file]\n";
1476 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1477 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1478 print " [--estimate] [--gestimate] [--stats] [--date]\n";