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(defined($dumpers_active)) {
721 if($status_driver ne "") {
722 $dumpers_active[$dumpers_active_prev]
723 +=$current_time-$state_time_prev;
724 $dumpers_held[$dumpers_active_prev]{$status_driver}
725 +=$current_time-$state_time_prev;
727 $state_time_prev=$current_time;
728 $dumpers_active_prev=$dumpers_active;
730 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
731 $dumpers_held[$dumpers_active]{$status_driver}=0;
735 elsif(/taper: .*wrote label `(\S*)'/) {
737 $ntlabel{$nb_tape} = $1;
738 $ntpartition{$nb_tape} = 0;
739 $ntsize{$nb_tape} = 0;
740 $ntesize{$nb_tape} = 0;
743 #print "Ignoring: $_\n";
749 if(defined $current_time) {
750 for ($d = 0; $d < $#dumpers_active; $d++) {
751 $the_dumper = "dumper$d";
752 if(defined($running_dumper{$the_dumper}) &&
753 $running_dumper{$the_dumper} ne "0") {
754 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
798 foreach $host (sort @hosts) {
799 foreach $partition (sort @$host) {
800 foreach $datestamp (sort @datestamp) {
801 $hostpart=&make_hostpart($host,$partition,$datestamp);
802 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
803 if(length("$host:$partition") > $maxnamelength) {
804 $maxnamelength = length("$host:$partition");
810 foreach $host (sort @hosts) {
811 foreach $partition (sort @$host) {
812 foreach $datestamp (sort @datestamp) {
813 $hostpart=&make_hostpart($host,$partition,$datestamp);
814 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
816 if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
817 defined $holding_file{$hostpart}) {
818 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
821 if($estimate_done != 1 && !defined $flush{$hostpart}) {
822 if(defined $estimate{$hostpart}) {
823 if($estimate{$hostpart} != 1) {
824 if( defined $opt_gestimate) {
825 printf "%8s ", $datestamp if defined $opt_date;
826 printf "%-${maxnamelength}s", "$host:$partition";
827 print " getting estimate\n";
831 if(defined $opt_estimate ||
832 (defined $opt_gestimate && $partialestimate{$hostpart} == 1)) {
833 printf "%8s ", $datestamp if defined $opt_date;
834 printf "%-${maxnamelength}s", "$host:$partition";
835 printf "%2d", $level{$hostpart};
836 printf "%9d$unit", $esize{$hostpart};
837 if($partialestimate{$hostpart} == 1) {
840 print " estimate done\n";
843 $estsize += $esize{$hostpart};
848 if(defined $estimate{$hostpart}) {
849 if($estimate{$hostpart} == 1) {
851 $estsize += $esize{$hostpart};
853 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
854 if( defined $opt_failed) {
855 printf "%8s ", $datestamp if defined $opt_date;
856 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
857 printf " no estimate\n";
864 $flsize += $size{$hostpart};
867 if(defined $taper_started{$hostpart} &&
868 $taper_started{$hostpart}==1) {
869 if(defined $dump_started{$hostpart}) {
871 if(defined($size{$hostpart})) {
872 $dsize += $size{$hostpart};
875 $dsize += $esize{$hostpart};
877 $desize += $esize{$hostpart};
879 if(defined $dump_started{$hostpart} &&
880 $dump_started{$hostpart} == 1 &&
881 $dump_finished{$hostpart} == 0 &&
882 $taper_started{$hostpart} == 1) {
883 if( defined $opt_dumpingtape ) {
884 printf "%8s ", $datestamp if defined $opt_date;
885 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
886 printf "%9d$unit", $esize{$hostpart};
887 print " dumping to tape";
888 if( defined $starttime ) {
889 print " (", &showtime($taper_time{$hostpart}), ")";
894 $dtesize += $esize{$hostpart};
896 elsif($taper_finished{$hostpart} == 0) {
897 if( defined $opt_writingtape ) {
898 printf "%8s ", $datestamp if defined $opt_date;
899 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
900 printf "%9d$unit", $size{$hostpart};
902 print " writing to tape";
905 print " flushing to tape";
907 if( defined $starttime ) {
908 print " (", &showtime($taper_time{$hostpart}), ")";
913 $tasize += $size{$hostpart};
914 if(defined $esize{$hostpart}) {
915 $taesize += $esize{$hostpart};
918 $taesize += $size{$hostpart};
921 elsif($taper_finished{$hostpart} < 0) {
923 if(defined $size{$hostpart}) {
924 $xsize = $size{$hostpart};
926 elsif(defined $esize{$hostpart}) {
927 $xsize = $esize{$hostpart};
933 if(defined $esize{$hostpart}) {
934 $exsize += $esize{$hostpart};
940 if( defined $opt_failed ||
941 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
942 printf "%8s ", $datestamp if defined $opt_date;
943 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
944 printf "%9d$unit", $xsize;
946 print " failed to tape";
949 print " failed to flush";
951 print " (will retry)" unless $taper_finished{$hostpart} < -1;
952 if( defined $starttime ) {
953 print " (", &showtime($taper_time{$hostpart}), ")";
972 elsif($taper_finished{$hostpart} == 1) {
973 if( defined $opt_finished ) {
974 printf "%8s ", $datestamp if defined $opt_date;
975 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
976 printf "%9d$unit", $size{$hostpart};
983 if( defined $starttime ) {
984 print " (", &showtime($taper_time{$hostpart}), ")";
986 print ", PARTIAL" if defined $partial{$hostpart} &&
987 $partial{$hostpart} == 1;
991 $tsize += $size{$hostpart};
992 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
993 $tesize += $esize{$hostpart};
996 $tesize += $size{$hostpart};
1000 printf "%8s ", $datestamp if defined $opt_date;
1001 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1002 print " unknown state TAPER\n";
1005 elsif(defined $dump_started{$hostpart}) {
1006 if($dump_started{$hostpart} == -1) {
1007 if( defined $opt_failed ) {
1008 printf "%8s ", $datestamp if defined $opt_date;
1009 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1010 printf " " . $error{$hostpart} . "\n";
1013 $fsize+=$esize{$hostpart};
1015 elsif($dump_started{$hostpart} == 0) {
1016 if($estimate{$hostpart} == 1) {
1017 if( defined $opt_waitdumping ) {
1018 printf "%8s ", $datestamp if defined $opt_date;
1019 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1020 printf "%9d$unit", $esize{$hostpart};
1021 print " wait for dumping $error{$hostpart}\n";
1024 $wsize += $esize{$hostpart};
1027 elsif($dump_started{$hostpart} == 1 &&
1028 $dump_finished{$hostpart} == -1) {
1029 if( defined $opt_failed ) {
1030 printf "%8s ", $datestamp if defined $opt_date;
1031 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1032 print " ", $error{$hostpart};
1033 if( defined $starttime ) {
1034 print " (", &showtime($dump_time{$hostpart}), ")";
1039 $fsize+=$esize{$hostpart};
1041 elsif($dump_started{$hostpart} == 1 &&
1042 $dump_finished{$hostpart} != 1) {
1043 if( defined $opt_dumping ) {
1044 printf "%8s ", $datestamp if defined $opt_date;
1045 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1046 printf "%9d$unit", $esize{$hostpart};
1047 printf " dumping %8d$unit", $size{$hostpart};
1048 if($size{$hostpart} != 0) {
1049 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1051 if( defined $starttime ) {
1052 print " (", &showtime($dump_time{$hostpart}), ")";
1054 if(defined $dump_roomq{$hostpart}) {
1055 print " " . $error{$hostpart};
1060 $dusize += $size{$hostpart};
1061 $duesize += $esize{$hostpart};
1063 elsif($dump_finished{$hostpart} == 1 &&
1064 $taper_started{$hostpart} != 1) {
1065 if( defined $opt_waittaper ) {
1066 printf "%8s ", $datestamp if defined $opt_date;
1067 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1068 printf "%9d$unit", $size{$hostpart};
1070 if( defined $starttime ) {
1071 print " (", &showtime($dump_time{$hostpart}), ")";
1073 print ", wait for writing to tape";
1074 print ", PARTIAL" if defined $partial{$hostpart} &&
1075 $partial{$hostpart} == 1;;
1079 $dsize += $size{$hostpart};
1080 $desize += $esize{$hostpart};
1082 $twsize += $size{$hostpart};
1083 $twesize += $esize{$hostpart};
1086 printf "%8s ", $datestamp if defined $opt_date;
1087 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1088 print " unknown state DUMPER\n";
1091 elsif(defined $flush{$hostpart}) {
1092 if( defined $opt_waittaper ) {
1093 printf "%8s ", $datestamp if defined $opt_date;
1094 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1095 printf "%9d$unit", $size{$hostpart};
1096 print " waiting to flush";
1097 print ", PARTIAL" if defined $partial{$hostpart} &&
1098 $partial{$hostpart} == 1;
1102 $wfsize += $size{$hostpart};
1104 elsif(defined $level{$hostpart}) {
1105 printf "%8s ", $datestamp if defined $opt_date;
1106 printf "%-${maxnamelength}s%2d", "$host:$partition", $level{$hostpart};
1107 print " unknown state\n";
1114 if (defined $opt_summary) {
1116 print "SUMMARY part real estimated\n";
1117 print " size size\n";
1118 printf "partition : %3d\n", $nb_partition;
1119 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1120 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1121 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1122 $fpartition , $fsize,
1123 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1124 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1125 $wpartition , $wsize,
1126 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1127 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1128 $dtpartition, $dtesize,
1129 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1130 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1131 $dupartition, $dusize, $duesize,
1132 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1133 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1134 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1135 $dpartition , $dsize , $desize,
1136 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1137 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1138 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1139 $twpartition, $twsize, $twesize,
1140 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1141 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1142 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1143 $wfpartition, $wfsize, $wfsize, 100, 0;
1144 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1145 $tapartition, $tasize, $taesize,
1146 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1147 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1148 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1149 $tfpartition, $tfsize, $tfesize,
1150 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1151 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1152 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1153 $tpartition , $tsize , $tesize,
1154 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1155 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1156 if($nb_tape > 1 || $tape_size != 0) {
1157 for($i=1; $i <= $nb_tape; $i++) {
1158 if($tape_size != 0) {
1159 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s\n",
1160 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1163 printf " tape %-3d : %3d %9d$unit %9d$unit %s\n",
1164 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1168 if($idle_dumpers ==0) {
1169 printf "all dumpers active\n";
1172 $c1 = ($idle_dumpers == 1) ? "" : "s";
1173 $c2 = ($idle_dumpers < 10) ? " " : "";
1174 $c3 = ($idle_dumpers == 1) ? " " : "";
1175 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1177 if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
1178 printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
1181 printf "taper idle\n";
1183 if (defined ($free{"kps:"})) {
1184 printf "network free kps: %9d\n", $free{"kps:"};
1186 if (defined ($free{"space:"})) {
1187 if ($holding_space) {
1188 $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
1192 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space:"}/$unitdivisor), $hs;
1196 if(defined $opt_stats) {
1197 if(defined($current_time) && $current_time != $start_time) {
1198 $total_time=$current_time-$start_time;
1199 foreach $key (sort byprocess keys %busy_time) {
1200 printf "%8s busy : %8s (%6.2f%%)\n",
1201 $key, &busytime($busy_time{$key}),
1202 ($busy_time{$key} * 1.0 / $total_time) * 100;
1204 for ($d = 0; $d <= $#dumpers_active; $d++) {
1205 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1206 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1207 &busytime($dumpers_active[$d]),
1208 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1211 $s2 = " " x length($l);
1212 $r = $dumpers_held[$d];
1213 foreach $key (sort valuesort keys %$r) {
1215 unless $dumpers_held[$d]{$key} >= 1;
1216 printf "%s%20s: %8s (%6.2f%%)\n",
1219 &busytime($dumpers_held[$d]{$key}),
1220 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1230 sub make_hostpart() {
1231 local($host,$partition,$datestamp) = @_;
1233 if(! defined($hosts{$host})) {
1238 foreach $pp (sort @$host) {
1239 $new_part = 0 if ($pp eq $partition);
1241 push @$host, $partition if $new_part==1;
1243 my($hostpart) = "$host$partition$datestamp";
1244 if(!defined $datestamp{$datestamp}) {
1245 $datestamp{$datestamp} = 1;
1246 push @datestamp, $datestamp;
1252 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1253 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1254 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1258 $r->{$b} <=> $r->{$a};
1262 local($filename) = @_;
1265 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1266 $atime,$mtime,$ctime,$blksize,$blocks);
1267 while ($filename ne "") {
1268 $filename = "$filename.tmp" if (!(-e "$filename"));
1269 $filename = "/dev/null" if (!(-e "$filename"));
1270 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1271 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1272 $size=$size-32768 if $size > 32768;
1274 open(DUMP,$filename);
1277 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1278 last if /^To restore, position tape at start of file and run/;
1293 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1294 'Jul','Aug','Sep','Oct','Nov','Dec');
1296 # Preset an array of values in case some parts are not passed as
1297 # arguments. This lets the date, etc, be omitted and default to
1306 # See if this argument looks like a month name.
1312 $month = $month + 1;
1319 # See if this is a day of the month.
1321 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1326 # See if the next argument looks like a time.
1328 if ($a =~ /^(\d+):(\d+)/) {
1331 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1337 # See if this is a year.
1339 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1345 $time = &timelocal (@tl);
1352 my($oneday)=24*60*60;
1354 @now=localtime($starttime+$delta);
1355 if($delta > $oneday) {
1356 $result=sprintf("%d+",$delta/$oneday);
1360 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1366 my($oneday)=24*60*60;
1368 if($busy > $oneday) {
1369 $days=int($busy/$oneday);
1370 $result=sprintf("%d+",$busy/$oneday);
1371 $busy-=$days*$oneday;
1375 $hours=int($busy/60/60);
1376 $busy-=$hours*60*60;
1377 $minutes=int($busy/60);
1380 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1385 print "amstatus [--config] config [--file amdump_file]\n";
1386 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1387 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1388 print " [--estimate] [--gestimate] [--stats] [--date]\n";