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(/planner: timestamp (\S+)/) {
184 if(!defined $datestamp{$gdatestamp}) {
185 $datestamp{$gdatestamp} = 1;
186 push @datestamp, $gdatestamp;
189 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\)/) {
192 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
193 $estimate{$hostpart}=0;
196 $dump_started{$hostpart}=0;
197 $dump_finished{$hostpart}=0;
198 $taper_started{$hostpart}=0;
199 $taper_finished{$hostpart}=0;
200 $partialestimate{$hostpart}=0;
201 $error{$hostpart}="";
202 if($4 != -1) { $getest{$hostpart} .= ":$4:" };
203 if($5 != -1) { $getest{$hostpart} .= ":$5:" };
204 if($6 != -1) { $getest{$hostpart} .= ":$6:" };
206 elsif(/setup_estimate: (\S+):(\S+): command .*, options:/) {
209 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
210 $estimate{$hostpart}=0;
213 $dump_started{$hostpart}=0;
214 $dump_finished{$hostpart}=0;
215 $taper_started{$hostpart}=0;
216 $taper_finished{$hostpart}=0;
217 $partialestimate{$hostpart}=0;
218 $error{$hostpart}="";
220 while (! /getting estimates/) { $_ = <AMDUMP>; }
222 if(/getting estimates (-?\d) \(-2\) (-?\d) \(-2\) (-?\d) \(-2\)/) {
223 if($1 != -1) { $getest{$hostpart} .= ":$1:" };
224 if($2 != -1) { $getest{$hostpart} .= ":$2:" };
225 if($3 != -1) { $getest{$hostpart} .= ":$3:" };
231 elsif(/got result for host (\S+) disk (\S+): (\d+) -> (\d+)K,/) {
234 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
235 $estimate{$hostpart}=1;
236 $level{$hostpart}=$3;
237 $esize{$hostpart}=$4 / $unitdivisor;
238 $partialestimate{$hostpart}=0;
239 $getest{$hostpart} = "";
241 elsif(/got partial result for host (\S+) disk (\S+): (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K, (-?\d+) -> (-?\d+)K/) {
244 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
245 if($4 > 0 || $6 > 0 || $8 > 0) {
246 $estimate{$hostpart}=1;
247 $level{$hostpart}=$3;
248 $esize{$hostpart}=$4 / $unitdivisor;
249 $partialestimate{$hostpart}=1;
250 if($4 > 0) { $getest{$hostpart} =~ s/:$3://; }
251 if($6 > 0) { $getest{$hostpart} =~ s/:$5://; }
252 if($8 > 0) { $getest{$hostpart} =~ s/:$7://; }
254 if($getest{$hostpart} eq "") { $partialestimate{$hostpart}=0; }
257 elsif(/getting estimates took/) {
263 elsif(/GENERATING SCHEDULE:/) {
264 $generating_schedule=1;
266 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
267 if($generating_schedule == 1 ) {
270 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
271 $level{"$hostpart"}=$4;
273 $esize=32 if $esize<32;
274 $esize{$hostpart}=$esize / $unitdivisor;
275 $degr_level{$hostpart}=-1;
278 elsif(/^DUMP (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
279 if($generating_schedule == 1 ) {
283 $hostpart=&make_hostpart($host,$partition,$datestamp);
284 $level{"$hostpart"}=$5;
286 $esize=32 if $esize<32;
287 $esize{$hostpart}=$esize / $unitdivisor;
288 $degr_level{$hostpart}=-1;
291 elsif(/^DUMP (\S+) (\S+) (\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+/) {
292 if($generating_schedule == 1 ) {
298 $hostpart=&make_hostpart($host,$partition,$datestamp);
299 $level{"$hostpart"}=$6;
301 $esize=32 if $esize<32;
302 $esize{$hostpart}=$esize / $unitdivisor;
303 $degr_level{$hostpart}=-1;
306 elsif(/^(\S+) (\S+) (\d+) (\d+) \d+:\d+:\d+:\d+:\d+:\d+ (\d+) \d+ (\d+) \d+:\d+:\d+:\d+:\d+:\d+ ([-]*\d+) \d+/) {
307 if($generating_schedule == 1 ) {
310 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
311 $level{$hostpart}=$4;
313 $esize=32 if $esize<32;
314 $esize{$hostpart}=$esize / $unitdivisor;
315 $degr_level{$hostpart}=$6;
316 $degr_size{$hostpart}=$7 / $unitdivisor;
317 $degr_size{$hostpart}=32 if ($7 < 32);
320 elsif(/^DUMP (\S+) (\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 ) {
325 $hostpart=&make_hostpart($host,$partition,$datestamp);
326 $level{$hostpart}=$5;
328 $esize=32 if $esize<32;
329 $esize{$hostpart}=$esize / $unitdivisor;
330 $degr_level{$hostpart}=$7;
331 $degr_size{$hostpart}=$8 / $unitdivisor;
332 $degr_size{$hostpart}=32 if ($8 < 32);
335 elsif(/^FLUSH (\S+) (\S+) (\S+) (\d+) (\S+)/) {
341 $hostpart=&make_hostpart($host,$partition,$datestamp);
343 $holding_file{$hostpart}=$holding_file;
344 $level{$hostpart}=$level;
346 elsif(/^driver: start time (\S+)/) {
349 $dumpers_active[0]=0;
353 elsif(/^driver: tape size (\d+)/) {
354 $tape_size = $1 / $unitdivisor;
356 elsif(/^driver: adding holding disk \d+ dir \S+ size (\d+)/) {
357 $holding_space += $1;
359 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
363 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
365 $serial{$serial}=$hostpart;
366 $dump_started{$hostpart}=1;
367 $dump_time{$hostpart}=$1;
368 $dump_finished{$hostpart}=0;
369 if( $level{$hostpart} != $8 &&
370 $degr_level{$hostpart} == $8) {
371 $level{$hostpart}=$degr_level{$hostpart};
372 $esize{$hostpart}=$degr_size{$hostpart};
374 if(! defined($busy_time{$2})) {
377 $running_dumper{$2} = $hostpart;
378 $error{$hostpart}="";
379 $size{$hostpart} = 0;
381 if(! defined($dumpers_active[$dumpers_active])) {
382 $dumpers_active[$dumpers_active]=0;
384 if(! defined($dumpers_held[$dumpers_active])) {
385 $dumpers_held[$dumpers_active]={};
388 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\S+) (\S+) (\d+)/) {
392 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
394 $serial{$serial}=$hostpart;
395 #$chunk_started{$hostpart}=1;
396 #$chunk_time{$hostpart}=$1;
397 #$chunk_finished{$hostpart}=0;
398 $holding_file{$hostpart}=$5;
400 elsif(/driver: send-cmd time (\S+) to (chunker\d*): (PORT-WRITE) (\d+-\d+) (\S+) (\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 (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
420 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
422 $serial{$serial}=$hostpart;
423 $dump_started{$hostpart}=1;
424 $dump_time{$hostpart}=$1;
425 $dump_finished{$hostpart}=0;
426 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
427 if( $level{$hostpart} != $9 &&
428 $degr_level{$hostpart} == $9) {
429 $level{$hostpart}=$degr_level{$hostpart};
430 $esize{$hostpart}=$degr_size{$hostpart};
432 if(! defined($busy_time{$2})) {
435 $running_dumper{$2} = $hostpart;
436 $error{$hostpart}="";
437 $size{$hostpart} = 0;
439 if(! defined($dumpers_active[$dumpers_active])) {
440 $dumpers_active[$dumpers_active]=0;
442 if(! defined($dumpers_held[$dumpers_active])) {
443 $dumpers_held[$dumpers_active]={};
446 elsif(/driver: send-cmd time (\S+) to (dumper\d*): (FILE-DUMP|PORT-DUMP) (\d+-\d+) (\S+) (\S+) (\S+) (\S+) (\S+) (\d+)/) {
454 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
456 $serial{$serial}=$hostpart;
457 $dump_started{$hostpart}=1;
458 $dump_time{$hostpart}=$1;
459 $dump_finished{$hostpart}=0;
460 $holding_file{$hostpart}=$5 if $3 eq "FILE-DUMP";
461 if( $level{$hostpart} != $10 &&
462 $degr_level{$hostpart} == $10) {
463 $level{$hostpart}=$degr_level{$hostpart};
464 $esize{$hostpart}=$degr_size{$hostpart};
466 if(! defined($busy_time{$2})) {
469 $running_dumper{$2} = $hostpart;
470 $error{$hostpart}="";
471 $size{$hostpart} = 0;
473 if(! defined($dumpers_active[$dumpers_active])) {
474 $dumpers_active[$dumpers_active]=0;
476 if(! defined($dumpers_held[$dumpers_active])) {
477 $dumpers_held[$dumpers_active]={};
480 elsif(/driver: send-cmd time (\S+) to (chunker\d*): CONTINUE (\d+-\d+) (\S+) (\d+) (\d+)/) {
483 $hostpart=$serial{$serial};
484 if($hostpart ne "") {
485 $dump_roomq{$hostpart}=undef;
486 $error{$hostpart}="";
489 elsif(/driver: result time (\S+) from (dumper\d+): FAILED (\d+-\d+) (.*)/) {
493 $hostpart=$serial{$serial};
494 $dump_finished{$hostpart}=-1;
495 $busy_time{$2}+=($1-$dump_time{$hostpart});
496 $running_dumper{$2} = "0";
497 $dump_time{$hostpart}=$1;
498 $error{$hostpart}="driver: $error";
501 elsif(/driver: result time (\S+) from (dumper\d+): TRY-AGAIN (\d+-\d+) (.*)/) {
505 $hostpart=$serial{$serial};
506 $dump_started{$hostpart}=0;
507 $dump_finished{$hostpart}=0;
508 $busy_time{$2}+=($1-$dump_time{$hostpart});
509 $running_dumper{$2} = "0";
510 $dump_time{$hostpart}=$1;
511 $error{$hostpart}="driver: (aborted:$error)";
514 elsif(/driver: result time (\S+) from (dumper\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) (\d+) (\d+) "?\[.*\]"?/) {
517 $origsize=$5 / $unitdivisor;
518 $outputsize=$6 / $unitdivisor;
519 $hostpart=$serial{$serial};
520 $size{$hostpart}=$outputsize;
521 $dump_finished{$hostpart}=1;
522 $busy_time{$2}+=($1-$dump_time{$hostpart});
523 $running_dumper{$2} = "0";
524 $dump_time{$hostpart}=$1;
525 $error{$hostpart}="";
527 if ($3 eq "PARTIAL") {
528 $partial{$hostpart} = 1;
531 $partial{$hostpart} = 0;
534 elsif(/driver: result time (\S+) from (chunker\d+): (DONE|PARTIAL) (\d+-\d+) (\d+) "?\[.*\]"?/) {
537 $outputsize=$5 / $unitdivisor;
538 $hostpart=$serial{$serial};
539 $size{$hostpart}=$outputsize;
540 $dump_finished{$hostpart}=1;
541 $busy_time{$2}+=($1-$dump_time{$hostpart});
542 $running_dumper{$2} = "0";
543 $dump_time{$hostpart}=$1;
544 $error{$hostpart}="";
545 if ($3 eq "PARTIAL") {
546 $partial{$hostpart} = 1;
549 $partial{$hostpart} = 0;
552 elsif(/driver: result time (\S+) from (dumper\d+): ABORT-FINISHED (\d+-\d+)/) {
555 $hostpart=$serial{$serial};
556 $dump_started{$hostpart}=0;
557 $dump_finished{$hostpart}=0;
558 $busy_time{$2}+=($1-$dump_time{$hostpart});
559 $running_dumper{$2} = "0";
560 $dump_time{$hostpart}=$1;
561 $error{$hostpart}="driver: (aborted)";
564 elsif(/driver: result time (\S+) from (chunker\d+): RQ-MORE-DISK (\d+-\d+)/) {
567 $hostpart=$serial{$serial};
568 $dump_roomq{$hostpart}=1;
569 $error{$hostpart}="(waiting for holding disk space)";
571 elsif(/driver: finished-cmd time (\S+) dumper\d+ dumped (\S+):(\S+)/){
574 elsif(/driver: send-cmd time (\S+) to taper: START-TAPER (\S+)/) {
575 if(!defined $gdatestamp) {
577 if(!defined $datestamp{$gdatestamp}) {
578 $datestamp{$gdatestamp} = 1;
579 push @datestamp, $gdatestamp;
583 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S+) (\d*) (\S+)/){
590 if(!defined $datestamp{$ldatestamp}) {
591 $datestamp{$ldatestamp} = 1;
592 push @datestamp, $ldatestamp;
594 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
595 $serial{$serial}=$hostpart;
596 if(!defined $level{$hostpart}) {
597 $level{$hostpart} = $level;
599 $taper_started{$hostpart}=1;
600 $taper_finished{$hostpart}=0;
601 $taper_time{$hostpart}=$1;
603 #features (maybe missing features)
604 elsif(/driver: send-cmd time (\S+) to taper: FILE-WRITE (\d+-\d+) (\S+) (\S+) (\S*) (\S+) (\d*) (\S+)/){
613 if(!defined $datestamp{$ldatestamp}) {
614 $datestamp{$ldatestamp} = 1;
615 push @datestamp, $ldatestamp;
617 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
618 $serial{$serial}=$hostpart;
619 if(!defined $level{$hostpart}) {
620 $level{$hostpart} = $level;
622 $taper_started{$hostpart}=1;
623 $taper_finished{$hostpart}=0;
624 $taper_time{$hostpart}=$1;
626 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) \d+( \d+|)/){
631 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
632 $serial{$serial}=$hostpart;
633 $taper_started{$hostpart}=1;
634 $taper_finished{$hostpart}=0;
635 $taper_time{$hostpart}=$1;
637 elsif(/driver: send-cmd time (\S+) to taper: PORT-WRITE (\d+-\d+) (\S+) (\S+) (\S+) \d+ \d+/){
643 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
644 $serial{$serial}=$hostpart;
645 $taper_started{$hostpart}=1;
646 $taper_finished{$hostpart}=0;
647 $taper_time{$hostpart}=$1;
649 elsif(/driver: result time (\S+) from taper: (DONE|PARTIAL) (\d+-\d+) (\S+) (\d+) "?\[sec (\S+) kb (\d+) kps/) {
653 $size=$7 / $unitdivisor;
654 $hostpart=$serial{$serial};
655 $taper_finished{$hostpart}=1;
656 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
657 $taper_time{$hostpart}=$1;
658 if(!defined $size{$hostpart}) {
659 $size{$hostpart}=$size;
661 $ntpartition{$nb_tape}++;
662 $ntsize{$nb_tape} += $size{$hostpart};
663 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
664 $ntesize{$nb_tape} += $esize{$hostpart};
667 $ntesize{$nb_tape} += $size{$hostpart};
669 if ($3 eq "PARTIAL") {
670 $partial{$hostpart} = 1;
673 $partial{$hostpart} = 0;
676 elsif(/driver: result time (\S+) from taper: (TRY-AGAIN|TAPE-ERROR) (\d+-\d+) (.+)/) {
680 $hostpart=$serial{$serial};
681 $taper_finished{$hostpart}= $2 eq 'TAPE-ERROR' ? -2 : -1;
682 $busy_time{"taper"}+=($1-$taper_time{$hostpart});
683 $taper_time{$hostpart}=$1;
684 $error{$hostpart}="driver: $error";
686 elsif(/driver: dump failed (\S+) (\S+) (\S+), too many dumper retry/) {
688 $hostpart=$serial{$serial};
689 $dump_started{$hostpart}=-1;
690 $dump_finished{$hostpart}=-2;
691 $error{$hostpart} .= "(too many dumper retry)";
693 elsif(/driver: tape failed (\S+) (\S+) (\S+), too many taper retry/) {
695 $hostpart=$serial{$serial};
696 $taper_started{$hostpart}=-1;
697 $taper_finished{$hostpart}=-2;
698 $error{$hostpart} .= "(too many taper retry)";
700 elsif(/planner: FAILED (\S+) (\S+) (\S+) (-?\d+) (.*)/) {
704 $hostpart=&make_hostpart($host,$partition,$datestamp);
705 $dump_started{$hostpart}=-1;
706 $level{$hostpart}=$4;
707 $error{$hostpart}="planner: $5";
709 elsif(/dump of driver schedule after start degraded mode:/) {
710 $start_degraded_mode=1;
712 elsif(/driver: state time (\S+) free (.*) taper: (\S+) idle-dumpers: (\d+) qlen (.*) driver-idle: (\S+)/) {
717 %free = split (/ +/, $2);
718 %qlen = split (/ +/, $5);
720 if($status_driver ne "") {
721 $dumpers_active[$dumpers_active_prev]
722 +=$current_time-$state_time_prev;
723 $dumpers_held[$dumpers_active_prev]{$status_driver}
724 +=$current_time-$state_time_prev;
726 $state_time_prev=$current_time;
727 $dumpers_active_prev=$dumpers_active;
729 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
730 $dumpers_held[$dumpers_active]{$status_driver}=0;
733 elsif(/taper: wrote label `(\S*)'/) {
735 $ntlabel{$nb_tape} = $1;
736 $ntpartition{$nb_tape} = 0;
737 $ntsize{$nb_tape} = 0;
738 $ntesize{$nb_tape} = 0;
741 #print "Ignoring: $_\n";
747 if(defined $current_time) {
748 for ($d = 0; $d < $#dumpers_active; $d++) {
749 $the_dumper = "dumper$d";
750 if(defined($running_dumper{$the_dumper}) &&
751 $running_dumper{$the_dumper} ne "0") {
752 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
796 foreach $host (sort @hosts) {
797 foreach $partition (sort @$host) {
798 foreach $datestamp (sort @datestamp) {
799 $hostpart=&make_hostpart($host,$partition,$datestamp);
800 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
801 if(length("$host:$partition") > $maxnamelength) {
802 $maxnamelength = length("$host:$partition");
808 foreach $host (sort @hosts) {
809 foreach $partition (sort @$host) {
810 foreach $datestamp (sort @datestamp) {
811 $hostpart=&make_hostpart($host,$partition,$datestamp);
812 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
814 if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
815 defined $holding_file{$hostpart}) {
816 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
819 if($estimate_done != 1 && !defined $flush{$hostpart}) {
820 if(defined $estimate{$hostpart}) {
821 if($estimate{$hostpart} != 1) {
822 if( defined $opt_gestimate) {
823 printf "%8s ", $datestamp if defined $opt_date;
824 printf "%-${maxnamelength}s", "$host:$partition";
825 print " getting estimate\n";
829 if(defined $opt_estimate ||
830 (defined $opt_gestimate && $partialestimate{$hostpart} == 1)) {
831 printf "%8s ", $datestamp if defined $opt_date;
832 printf "%-${maxnamelength}s", "$host:$partition";
833 printf "%2d", $level{$hostpart};
834 printf "%9d$unit", $esize{$hostpart};
835 if($partialestimate{$hostpart} == 1) {
838 print " estimate done\n";
841 $estsize += $esize{$hostpart};
846 if(defined $estimate{$hostpart}) {
847 if($estimate{$hostpart} == 1) {
849 $estsize += $esize{$hostpart};
851 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
852 if( defined $opt_failed) {
853 printf "%8s ", $datestamp if defined $opt_date;
854 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
855 printf " no estimate\n";
862 $flsize += $size{$hostpart};
865 if(defined $taper_started{$hostpart} &&
866 $taper_started{$hostpart}==1) {
867 if(defined $dump_started{$hostpart}) {
869 if(defined($size{$hostpart})) {
870 $dsize += $size{$hostpart};
873 $dsize += $esize{$hostpart};
875 $desize += $esize{$hostpart};
877 if(defined $dump_started{$hostpart} &&
878 $dump_started{$hostpart} == 1 &&
879 $dump_finished{$hostpart} == 0 &&
880 $taper_started{$hostpart} == 1) {
881 if( defined $opt_dumpingtape ) {
882 printf "%8s ", $datestamp if defined $opt_date;
883 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
884 printf "%9d$unit", $esize{$hostpart};
885 print " dumping to tape";
886 if( defined $starttime ) {
887 print " (", &showtime($taper_time{$hostpart}), ")";
892 $dtesize += $esize{$hostpart};
894 elsif($taper_finished{$hostpart} == 0) {
895 if( defined $opt_writingtape ) {
896 printf "%8s ", $datestamp if defined $opt_date;
897 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
898 printf "%9d$unit", $size{$hostpart};
900 print " writing to tape";
903 print " flushing to tape";
905 if( defined $starttime ) {
906 print " (", &showtime($taper_time{$hostpart}), ")";
911 $tasize += $size{$hostpart};
912 if(defined $esize{$hostpart}) {
913 $taesize += $esize{$hostpart};
916 $taesize += $size{$hostpart};
919 elsif($taper_finished{$hostpart} < 0) {
921 if(defined $size{$hostpart}) {
922 $xsize = $size{$hostpart};
924 elsif(defined $esize{$hostpart}) {
925 $xsize = $esize{$hostpart};
931 if(defined $esize{$hostpart}) {
932 $exsize += $esize{$hostpart};
938 if( defined $opt_failed ||
939 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
940 printf "%8s ", $datestamp if defined $opt_date;
941 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
942 printf "%9d$unit", $xsize;
944 print " failed to tape";
947 print " failed to flush";
949 print " (will retry)" unless $taper_finished{$hostpart} < -1;
950 if( defined $starttime ) {
951 print " (", &showtime($taper_time{$hostpart}), ")";
970 elsif($taper_finished{$hostpart} == 1) {
971 if( defined $opt_finished ) {
972 printf "%8s ", $datestamp if defined $opt_date;
973 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
974 printf "%9d$unit", $size{$hostpart};
981 if( defined $starttime ) {
982 print " (", &showtime($taper_time{$hostpart}), ")";
984 print ", PARTIAL" if defined $partial{$hostpart} &&
985 $partial{$hostpart} == 1;
989 $tsize += $size{$hostpart};
990 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
991 $tesize += $esize{$hostpart};
994 $tesize += $size{$hostpart};
998 printf "%8s ", $datestamp if defined $opt_date;
999 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1000 print " unknown state TAPER\n";
1003 elsif(defined $dump_started{$hostpart}) {
1004 if($dump_started{$hostpart} == -1) {
1005 if( defined $opt_failed ) {
1006 printf "%8s ", $datestamp if defined $opt_date;
1007 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1008 printf " " . $error{$hostpart} . "\n";
1011 $fsize+=$esize{$hostpart};
1013 elsif($dump_started{$hostpart} == 0) {
1014 if($estimate{$hostpart} == 1) {
1015 if( defined $opt_waitdumping ) {
1016 printf "%8s ", $datestamp if defined $opt_date;
1017 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1018 printf "%9d$unit", $esize{$hostpart};
1019 print " wait for dumping $error{$hostpart}\n";
1022 $wsize += $esize{$hostpart};
1025 elsif($dump_started{$hostpart} == 1 &&
1026 $dump_finished{$hostpart} == -1) {
1027 if( defined $opt_failed ) {
1028 printf "%8s ", $datestamp if defined $opt_date;
1029 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1030 print " ", $error{$hostpart};
1031 if( defined $starttime ) {
1032 print " (", &showtime($dump_time{$hostpart}), ")";
1037 $fsize+=$esize{$hostpart};
1039 elsif($dump_started{$hostpart} == 1 &&
1040 $dump_finished{$hostpart} != 1) {
1041 if( defined $opt_dumping ) {
1042 printf "%8s ", $datestamp if defined $opt_date;
1043 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1044 printf "%9d$unit", $esize{$hostpart};
1045 printf " dumping %8d$unit", $size{$hostpart};
1046 if($size{$hostpart} != 0) {
1047 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1049 if( defined $starttime ) {
1050 print " (", &showtime($dump_time{$hostpart}), ")";
1052 if(defined $dump_roomq{$hostpart}) {
1053 print " " . $error{$hostpart};
1058 $dusize += $size{$hostpart};
1059 $duesize += $esize{$hostpart};
1061 elsif($dump_finished{$hostpart} == 1 &&
1062 $taper_started{$hostpart} != 1) {
1063 if( defined $opt_waittaper ) {
1064 printf "%8s ", $datestamp if defined $opt_date;
1065 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1066 printf "%9d$unit", $size{$hostpart};
1068 if( defined $starttime ) {
1069 print " (", &showtime($dump_time{$hostpart}), ")";
1071 print ", wait for writing to tape";
1072 print ", PARTIAL" if defined $partial{$hostpart} &&
1073 $partial{$hostpart} == 1;;
1077 $dsize += $size{$hostpart};
1078 $desize += $esize{$hostpart};
1080 $twsize += $size{$hostpart};
1081 $twesize += $esize{$hostpart};
1084 printf "%8s ", $datestamp if defined $opt_date;
1085 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1086 print " unknown state DUMPER\n";
1089 elsif(defined $flush{$hostpart}) {
1090 if( defined $opt_waittaper ) {
1091 printf "%8s ", $datestamp if defined $opt_date;
1092 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1093 printf "%9d$unit", $size{$hostpart};
1094 print " waiting to flush";
1095 print ", PARTIAL" if defined $partial{$hostpart} &&
1096 $partial{$hostpart} == 1;
1100 $wfsize += $size{$hostpart};
1102 elsif(defined $level{$hostpart}) {
1103 printf "%8s ", $datestamp if defined $opt_date;
1104 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1105 print " unknown state\n";
1112 if (defined $opt_summary) {
1114 print "SUMMARY part real estimated\n";
1115 print " size size\n";
1116 printf "partition : %3d\n", $nb_partition;
1117 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1118 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1119 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1120 $fpartition , $fsize,
1121 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1122 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1123 $wpartition , $wsize,
1124 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1125 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1126 $dtpartition, $dtesize,
1127 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1128 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1129 $dupartition, $dusize, $duesize,
1130 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1131 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1132 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1133 $dpartition , $dsize , $desize,
1134 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1135 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1136 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1137 $twpartition, $twsize, $twesize,
1138 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1139 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1140 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1141 $wfpartition, $wfsize, $wfsize, 100, 0;
1142 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1143 $tapartition, $tasize, $taesize,
1144 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1145 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1146 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1147 $tfpartition, $tfsize, $tfesize,
1148 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1149 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1150 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1151 $tpartition , $tsize , $tesize,
1152 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1153 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1154 if($nb_tape > 1 || $tape_size != 0) {
1155 for($i=1; $i <= $nb_tape; $i++) {
1156 if($tape_size != 0) {
1157 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s\n",
1158 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1161 printf " tape %-3d : %3d %9d$unit %9d$unit %s\n",
1162 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1166 if($idle_dumpers ==0) {
1167 printf "all dumpers active\n";
1170 $c1 = ($idle_dumpers == 1) ? "" : "s";
1171 $c2 = ($idle_dumpers < 10) ? " " : "";
1172 $c3 = ($idle_dumpers == 1) ? " " : "";
1173 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1175 if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
1176 printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
1179 printf "taper idle\n";
1181 if (defined ($free{"kps:"})) {
1182 printf "network free kps: %9d\n", $free{"kps:"};
1184 if (defined ($free{"space:"})) {
1185 if ($holding_space) {
1186 $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
1190 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space:"}/$unitdivisor), $hs;
1194 if(defined $opt_stats) {
1195 if(defined($current_time) && $current_time != $start_time) {
1196 $total_time=$current_time-$start_time;
1197 foreach $key (sort byprocess keys %busy_time) {
1198 printf "%8s busy : %8s (%6.2f%%)\n",
1199 $key, &busytime($busy_time{$key}),
1200 ($busy_time{$key} * 1.0 / $total_time) * 100;
1202 for ($d = 0; $d <= $#dumpers_active; $d++) {
1203 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1204 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1205 &busytime($dumpers_active[$d]),
1206 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1209 $s2 = " " x length($l);
1210 $r = $dumpers_held[$d];
1211 foreach $key (sort valuesort keys %$r) {
1213 unless $dumpers_held[$d]{$key} >= 1;
1214 printf "%s%20s: %8s (%6.2f%%)\n",
1217 &busytime($dumpers_held[$d]{$key}),
1218 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1228 sub make_hostpart() {
1229 local($host,$partition,$datestamp) = @_;
1231 if(! defined($hosts{$host})) {
1236 foreach $pp (sort @$host) {
1237 $new_part = 0 if ($pp eq $partition);
1239 push @$host, $partition if $new_part==1;
1241 my($hostpart) = "$host$partition$datestamp";
1242 if(!defined $datestamp{$datestamp}) {
1243 $datestamp{$datestamp} = 1;
1244 push @datestamp, $datestamp;
1250 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1251 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1252 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1256 $r->{$b} <=> $r->{$a};
1260 local($filename) = @_;
1263 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1264 $atime,$mtime,$ctime,$blksize,$blocks);
1265 while ($filename ne "") {
1266 $filename = "$filename.tmp" if (!(-e "$filename"));
1267 $filename = "/dev/null" if (!(-e "$filename"));
1268 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1269 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1270 $size=$size-32768 if $size > 32768;
1272 open(DUMP,$filename);
1275 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1276 last if /^To restore, position tape at start of file and run/;
1291 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1292 'Jul','Aug','Sep','Oct','Nov','Dec');
1294 # Preset an array of values in case some parts are not passed as
1295 # arguments. This lets the date, etc, be omitted and default to
1304 # See if this argument looks like a month name.
1310 $month = $month + 1;
1317 # See if this is a day of the month.
1319 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1324 # See if the next argument looks like a time.
1326 if ($a =~ /^(\d+):(\d+)/) {
1329 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1335 # See if this is a year.
1337 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1343 $time = &timelocal (@tl);
1350 my($oneday)=24*60*60;
1352 @now=localtime($starttime+$delta);
1353 if($delta > $oneday) {
1354 $result=sprintf("%d+",$delta/$oneday);
1358 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1364 my($oneday)=24*60*60;
1366 if($busy > $oneday) {
1367 $days=int($busy/$oneday);
1368 $result=sprintf("%d+",$busy/$oneday);
1369 $busy-=$days*$oneday;
1373 $hours=int($busy/60/60);
1374 $busy-=$hours*60*60;
1375 $minutes=int($busy/60);
1378 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1383 print "amstatus [--config] config [--file amdump_file]\n";
1384 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1385 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1386 print " [--estimate] [--gestimate] [--stats] [--date]\n";