5 eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
6 & eval 'exec @PERL@ -S $0 $argv:q'
9 require "newgetopt.pl";
12 $confdir="@CONFIG_DIR@";
14 $prefix=$prefix; # avoid warnings about possible typo
15 $exec_prefix="@exec_prefix@";
16 $exec_prefix=$exec_prefix; # ditto
19 $USE_VERSION_SUFFIXES='@USE_VERSION_SUFFIXES@';
21 if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
25 $result = &NGetOpt ( "summary",
28 "waitdumping|wdumping",
35 "gestimate|gettingestimate",
44 if( defined $opt_config ) {
56 #untaint user input $ARGV[0]
58 if ($conf =~ /^([\w.-]+)$/) { # $1 is untainted
61 die "filename '$conf' has invalid characters.\n";
65 if ( ! -d "$confdir/$conf" ) {
66 die "amstatus$suf: could not find directory $confdir/$conf";
69 $oldPATH = $ENV{'PATH'};
70 $ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; # force known path
74 chdir "$confdir/$conf";
76 $logdir=`$sbindir/amgetconf$suf logdir`;
79 $errfile="$logdir/amdump";
81 $nb_options = defined( $opt_summary ) +
82 defined( $opt_stats ) +
83 defined( $opt_dumping ) +
84 defined( $opt_waitdumping ) +
85 defined( $opt_waittaper ) +
86 defined( $opt_dumpingtape ) +
87 defined( $opt_writingtape ) +
88 defined( $opt_finished ) +
89 defined( $opt_estimate ) +
90 defined( $opt_gestimate ) +
91 defined( $opt_failed );
93 if($nb_options == 0 ) {
100 $opt_writingtape = 1;
107 $unit=`$sbindir/amgetconf$suf displayunit`;
108 $ENV{'PATH'} = $oldPATH;
115 elsif($unit eq 'M') {
119 elsif($unit eq 'G') {
120 $unitdivisor = 1024*1024;
123 elsif($unit eq 'T') {
124 $unitdivisor = 1024*1024*1024;
129 if( defined $opt_file) {
130 if( $opt_file =~ m,^/, ) {
131 $errfile = $opt_file;
133 $errfile = "$pwd/$opt_file";
134 $errfile = "$logdir/$opt_file" if ( ! (-f $errfile ));
138 $errfile="$logdir/amflush" if(! (-f $errfile));
140 if (-f "$logdir/amflush.1" && -f "$logdir/amdump.1" &&
141 -M "$logdir/amflush.1" < -M "$logdir/amdump.1") {
142 $errfile="$logdir/amflush.1";
144 $errfile="$logdir/amdump.1";
149 open(AMDUMP,"<$errfile") || die("$errfile: $!");
150 print "Using $errfile";
152 $start_degraded_mode = 0;
154 $label = ""; # -w fodder
155 $origsize = 0; # -w fodder
162 @dumpers_active = ();
164 $ntpartition{$nb_tape} = 0;
165 $ntsize{$nb_tape} = 0;
166 $ntesize{$nb_tape} = 0;
171 if(/(amdump|amflush): start at (.*)/) {
173 $starttime=&unctime(split(/[ ]+/,$2));
175 elsif(/amdump: datestamp (\S+)/) {
177 if(!defined $datestamp{$gdatestamp}) {
178 $datestamp{$gdatestamp} = 1;
179 push @datestamp, $gdatestamp;
182 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\)/) {
185 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
186 $estimate{$hostpart}=0;
189 $dump_started{$hostpart}=0;
190 $dump_finished{$hostpart}=0;
191 $taper_started{$hostpart}=0;
192 $taper_finished{$hostpart}=0;
193 $partialestimate{$hostpart}=0;
194 $error{$hostpart}="";
195 if($4 != -1) { $getest{$hostpart} .= ":$4:" };
196 if($5 != -1) { $getest{$hostpart} .= ":$5:" };
197 if($6 != -1) { $getest{$hostpart} .= ":$6:" };
199 elsif(/setup_estimate: (\S+):(\S+): command .*, options:/) {
202 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
203 $estimate{$hostpart}=0;
206 $dump_started{$hostpart}=0;
207 $dump_finished{$hostpart}=0;
208 $taper_started{$hostpart}=0;
209 $taper_finished{$hostpart}=0;
210 $partialestimate{$hostpart}=0;
211 $error{$hostpart}="";
213 while (! /getting estimates/) { $_ = <AMDUMP>; }
215 if(/getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
216 if($1 != -1) { $getest{$hostpart} .= ":$1:" };
217 if($2 != -1) { $getest{$hostpart} .= ":$2:" };
218 if($3 != -1) { $getest{$hostpart} .= ":$3:" };
224 elsif(/got result for host (\S+) disk (\S+): (\d+) -> (\d+)K,/) {
227 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
228 $estimate{$hostpart}=1;
229 $level{$hostpart}=$3;
230 $esize{$hostpart}=$4 / $unitdivisor;
231 $partialestimate{$hostpart}=0;
232 $getest{$hostpart} = "";
234 elsif(/got partial result for host (\S+) disk (\S+): (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K/) {
237 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
238 if($4 > 0 || $6 > 0 || $8 > 0) {
239 $estimate{$hostpart}=1;
240 $level{$hostpart}=$3;
241 $esize{$hostpart}=$4 / $unitdivisor;
242 $partialestimate{$hostpart}=1;
243 if($4 > 0) { $getest{$hostpart} =~ s/:$3://; }
244 if($6 > 0) { $getest{$hostpart} =~ s/:$5://; }
245 if($8 > 0) { $getest{$hostpart} =~ s/:$7://; }
247 if($getest{$hostpart} eq "") { $partialestimate{$hostpart}=0; }
250 elsif(/getting estimates took/) {
256 elsif(/GENERATING SCHEDULE:/) {
257 $generating_schedule=1;
259 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
260 if($generating_schedule == 1 ) {
263 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
264 $level{"$hostpart"}=$4;
266 $esize=32 if $esize<32;
267 $esize{$hostpart}=$esize / $unitdivisor;
268 $degr_level{$hostpart}=-1;
271 elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
272 if($generating_schedule == 1 ) {
276 $hostpart=&make_hostpart($host,$partition,$datestamp);
277 $level{"$hostpart"}=$5;
279 $esize=32 if $esize<32;
280 $esize{$hostpart}=$esize / $unitdivisor;
281 $degr_level{$hostpart}=-1;
284 elsif(/^DUMP (\S+) (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
285 if($generating_schedule == 1 ) {
291 $hostpart=&make_hostpart($host,$partition,$datestamp);
292 $level{"$hostpart"}=$6;
294 $esize=32 if $esize<32;
295 $esize{$hostpart}=$esize / $unitdivisor;
296 $degr_level{$hostpart}=-1;
299 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
300 if($generating_schedule == 1 ) {
303 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
304 $level{$hostpart}=$4;
306 $esize=32 if $esize<32;
307 $esize{$hostpart}=$esize / $unitdivisor;
308 $degr_level{$hostpart}=$6;
309 $degr_size{$hostpart}=$7 / $unitdivisor;
310 $degr_size{$hostpart}=32 if ($7 < 32);
313 elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
314 if($generating_schedule == 1 ) {
318 $hostpart=&make_hostpart($host,$partition,$datestamp);
319 $level{$hostpart}=$5;
321 $esize=32 if $esize<32;
322 $esize{$hostpart}=$esize / $unitdivisor;
323 $degr_level{$hostpart}=$7;
324 $degr_size{$hostpart}=$8 / $unitdivisor;
325 $degr_size{$hostpart}=32 if ($8 < 32);
328 elsif(/^FLUSH (\S+) (\S+) (\S+) (\d+) (\S+)/) {
334 $hostpart=&make_hostpart($host,$partition,$datestamp);
336 $holding_file{$hostpart}=$holding_file;
337 $level{$hostpart}=$level;
339 elsif(/^driver: start time (\S+)/) {
342 $dumpers_active[0]=0;
346 elsif(/^driver: tape size (\d+)/) {
347 $tape_size = $1 / $unitdivisor;
349 elsif(/^driver: adding holding disk \d+ dir \S+ size (\d+)/) {
350 $holding_space += $1;
352 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
356 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
358 $serial{$serial}=$hostpart;
359 $dump_started{$hostpart}=1;
360 $dump_time{$hostpart}=$1;
361 $dump_finished{$hostpart}=0;
362 if( $level{$hostpart} != $8 &&
363 $degr_level{$hostpart} == $8) {
364 $level{$hostpart}=$degr_level{$hostpart};
365 $esize{$hostpart}=$degr_size{$hostpart};
367 if(! defined($busy_time{$2})) {
370 $running_dumper{$2} = $hostpart;
371 $error{$hostpart}="";
373 if(! defined($dumpers_active[$dumpers_active])) {
374 $dumpers_active[$dumpers_active]=0;
376 if(! defined($dumpers_held[$dumpers_active])) {
377 $dumpers_held[$dumpers_active]={};
380 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
384 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
386 $serial{$serial}=$hostpart;
387 #$chunk_started{$hostpart}=1;
388 #$chunk_time{$hostpart}=$1;
389 #$chunk_finished{$hostpart}=0;
390 $holding_file{$hostpart}=$5;
392 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
398 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
400 $serial{$serial}=$hostpart;
401 #$chunk_started{$hostpart}=1;
402 #$chunk_time{$hostpart}=$1;
403 #$chunk_finished{$hostpart}=0;
404 $holding_file{$hostpart}=$5;
406 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
412 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
414 $serial{$serial}=$hostpart;
415 $dump_started{$hostpart}=1;
416 $dump_time{$hostpart}=$1;
417 $dump_finished{$hostpart}=0;
418 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
419 if( $level{$hostpart} != $9 &&
420 $degr_level{$hostpart} == $9) {
421 $level{$hostpart}=$degr_level{$hostpart};
422 $esize{$hostpart}=$degr_size{$hostpart};
424 if(! defined($busy_time{$2})) {
427 $running_dumper{$2} = $hostpart;
428 $error{$hostpart}="";
430 if(! defined($dumpers_active[$dumpers_active])) {
431 $dumpers_active[$dumpers_active]=0;
433 if(! defined($dumpers_held[$dumpers_active])) {
434 $dumpers_held[$dumpers_active]={};
437 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
445 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
447 $serial{$serial}=$hostpart;
448 $dump_started{$hostpart}=1;
449 $dump_time{$hostpart}=$1;
450 $dump_finished{$hostpart}=0;
451 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
452 if( $level{$hostpart} != $10 &&
453 $degr_level{$hostpart} == $10) {
454 $level{$hostpart}=$degr_level{$hostpart};
455 $esize{$hostpart}=$degr_size{$hostpart};
457 if(! defined($busy_time{$2})) {
460 $running_dumper{$2} = $hostpart;
461 $error{$hostpart}="";
463 if(! defined($dumpers_active[$dumpers_active])) {
464 $dumpers_active[$dumpers_active]=0;
466 if(! defined($dumpers_held[$dumpers_active])) {
467 $dumpers_held[$dumpers_active]={};
470 elsif(/driver: send-cmd time (\S+) to (chunker\d*): CONTINUE (\d+-\d+) (\S+) (\d+) (\d+)/) {
473 $hostpart=$serial{$serial};
474 if($hostpart ne "") {
475 $dump_roomq{$hostpart}=undef;
476 $error{$hostpart}="";
479 elsif(/driver: result time (\S+) from (dumper\d+): FAILED (\d+-\d+) (.*)/) {
483 $hostpart=$serial{$serial};
484 $dump_finished{$hostpart}=-1;
485 $busy_time{$2}+=($1-$dump_time{$hostpart});
486 $running_dumper{$2} = "0";
487 $dump_time{$hostpart}=$1;
488 $error{$hostpart}="driver: $error";
491 elsif(/driver: result time (\S+) from (dumper\d+): TRY-AGAIN (\d+-\d+) (.*)/) {
495 $hostpart=$serial{$serial};
496 $dump_started{$hostpart}=0;
497 $dump_finished{$hostpart}=0;
498 $busy_time{$2}+=($1-$dump_time{$hostpart});
499 $running_dumper{$2} = "0";
500 $dump_time{$hostpart}=$1;
501 $error{$hostpart}="driver: (aborted:$error)";
504 elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) \[.*\]/) {
507 $origsize=$5 / $unitdivisor;
508 $outputsize=$6 / $unitdivisor;
509 $hostpart=$serial{$serial};
510 $size{$hostpart}=$outputsize;
511 $dump_finished{$hostpart}=1;
512 $busy_time{$2}+=($1-$dump_time{$hostpart});
513 $running_dumper{$2} = "0";
514 $dump_time{$hostpart}=$1;
515 $error{$hostpart}="";
517 $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
519 elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) \[.*\]/) {
522 $outputsize=$5 / $unitdivisor;
523 $hostpart=$serial{$serial};
524 $size{$hostpart}=$outputsize;
525 $dump_finished{$hostpart}=1;
526 $busy_time{$2}+=($1-$dump_time{$hostpart});
527 $running_dumper{$2} = "0";
528 $dump_time{$hostpart}=$1;
529 $error{$hostpart}="";
530 $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
532 elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
535 $hostpart=$serial{$serial};
536 $dump_started{$hostpart}=0;
537 $dump_finished{$hostpart}=0;
538 $busy_time{$2}+=($1-$dump_time{$hostpart});
539 $running_dumper{$2} = "0";
540 $dump_time{$hostpart}=$1;
541 $error{$hostpart}="driver: (aborted)";
544 elsif(/driver: result time (\S+) from (chunker\d+): RQ-MORE-DISK (\d+-\d+)/) {
547 $hostpart=$serial{$serial};
548 $dump_roomq{$hostpart}=1;
549 $error{$hostpart}="(waiting for holding disk space)";
551 elsif(/driver: finished-cmd time (\S+) dumper\d+ dumped (\S+):(\S+)/){
554 elsif(/driver: send-cmd time (\S+) to taper: START-TAPER (\S+)/) {
555 if(!defined $gdatestamp) {
557 if(!defined $datestamp{$gdatestamp}) {
558 $datestamp{$gdatestamp} = 1;
559 push @datestamp, $gdatestamp;
563 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S+) (\d*) (\S+)/){
570 if(!defined $datestamp{$ldatestamp}) {
571 $datestamp{$ldatestamp} = 1;
572 push @datestamp, $ldatestamp;
574 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
575 $serial{$serial}=$hostpart;
576 if(!defined $level{$hostpart}) {
577 $level{$hostpart} = $level;
579 $serial{$serial}=$hostpart;
580 $taper_started{$hostpart}=1;
581 $taper_finished{$hostpart}=0;
582 $taper_time{$hostpart}=$1;
584 #features (maybe missing features)
585 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S*) (\S+) (\d*) (\S+)/){
594 if(!defined $datestamp{$ldatestamp}) {
595 $datestamp{$ldatestamp} = 1;
596 push @datestamp, $ldatestamp;
598 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
599 $serial{$serial}=$hostpart;
600 if(!defined $level{$hostpart}) {
601 $level{$hostpart} = $level;
603 $serial{$serial}=$hostpart;
604 $taper_started{$hostpart}=1;
605 $taper_finished{$hostpart}=0;
606 $taper_time{$hostpart}=$1;
608 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) \d+( \d+|)/){
613 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
614 $serial{$serial}=$hostpart;
615 $taper_started{$hostpart}=1;
616 $taper_finished{$hostpart}=0;
617 $taper_time{$hostpart}=$1;
619 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) (\S+) \d+ \d+/){
625 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
626 $serial{$serial}=$hostpart;
627 $taper_started{$hostpart}=1;
628 $taper_finished{$hostpart}=0;
629 $taper_time{$hostpart}=$1;
631 elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) \[sec (\S+) kb (\d+) kps/) {
635 $size=$7 / $unitdivisor;
636 $hostpart=$serial{$serial};
637 $taper_finished{$hostpart}=1;
638 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
639 $taper_time{$hostpart}=$1;
640 if(!defined $size{$hostpart}) {
641 $size{$hostpart}=$size;
643 $ntpartition{$nb_tape}++;
644 $ntsize{$nb_tape} += $size{$hostpart};
645 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
646 $ntesize{$nb_tape} += $esize{$hostpart};
649 $ntesize{$nb_tape} += $size{$hostpart};
651 $partial{$hostpart}=1 if $3 eq "PARTIAL" ;
653 elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
657 $hostpart=$serial{$serial};
658 $taper_finished{$hostpart}= $2 eq 'TAPE-ERROR' ? -2 : -1;
659 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
660 $taper_time{$hostpart}=$1;
661 $error{$hostpart}="driver: $error";
663 elsif(/driver: dump failed (\S+) (\S+) (\S+), too many dumper retry/) {
665 $hostpart=$serial{$serial};
666 $dump_started{$hostpart}=-1;
667 $dump_finished{$hostpart}=-2;
668 $error{$hostpart} .= "(too many dumper retry)";
670 elsif(/driver: tape failed (\S+) (\S+) (\S+), too many taper retry/) {
672 $hostpart=$serial{$serial};
673 $taper_started{$hostpart}=-1;
674 $taper_finished{$hostpart}=-2;
675 $error{$hostpart} .= "(too many taper retry)";
677 elsif(/planner: FAILED (\S+) (\S+) (\S+) (-?\d+) (.*)/) {
681 $hostpart=&make_hostpart($host,$partition,$datestamp);
682 $dump_started{$hostpart}=-1;
683 $level{$hostpart}=$4;
684 $error{$hostpart}="planner: $5";
686 elsif(/dump of driver schedule after start degraded mode:/) {
687 $start_degraded_mode=1;
689 elsif(/driver: state time (\S+) free (.*) taper: (\S+) idle-dumpers: (\d+) qlen (.*) driver-idle: (\S+)/) {
694 %free = split (/ +/, $2);
695 %qlen = split (/ +/, $5);
697 if($status_driver ne "") {
698 $dumpers_active[$dumpers_active_prev]
699 +=$current_time-$state_time_prev;
700 $dumpers_held[$dumpers_active_prev]{$status_driver}
701 +=$current_time-$state_time_prev;
703 $state_time_prev=$current_time;
704 $dumpers_active_prev=$dumpers_active;
706 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
707 $dumpers_held[$dumpers_active]{$status_driver}=0;
710 elsif(/taper: wrote label `(\S*)'/) {
712 $ntlabel{$nb_tape} = $1;
713 $ntpartition{$nb_tape} = 0;
714 $ntsize{$nb_tape} = 0;
715 $ntesize{$nb_tape} = 0;
718 #print "Ignoring: $_\n";
724 if(defined $current_time) {
725 for ($d = 0; $d < $#dumpers_active; $d++) {
726 $the_dumper = "dumper$d";
727 if(defined($running_dumper{$the_dumper}) &&
728 $running_dumper{$the_dumper} ne "0") {
729 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
773 foreach $host (sort @hosts) {
774 foreach $partition (sort @$host) {
775 foreach $datestamp (sort @datestamp) {
776 $hostpart=&make_hostpart($host,$partition,$datestamp);
777 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
778 if(length("$host:$partition") > $maxnamelength) {
779 $maxnamelength = length("$host:$partition");
785 foreach $host (sort @hosts) {
786 foreach $partition (sort @$host) {
787 foreach $datestamp (sort @datestamp) {
788 $hostpart=&make_hostpart($host,$partition,$datestamp);
789 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
791 if( !defined $size{$hostpart} && defined $holding_file{$hostpart}) {
792 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
795 if($estimate_done != 1 && !defined $flush{$hostpart}) {
796 if(defined $estimate{$hostpart}) {
797 if($estimate{$hostpart} != 1) {
798 if( defined $opt_gestimate) {
799 printf "%8s ", $datestamp if defined $opt_date;
800 printf "%-${maxnamelength}s", "$host:$partition";
801 print " getting estimate\n";
805 if(defined $opt_estimate ||
806 (defined $opt_gestimate && $partialestimate{$hostpart} == 1)) {
807 printf "%8s ", $datestamp if defined $opt_date;
808 printf "%-${maxnamelength}s", "$host:$partition";
809 printf "%2d", $level{$hostpart};
810 printf "%9d$unit", $esize{$hostpart};
811 if($partialestimate{$hostpart} == 1) {
814 print " estimate done\n";
817 $estsize += $esize{$hostpart};
822 if(defined $estimate{$hostpart}) {
823 if($estimate{$hostpart} == 1) {
825 $estsize += $esize{$hostpart};
827 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
828 if( defined $opt_failed) {
829 printf "%8s ", $datestamp if defined $opt_date;
830 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
831 printf " no estimate\n";
838 $flsize += $size{$hostpart};
841 if(defined $taper_started{$hostpart} &&
842 $taper_started{$hostpart}==1) {
843 if(defined $dump_started{$hostpart}) {
845 if(defined($size{$hostpart})) {
846 $dsize += $size{$hostpart};
849 $dsize += $esize{$hostpart};
851 $desize += $esize{$hostpart};
853 if(defined $dump_started{$hostpart} &&
854 $dump_started{$hostpart} == 1 &&
855 $dump_finished{$hostpart} == 0 &&
856 $taper_started{$hostpart} == 1) {
857 if( defined $opt_dumpingtape ) {
858 printf "%8s ", $datestamp if defined $opt_date;
859 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
860 printf "%9d$unit", $esize{$hostpart};
861 print " dumping to tape";
862 if( defined $starttime ) {
863 print " (", &showtime($taper_time{$hostpart}), ")";
868 $dtesize += $esize{$hostpart};
870 elsif($taper_finished{$hostpart} == 0) {
871 if( defined $opt_writingtape ) {
872 printf "%8s ", $datestamp if defined $opt_date;
873 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
874 printf "%9d$unit", $size{$hostpart};
876 print " writing to tape";
879 print " flushing to tape";
881 if( defined $starttime ) {
882 print " (", &showtime($taper_time{$hostpart}), ")";
887 $tasize += $size{$hostpart};
888 if(defined $esize{$hostpart}) {
889 $taesize += $esize{$hostpart};
892 $taesize += $size{$hostpart};
895 elsif($taper_finished{$hostpart} < 0) {
897 if(defined $size{$hostpart}) {
898 $xsize = $size{$hostpart};
900 elsif(defined $esize{$hostpart}) {
901 $xsize = $esize{$hostpart};
907 if(defined $esize{$hostpart}) {
908 $exsize += $esize{$hostpart};
914 if( defined $opt_failed ||
915 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
916 printf "%8s ", $datestamp if defined $opt_date;
917 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
918 printf "%9d$unit", $xsize;
920 print " failed to tape";
923 print " failed to flush";
925 print " (will retry)" unless $taper_finished{$hostpart} < -1;
926 if( defined $starttime ) {
927 print " (", &showtime($taper_time{$hostpart}), ")";
946 elsif($taper_finished{$hostpart} == 1) {
947 if( defined $opt_finished ) {
948 printf "%8s ", $datestamp if defined $opt_date;
949 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
950 printf "%9d$unit", $size{$hostpart};
957 if( defined $starttime ) {
958 print " (", &showtime($taper_time{$hostpart}), ")";
960 print ", PARTIAL" if defined $partial{$hostpart};
964 $tsize += $size{$hostpart};
965 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
966 $tesize += $esize{$hostpart};
969 $tesize += $size{$hostpart};
973 printf "%8s ", $datestamp if defined $opt_date;
974 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
975 print " unknown state TAPER\n";
978 elsif(defined $dump_started{$hostpart}) {
979 if($dump_started{$hostpart} == -1) {
980 if( defined $opt_failed ) {
981 printf "%8s ", $datestamp if defined $opt_date;
982 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
983 printf " " . $error{$hostpart} . "\n";
986 $fsize+=$esize{$hostpart};
988 elsif($dump_started{$hostpart} == 0) {
989 if($estimate{$hostpart} == 1) {
990 if( defined $opt_waitdumping ) {
991 printf "%8s ", $datestamp if defined $opt_date;
992 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
993 printf "%9d$unit", $esize{$hostpart};
994 print " wait for dumping $error{$hostpart}\n";
997 $wsize += $esize{$hostpart};
1000 elsif($dump_started{$hostpart} == 1 &&
1001 $dump_finished{$hostpart} == -1) {
1002 if( defined $opt_failed ) {
1003 printf "%8s ", $datestamp if defined $opt_date;
1004 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1005 print " ", $error{$hostpart};
1006 if( defined $starttime ) {
1007 print " (", &showtime($dump_time{$hostpart}), ")";
1012 $fsize+=$esize{$hostpart};
1014 elsif($dump_started{$hostpart} == 1 &&
1015 $dump_finished{$hostpart} != 1) {
1016 if( defined $opt_dumping ) {
1017 printf "%8s ", $datestamp if defined $opt_date;
1018 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1019 printf "%9d$unit", $esize{$hostpart};
1020 printf " dumping %8d$unit", $size{$hostpart};
1021 if($size{$hostpart} != 0) {
1022 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1024 if( defined $starttime ) {
1025 print " (", &showtime($dump_time{$hostpart}), ")";
1027 if(defined $dump_roomq{$hostpart}) {
1028 print " " . $error{$hostpart};
1033 $dusize += $size{$hostpart};
1034 $duesize += $esize{$hostpart};
1036 elsif($dump_finished{$hostpart} == 1 &&
1037 $taper_started{$hostpart} != 1) {
1038 if( defined $opt_waittaper ) {
1039 printf "%8s ", $datestamp if defined $opt_date;
1040 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1041 printf "%9d$unit", $size{$hostpart};
1043 if( defined $starttime ) {
1044 print " (", &showtime($dump_time{$hostpart}), ")";
1046 print ", wait for writing to tape";
1047 print ", PARTIAL" if defined $partial{$hostpart};
1051 $dsize += $size{$hostpart};
1052 $desize += $esize{$hostpart};
1054 $twsize += $size{$hostpart};
1055 $twesize += $esize{$hostpart};
1058 printf "%8s ", $datestamp if defined $opt_date;
1059 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1060 print " unknown state DUMPER\n";
1063 elsif(defined $flush{$hostpart}) {
1064 if( defined $opt_waittaper ) {
1065 printf "%8s ", $datestamp if defined $opt_date;
1066 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1067 printf "%9d$unit", $size{$hostpart};
1068 print " waiting to flush";
1069 print ", PARTIAL" if defined $partial{$hostpart};
1073 $wfsize += $size{$hostpart};
1075 elsif(defined $level{$hostpart}) {
1076 printf "%8s ", $datestamp if defined $opt_date;
1077 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1078 print " unknown state\n";
1085 if (defined $opt_summary) {
1087 print "SUMMARY part real estimated\n";
1088 print " size size\n";
1089 printf "partition : %3d\n", $nb_partition;
1090 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1091 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1092 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1093 $fpartition , $fsize,
1094 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1095 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1096 $wpartition , $wsize,
1097 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1098 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1099 $dtpartition, $dtesize,
1100 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1101 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1102 $dupartition, $dusize, $duesize,
1103 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1104 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1105 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1106 $dpartition , $dsize , $desize,
1107 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1108 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1109 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1110 $twpartition, $twsize, $twesize,
1111 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1112 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1113 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1114 $wfpartition, $wfsize, $wfsize, 100, 0;
1115 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1116 $tapartition, $tasize, $taesize,
1117 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1118 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1119 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1120 $tfpartition, $tfsize, $tfesize,
1121 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1122 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1123 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1124 $tpartition , $tsize , $tesize,
1125 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1126 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1127 if($nb_tape > 1 || $tape_size != 0) {
1128 for($i=1; $i <= $nb_tape; $i++) {
1129 if($tape_size != 0) {
1130 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s\n",
1131 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1134 printf " tape %-3d : %3d %9d$unit %9d$unit %s\n",
1135 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1139 if($idle_dumpers ==0) {
1140 printf "all dumpers active\n";
1143 $c1 = ($idle_dumpers == 1) ? "" : "s";
1144 $c2 = ($idle_dumpers < 10) ? " " : "";
1145 $c3 = ($idle_dumpers == 1) ? " " : "";
1146 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1148 if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
1149 printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
1152 printf "taper idle\n";
1154 if (defined ($free{"kps:"})) {
1155 printf "network free kps: %9d\n", $free{"kps:"};
1157 if (defined ($free{"space:"})) {
1158 if ($holding_space) {
1159 $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
1163 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space:"}/$unitdivisor), $hs;
1167 if(defined $opt_stats) {
1168 if(defined($current_time) && $current_time != $start_time) {
1169 $total_time=$current_time-$start_time;
1170 foreach $key (sort byprocess keys %busy_time) {
1171 printf "%8s busy : %8s (%6.2f%%)\n",
1172 $key, &busytime($busy_time{$key}),
1173 ($busy_time{$key} * 1.0 / $total_time) * 100;
1175 for ($d = 0; $d <= $#dumpers_active; $d++) {
1176 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1177 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1178 &busytime($dumpers_active[$d]),
1179 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1182 $s2 = " " x length($l);
1183 $r = $dumpers_held[$d];
1184 foreach $key (sort valuesort keys %$r) {
1186 unless $dumpers_held[$d]{$key} >= 1;
1187 printf "%s%20s: %8s (%6.2f%%)\n",
1190 &busytime($dumpers_held[$d]{$key}),
1191 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1201 sub make_hostpart() {
1202 local($host,$partition,$datestamp) = @_;
1204 if(! defined($hosts{$host})) {
1209 foreach $pp (sort @$host) {
1210 $new_part = 0 if ($pp eq $partition);
1212 push @$host, $partition if $new_part==1;
1214 my($hostpart) = "$host$partition$datestamp";
1215 if(!defined $datestamp{$datestamp}) {
1216 $datestamp{$datestamp} = 1;
1217 push @datestamp, $datestamp;
1223 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1224 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1225 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1229 $r->{$b} <=> $r->{$a};
1233 local($filename) = @_;
1236 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1237 $atime,$mtime,$ctime,$blksize,$blocks);
1238 while ($filename ne "") {
1239 $filename = "$filename.tmp" if (!(-e "$filename"));
1240 $filename = "/dev/null" if (!(-e "$filename"));
1241 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1242 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1243 $size=$size-32768 if $size > 32768;
1245 open(DUMP,$filename);
1248 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1249 last if /^To restore, position tape at start of file and run/;
1264 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1265 'Jul','Aug','Sep','Oct','Nov','Dec');
1267 # Preset an array of values in case some parts are not passed as
1268 # arguments. This lets the date, etc, be omitted and default to
1277 # See if this argument looks like a month name.
1283 $month = $month + 1;
1290 # See if this is a day of the month.
1292 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1297 # See if the next argument looks like a time.
1299 if ($a =~ /^(\d+):(\d+)/) {
1302 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1308 # See if this is a year.
1310 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1316 $time = &timelocal (@tl);
1323 my($oneday)=24*60*60;
1325 @now=localtime($starttime+$delta);
1326 if($delta > $oneday) {
1327 $result=sprintf("%d+",$delta/$oneday);
1331 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1337 my($oneday)=24*60*60;
1339 if($busy > $oneday) {
1340 $days=int($busy/$oneday);
1341 $result=sprintf("%d+",$busy/$oneday);
1342 $busy-=$days*$oneday;
1346 $hours=int($busy/60/60);
1347 $busy-=$hours*60*60;
1348 $minutes=int($busy/60);
1351 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1356 print "amstatus [--config] config [--file amdump_file]\n";
1357 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1358 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1359 print " [--estimate] [--gestimate] [--stats] [--date]\n";