5 eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
6 & eval 'exec @PERL@ -S $0 $argv:q'
9 require "newgetopt.pl";
13 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
14 $ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; # force known path
16 $confdir="@CONFIG_DIR@";
18 $prefix=$prefix; # avoid warnings about possible typo
19 $exec_prefix="@exec_prefix@";
20 $exec_prefix=$exec_prefix; # ditto
29 $USE_VERSION_SUFFIXES='@USE_VERSION_SUFFIXES@';
31 if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) {
35 $result = &NGetOpt ( "summary",
38 "waitdumping|wdumping",
45 "gestimate|gettingestimate",
49 "locale-independent-date-format",
55 if( defined $opt_config ) {
67 #untaint user input $ARGV[0]
69 if ($conf =~ /^([\w.-]+)$/) { # $1 is untainted
72 die "filename '$conf' has invalid characters.\n";
75 if ( ! -e "$confdir/$conf" ) {
76 print "Configuration directory '" . $confdir/$conf . "' doesn't exist\n";
79 if ( ! -d "$confdir/$conf" ) {
80 print "Configuration directory '" . $confdir/$conf . "' is not a directory\n";
87 chdir "$confdir/$conf";
89 $logdir=`$sbindir/amgetconf$suf logdir`;
92 $errfile="$logdir/amdump";
94 $nb_options = defined( $opt_summary ) +
95 defined( $opt_stats ) +
96 defined( $opt_dumping ) +
97 defined( $opt_waitdumping ) +
98 defined( $opt_waittaper ) +
99 defined( $opt_dumpingtape ) +
100 defined( $opt_writingtape ) +
101 defined( $opt_finished ) +
102 defined( $opt_estimate ) +
103 defined( $opt_gestimate ) +
104 defined( $opt_failed );
106 if($nb_options == 0 ) {
110 $opt_waitdumping = 1;
112 $opt_dumpingtape = 1;
113 $opt_writingtape = 1;
120 $unit=`$sbindir/amgetconf$suf displayunit`;
122 $unit =~ tr/A-Z/a-z/;
127 elsif($unit eq 'm') {
130 elsif($unit eq 'g') {
131 $unitdivisor = 1024*1024;
133 elsif($unit eq 't') {
134 $unitdivisor = 1024*1024*1024;
142 if( defined $opt_file) {
143 if( $opt_file =~ m,^/, ) {
144 $errfile = $opt_file;
146 $errfile = "$pwd/$opt_file";
147 $errfile = "$logdir/$opt_file" if ( ! (-f $errfile ));
151 $errfile="$logdir/amflush" if(! (-f $errfile));
153 if (-f "$logdir/amflush.1" && -f "$logdir/amdump.1" &&
154 -M "$logdir/amflush.1" < -M "$logdir/amdump.1") {
155 $errfile="$logdir/amflush.1";
157 $errfile="$logdir/amdump.1";
162 open(AMDUMP,"<$errfile") || die("$errfile: $!");
163 print "Using $errfile\n";
165 $start_degraded_mode = 0;
167 $label = ""; # -w fodder
168 $origsize = 0; # -w fodder
175 @dumpers_active = ();
177 $ntpartition{$nb_tape} = 0;
178 $ntsize{$nb_tape} = 0;
179 $ntesize{$nb_tape} = 0;
181 $driver_finished = 0;
182 $generating_schedule = 0;
184 while($lineX = <AMDUMP>) {
186 $lineX =~ s/[:\s]+$//g; #remove separator at end of line
187 next if $lineX eq "";
188 @line = "ewords('[:\s]+', 0, $lineX);
189 next if !defined $line[0];
191 if($line[0] eq "amdump" || $line[0] eq "amflush") {
192 if ($line[1] eq "start" && $line[2] eq "at") {
194 $datestr =~ s/.*start at //g;
195 if (!defined $opt_locale_independent_date_format) {
196 print "From " . $datestr . "\n";
198 } elsif($line[1] eq "datestamp") {
199 $gdatestamp = $line[2];
200 if(!defined $datestamp{$gdatestamp}) {
201 $datestamp{$gdatestamp} = 1;
202 push @datestamp, $gdatestamp;
204 } elsif($line[1] eq "starttime") {
205 $starttime=&set_starttime($line[2]);
206 } elsif($line[1] eq "starttime-locale-independent") {
207 if (defined $opt_locale_independent_date_format) {
208 printf "From " . $line[2] . " " . $line[3] . ":" . $line[4] . ":" . $line[5] . " " . $line[6] . "\n";
211 if($line[0] eq "amflush") {
214 } elsif($line[0] eq "planner") {
215 if($line[1] eq "timestamp") {
216 $gdatestamp = $line[2];
217 if(!defined $datestamp{$gdatestamp}) {
218 $datestamp{$gdatestamp} = 1;
219 push @datestamp, $gdatestamp;
222 elsif($line[1] eq "FAILED") {
223 #2:host 3:disk 4:datestamp 5:level 6:errmsg
227 $hostpart=&make_hostpart($host,$partition,$datestamp);
228 $dump_started{$hostpart}=-1;
229 $level{$hostpart}=$line[5];
230 $error{$hostpart}="planner: " . $line[6];
231 } elsif($line[1] eq "time") {
232 if($line[3] eq "got") {
233 if($line[4] eq "result") {
235 $partition = $line[9];
236 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
237 $estimate{$hostpart}=1;
238 $level{$hostpart}=$line[10];
239 $line[12] =~ /(\d+)K/;
240 $esize{$hostpart}=$1 / $unitdivisor;
241 $partialestimate{$hostpart}=0;
242 $getest{$hostpart} = "";
243 } elsif($line[4] eq "partial") {
245 $partition = $line[10];
246 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
248 $line[13] =~ /(-?\d+)K/;
251 $line[16] =~ /(-?\d+)K/;
254 $line[19] =~ /(-?\d+)K/;
256 if($size1 > 0 || $size2 > 0 || $size3 > 0) {
257 $estimate{$hostpart}=1;
258 $level{$hostpart}=$line[11];
259 $esize{$hostpart}=$size1 / $unitdivisor;
260 $partialestimate{$hostpart}=1;
261 if($size1 > 0) { $getest{$hostpart} =~ s/:$level1://; }
262 if($size2 > 0) { $getest{$hostpart} =~ s/:$level2://; }
263 if($size3 > 0) { $getest{$hostpart} =~ s/:$level3://; }
264 if($getest{$hostpart} eq "") {$partialestimate{$hostpart}=0;}
267 } elsif($line[3] eq "getting" &&
268 $line[4] eq "estimates" &&
269 $line[5] eq "took") {
273 } elsif($line[0] eq "setup_estimate") {
275 $partition = $line[2];
276 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
277 $estimate{$hostpart}=0;
279 $degr_level{$hostpart}=-1;
281 $dump_started{$hostpart}=0;
282 $dump_finished{$hostpart}=0;
283 $taper_started{$hostpart}=0;
284 $taper_finished{$hostpart}=0;
285 $partialestimate{$hostpart}=0;
286 $error{$hostpart}="";
287 if($line[7] eq "last_level") {
288 $getest{$hostpart}="";
292 if($level1 != -1) { $getest{$hostpart} .= ":$level1:" };
293 if($level2 != -1) { $getest{$hostpart} .= ":$level2:" };
294 if($level3 != -1) { $getest{$hostpart} .= ":$level3:" };
296 } elsif($line[0] eq "GENERATING" &&
297 $line[1] eq "SCHEDULE") {
298 $generating_schedule=1;
299 } elsif($line[0] eq "--------") {
300 if ($generating_schedule == 1) {
301 $generating_schedule = 2;
302 } elsif ($generating_schedule == 2) {
303 $generating_schedule = 3;
305 } elsif($line[0] eq "DUMP") {
306 if($generating_schedule == 2 ) {
308 $partition = $line[3];
309 $datestamp = $line[4];
310 $hostpart=&make_hostpart($host,$partition,$datestamp);
311 $level{$hostpart}=$line[6];
312 $esize=$line[14]; #compressed size
313 $esize=32 if $esize<32;
314 $esize{$hostpart}=$esize / $unitdivisor;
315 if(!defined($line[22])) {
316 $degr_level{$hostpart}=-1;
318 $degr_level{$hostpart}=$line[18];
319 $esize=$line[25]; #compressed size
320 $esize=32 if $esize<32;
321 $degr_size{$hostpart}=$esize / $unitdivisor;
324 } elsif($line[0] eq "FLUSH") {
326 $partition = $line[2];
327 $datestamp = $line[3];
329 $holding_file = $line[5];
330 $hostpart=&make_hostpart($host,$partition,$datestamp);
332 $holding_file{$hostpart}=$holding_file;
333 $level{$hostpart}=$level;
334 } elsif($line[0] eq "driver") {
335 if($line[1] eq "start" && $line[2] eq "time") {
336 $start_time=$line[3];
337 $current_time=$line[3];
338 $dumpers_active[0]=0;
342 elsif($line[1] eq "tape" && $line[2] eq "size") {
343 $lineX =~ /^driver: start time (\S+)/;
344 $tape_size = $line[3] / $unitdivisor;
346 elsif($line[1] eq "adding" &&
347 $line[2] eq "holding" &&
348 $line[3] eq "disk") {
349 $holding_space += $line[8];
351 elsif($line[1] eq "send-cmd" && $line[2] eq "time") {
352 #print "send-cmd: " , $line[5] . " " . $line[6] . " " . $line[7] . "\n" if defined $line[5] && defined $line[6] && defined $line[7];
353 $current_time = $line[3];
354 if($line[5] =~ /dumper\d*/) {
356 if($line[6] eq "PORT-DUMP") {
357 #7:handle 8:port 9:host 10:amfeatures 11:disk 12:device 13:level ...
359 $partition = $line[11];
360 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
362 $dump_started{$hostpart}=1;
363 $dump_time{$hostpart}=$current_time;
364 $dump_finished{$hostpart}=0;
365 if( $level{$hostpart} != $line[13] &&
366 $degr_level{$hostpart} == $line[13]) {
367 $level{$hostpart}=$degr_level{$hostpart};
368 $esize{$hostpart}=$degr_size{$hostpart};
370 if(! defined($busy_time{$dumper})) {
371 $busy_time{$dumper}=0;
373 $running_dumper{$dumper} = $hostpart;
374 $error{$hostpart}="";
375 $size{$hostpart} = 0;
377 if(! defined($dumpers_active[$dumpers_active])) {
378 $dumpers_active[$dumpers_active]=0;
380 if(! defined($dumpers_held[$dumpers_active])) {
381 $dumpers_held[$dumpers_active]={};
385 elsif($line[5] =~ /chunker\d*/) {
386 if($line[6] eq "PORT-WRITE") {
388 $partition=$line[11];
389 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
391 $serial{$serial}=$hostpart;
392 $holding_file{$hostpart}=$line[8];
393 #$chunk_started{$hostpart}=1;
394 $chunk_time{$hostpart}=$current_time;
395 #$chunk_finished{$hostpart}=0;
397 elsif($line[6] eq "CONTINUE") {
398 #7:handle 8:filename 9:chunksize 10:use
400 $hostpart=$serial{$serial};
401 if($hostpart ne "") {
402 $dump_roomq{$hostpart}=undef;
403 $error{$hostpart}="";
407 elsif($line[5] =~ /taper/) {
408 if($line[6] eq "START-TAPER") {
410 $gdatestamp=$line[7];
411 if(!defined $datestamp{$gdatestamp}) {
412 $datestamp{$gdatestamp} = 1;
413 push @datestamp, $gdatestamp;
416 elsif($line[6] eq "FILE-WRITE") {
417 #7:handle 8:filename 9:host 10:disk 11:level 12:datestamp 13:splitsize
420 $partition=$line[10];
422 $ldatestamp=$line[12];
423 if(!defined $datestamp{$ldatestamp}) {
424 $datestamp{$ldatestamp} = 1;
425 push @datestamp, $ldatestamp;
427 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
428 $serial{$serial}=$hostpart;
429 if(!defined $level{$hostpart}) {
430 $level{$hostpart} = $level;
432 $taper_started{$hostpart}=1;
433 $taper_finished{$hostpart}=0;
434 $taper_time{$hostpart}=$current_time;
437 elsif($line[6] eq "PORT-WRITE") {
438 #7:handle 8:host 9:disk 10:level 11:datestamp 12:splitsize 13:diskbuffer 14:fallback_splitsize
443 $ldatestamp=$line[11];
444 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
445 $serial{$serial}=$hostpart;
446 $taper_started{$hostpart}=1;
447 $taper_finished{$hostpart}=0;
448 $taper_time{$hostpart}=$current_time;
453 elsif($line[1] eq "result" && $line[2] eq "time") {
454 #print "result: " , $line[5] . " " . $line[6] . " " . $line[7] . "\n" if defined $line[5] && defined $line[6] && defined $line[7];
455 $current_time = $line[3];
456 if($line[5] =~ /dumper\d+/) {
457 if($line[6] eq "FAILED" || $line[6] eq "TRY-AGAIN") {
461 $hostpart=$serial{$serial};
462 $dump_finished{$hostpart}=-1;
463 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
464 $running_dumper{$line[5]} = "0";
465 $dump_time{$hostpart}=$current_time;
466 $error{$hostpart}="dumper: $error";
470 elsif($line[6] eq "DONE") {
471 #7:handle 8:origsize 9:size ...
473 $origsize=$line[8] / $unitdivisor;
474 $outputsize=$line[9] / $unitdivisor;
475 $hostpart=$serial{$serial};
476 $size{$hostpart}=$outputsize;
477 $dump_finished{$hostpart}=1;
478 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
479 $running_dumper{$line[5]} = "0";
480 $dump_time{$hostpart}=$current_time;
481 $error{$hostpart}="";
484 elsif($line[6] eq "ABORT-FINISHED") {
487 $hostpart=$serial{$serial};
488 $dump_started{$hostpart}=0;
489 $dump_finished{$hostpart}=0;
490 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
491 $running_dumper{$line[5]} = "0";
492 $dump_time{$hostpart}=$current_time;
493 $error{$hostpart}="dumper: (aborted)";
497 elsif($line[5] =~ /chunker\d+/) {
498 if($line[6] eq "DONE" || $line[6] eq "PARTIAL") {
501 $outputsize=$line[8] / $unitdivisor;
502 $hostpart=$serial{$serial};
503 $size{$hostpart}=$outputsize;
504 $dump_finished{$hostpart}=1;
505 $busy_time{$line[5]}+=($current_time-$chunk_time{$hostpart});
506 $running_dumper{$line[5]} = "0";
507 $chunk_time{$hostpart}=$current_time;
508 $error{$hostpart}="";
509 if ($line[6] eq "PARTIAL") {
510 $partial{$hostpart} = 1;
513 $partial{$hostpart} = 0;
516 elsif($line[6] eq "FAILED") {
518 $hostpart=$serial{$serial};
519 $dump_finished{$hostpart}=-1;
520 $busy_time{$line[5]}+=($current_time-$chunk_time{$hostpart});
521 $running_dumper{$line[5]} = "0";
522 $chunk_time{$hostpart}=$current_time;
523 $error{$hostpart}="chunker: " .$line[8] if $error{$hostpart} eq "";
525 elsif($line[6] eq "RQ-MORE-DISK") {
528 $hostpart=$serial{$serial};
529 $dump_roomq{$hostpart}=1;
530 $error{$hostpart}="(waiting for holding disk space)";
533 elsif($line[5] eq "taper") {
534 if($line[6] eq "DONE" || $line[6] eq "PARTIAL") {
535 #7:handle 8:label 9:filenum 10:errstr
538 $hostpart=$serial{$serial};
539 $line[10] =~ /sec (\S+) kb (\d+) kps/;
540 $size=$2 / $unitdivisor;
541 $taper_finished{$hostpart}=1;
542 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
543 $taper_time{$hostpart}=$current_time;
544 if(!defined $size{$hostpart}) {
545 $size{$hostpart}=$size;
547 $ntpartition{$nb_tape}++;
548 $ntsize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
549 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
550 $ntesize{$nb_tape} += $esize{$hostpart} - $ntchunk_size;
553 $ntesize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
555 if ($line[6] eq "PARTIAL") {
556 $partial{$hostpart} = 1;
559 $partial{$hostpart} = 0;
561 if ($ntchunk_size > 0) {
562 $ntchunk{$nb_tape}++;
565 elsif($line[6] eq "PARTDONE") {
566 #7:handle 8:label 9:filenum 10:ksize 11:errstr
568 $hostpart=$serial{$serial};
569 #$line[11] =~ /.*kb (\d*) kps/;
570 #$size=$1 / $unitdivisor;
571 $size=$line[10] / $unitdivisor;
572 $tapedsize{$hostpart} += $size;
573 $ntchunk{$nb_tape}++;
574 $ntsize{$nb_tape} += $size;
575 $ntesize{$nb_tape} += $size;
576 $ntchunk_size += $size;
578 elsif($line[6] eq "REQUEST-NEW-TAPE") {
581 $hostpart=$serial{$serial};
582 if (defined $hostpart) {
583 $error{$hostpart} = "waiting for a new tape";
586 elsif($line[6] eq "NEW-TAPE") {
589 $hostpart=$serial{$serial};
590 if (defined $hostpart) {
591 $error{$hostpart} = "";
594 elsif($line[6] eq "TRY-AGAIN" || $line[6] eq "TAPE-ERROR") {
598 $hostpart=$serial{$serial};
599 if(defined $hostpart) {
600 $taper_finished{$hostpart}= $line[6] eq 'TAPE-ERROR' ? -2 : -1;
601 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
602 $taper_time{$hostpart}=$current_time;
603 $error{$hostpart}="taper: $error";
606 elsif($line[6] eq "FAILED") {
607 #7:handle 8:INPUT- 9:TAPE- 10:input_message 11:tape_message
609 $hostpart=$serial{$serial};
610 if(defined $hostpart) {
611 if($line[9] eq "TAPE-ERROR") {
613 $taper_finished{$hostpart} = -2;
617 $taper_finished{$hostpart} = -1;
619 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
620 $taper_time{$hostpart}=$current_time;
621 $error{$hostpart}="$error";
626 elsif($line[1] eq "finished-cmd" && $line[2] eq "time") {
627 $current_time=$line[3];
628 if($line[4] =~ /dumper\d+/) {
631 elsif($line[1] eq "dump" && $line[2] eq "failed") {
632 #3:handle 4: 5: 6:"too many dumper retry"
634 $hostpart=$serial{$serial};
635 $dump_started{$hostpart}=-1;
636 $dump_finished{$hostpart}=-2;
637 $error{$hostpart} .= "(" . $line[6] . ")";
639 elsif($line[1] eq "tape" && $line[2] eq "failed") {
640 #3:handle 4: 5: 6:"too many dumper retry"
642 $hostpart=$serial{$serial};
643 $taper_started{$hostpart}=-1;
644 $taper_finished{$hostpart}=-2;
645 $error{$hostpart} .= "(" . $line[6] . ")";
647 elsif($line[1] eq "state" && $line[2] eq "time") {
648 #3:time 4:"free" 5:"kps" 6:free 7:"space" 8:space 9:"taper" 10:taper 11:"idle-dumpers" 12:idle-dumpers 13:"qlen" 14:"tapeq" 15:tapeq 16:"runq" 17:runq 18:"roomq" 19:roomq 20:"wakeup" 21:wakeup 22:"driver-idle" 23:driver-idle
649 $current_time=$line[3];
650 $status_taper=$line[10];
651 $idle_dumpers=$line[12];
653 $free{"kps"} = $line[6];
654 $free{"space"} = $line[8];
655 $qlen{"tapeq"} = $line[15];
656 $qlen{"runq"} = $line[17];
657 $qlen{"roomq"} = $line[19];
659 if(defined($dumpers_active)) {
660 if($status_driver ne "") {
661 $dumpers_active[$dumpers_active_prev]
662 +=$current_time-$state_time_prev;
663 $dumpers_held[$dumpers_active_prev]{$status_driver}
664 +=$current_time-$state_time_prev;
666 $state_time_prev=$current_time;
667 $dumpers_active_prev=$dumpers_active;
668 $status_driver=$line[16];
669 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
670 $dumpers_held[$dumpers_active]{$status_driver}=0;
674 elsif($line[1] eq "FINISHED") {
675 $driver_finished = 1;
678 elsif($line[0] eq "dump") {
679 if($line[1] eq "of" &&
680 $line[2] eq "driver" &&
681 $line[3] eq "schedule" &&
682 $line[4] eq "after" &&
683 $line[5] eq "start" &&
684 $line[6] eq "degraded" &&
685 $line[7] eq "mode") {
686 $start_degraded_mode=1;
689 elsif($line[0] eq "taper") {
690 if($line[1] eq "slot") {
691 #2:slot 3:"wrote" 4:"label" 5:corrupted...
693 $lineX =~ /wrote label `(\S*)'/;
695 $ntlabel{$nb_tape} = $label;
696 $ntpartition{$nb_tape} = 0;
697 $ntsize{$nb_tape} = 0;
698 $ntesize{$nb_tape} = 0;
700 elsif($line[1] eq "wrote") {
701 #1:"wrote" 2:"label" 3:corrupted
703 $lineX =~ /wrote label `(\S*)'/;
705 $ntlabel{$nb_tape} = $label;
706 $ntpartition{$nb_tape} = 0;
707 $ntsize{$nb_tape} = 0;
708 $ntesize{$nb_tape} = 0;
711 elsif($line[0] eq "splitting" &&
712 $line[1] eq "chunk" &&
713 $line[2] eq "that" &&
714 $line[3] eq "started" &&
716 $line[6] eq "after") {
717 $line[7] =~ /(\d*)kb/;
719 $ntchunk{$nb_tape}++;
720 $ntsize{$nb_tape} += $size / $unitdivisor;
721 $ntesize{$nb_tape} += $size / $unitdivisor;
722 $ntchunk_size += $size / $unitdivisor;
725 #print "Ignoring: $lineX\n";
731 if(defined $current_time) {
732 for ($d = 0; $d < $#dumpers_active; $d++) {
733 $the_dumper = "dumper$d";
734 if(defined($running_dumper{$the_dumper}) &&
735 $running_dumper{$the_dumper} ne "0") {
736 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
780 foreach $host (sort @hosts) {
781 foreach $partition (sort @$host) {
782 foreach $datestamp (sort @datestamp) {
783 $hostpart=&make_hostpart($host,$partition,$datestamp);
784 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
785 if(length("$host:$partition") > $maxnamelength) {
786 $maxnamelength = length("$host:$partition");
792 foreach $host (sort @hosts) {
793 foreach $partition (sort @$host) {
794 foreach $datestamp (sort @datestamp) {
795 $hostpart=&make_hostpart($host,$partition,$datestamp);
796 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
798 if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
799 defined $holding_file{$hostpart}) {
800 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
803 if($estimate_done != 1 && !defined $flush{$hostpart}) {
804 if(defined $estimate{$hostpart}) {
805 if($estimate{$hostpart} != 1) {
806 if( defined $opt_gestimate) {
807 printf "%8s ", $datestamp if defined $opt_date;
808 printf "%-${maxnamelength}s", "$host:$partition";
809 print " getting estimate\n";
813 if(defined $opt_estimate ||
814 (defined $opt_gestimate && $partialestimate{$hostpart} == 1)) {
815 printf "%8s ", $datestamp if defined $opt_date;
816 printf "%-${maxnamelength}s", "$host:$partition";
817 printf "%2d ", $level{$hostpart};
818 printf "%9d$unit", $esize{$hostpart};
819 if($partialestimate{$hostpart} == 1) {
822 print " estimate done\n";
825 $estsize += $esize{$hostpart};
830 if(defined $estimate{$hostpart}) {
831 if($estimate{$hostpart} == 1) {
833 $estsize += $esize{$hostpart};
835 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
836 if( defined $opt_failed) {
837 printf "%8s ", $datestamp if defined $opt_date;
838 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
839 printf " no estimate\n";
841 $exit_status |= $STATUS_FAILED;
843 $fsize+=$esize{$hostpart};
848 $flsize += $size{$hostpart};
851 if(defined $taper_started{$hostpart} &&
852 $taper_started{$hostpart}==1) {
853 if(defined $dump_started{$hostpart}) {
855 if(defined($size{$hostpart})) {
856 $dsize += $size{$hostpart};
859 $dsize += $esize{$hostpart};
861 $desize += $esize{$hostpart};
863 if(defined $dump_started{$hostpart} &&
864 $dump_started{$hostpart} == 1 &&
865 $dump_finished{$hostpart} == -1) {
866 if(defined $opt_failed) {
867 printf "%8s ", $datestamp if defined $opt_date;
868 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
869 printf "%9d$unit", $esize{$hostpart};
870 print " dump to tape failed: " . $error{$hostpart};
873 $exit_status |= $STATUS_FAILED;
875 $fsize+=$esize{$hostpart};
876 } elsif(defined $dump_started{$hostpart} &&
877 $dump_started{$hostpart} == 1 &&
878 $dump_finished{$hostpart} == 0 &&
879 $taper_started{$hostpart} == 1) {
880 if( defined $opt_dumpingtape ) {
881 printf "%8s ", $datestamp if defined $opt_date;
882 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
883 printf "%9d$unit", $esize{$hostpart};
884 print " dumping to tape";
885 if( defined $starttime ) {
886 print " (", &showtime($taper_time{$hostpart}), ")";
891 $dtesize += $esize{$hostpart};
893 elsif($taper_finished{$hostpart} == 0) {
894 if( defined $opt_writingtape ) {
895 printf "%8s ", $datestamp if defined $opt_date;
896 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
897 printf "%9d$unit", $size{$hostpart};
899 print " writing to tape";
902 print " flushing to tape";
904 if(defined($tapedsize{$hostpart})) {
905 printf " (%d$unit done)", $tapedsize{$hostpart};
907 if( defined $starttime ) {
908 print " (", &showtime($taper_time{$hostpart}), ")";
910 print ", ", $error{$hostpart} if defined($error{$hostpart} &&
911 $error{$hostpart} ne "");
915 $tasize += $size{$hostpart};
916 if(defined $esize{$hostpart}) {
917 $taesize += $esize{$hostpart};
920 $taesize += $size{$hostpart};
923 elsif($taper_finished{$hostpart} < 0) {
925 if(defined $size{$hostpart}) {
926 $xsize = $size{$hostpart};
928 elsif(defined $esize{$hostpart}) {
929 $xsize = $esize{$hostpart};
935 if(defined $esize{$hostpart}) {
936 $exsize += $esize{$hostpart};
942 if( defined $opt_failed ||
943 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
944 printf "%8s ", $datestamp if defined $opt_date;
945 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
946 printf "%9d$unit", $xsize;
948 print " failed to tape";
951 print " failed to flush";
953 print ": ",$error{$hostpart} if defined $error{$hostpart};
955 print " (will retry)" unless $taper_finished{$hostpart} < -1;
956 if( defined $starttime ) {
957 print " (", &showtime($taper_time{$hostpart}), ")";
961 $exit_status |= $STATUS_TAPE;
977 elsif($taper_finished{$hostpart} == 1) {
978 if( defined $opt_finished ) {
979 printf "%8s ", $datestamp if defined $opt_date;
980 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
981 printf "%9d$unit", $size{$hostpart};
988 if( defined $starttime ) {
989 print " (", &showtime($taper_time{$hostpart}), ")";
991 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
993 $exit_status |= $STATUS_FAILED;
998 $tsize += $size{$hostpart};
999 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1000 $tesize += $esize{$hostpart};
1003 $tesize += $size{$hostpart};
1007 printf "%8s ", $datestamp if defined $opt_date;
1008 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1009 print " unknown state TAPER\n";
1012 elsif(defined $dump_started{$hostpart}) {
1013 if($dump_started{$hostpart} == -1) {
1014 if( defined $opt_failed ) {
1015 printf "%8s ", $datestamp if defined $opt_date;
1016 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1017 printf " " . $error{$hostpart} . "\n";
1019 $exit_status |= $STATUS_FAILED;
1022 $fsize+=$esize{$hostpart};
1024 elsif($dump_started{$hostpart} == 0) {
1025 if($estimate{$hostpart} == 1) {
1026 if( defined $opt_waitdumping ) {
1027 printf "%8s ", $datestamp if defined $opt_date;
1028 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1029 printf "%9d$unit", $esize{$hostpart};
1030 print " wait for dumping $error{$hostpart}\n";
1032 if($driver_finished == 1) {
1033 $exit_status |= $STATUS_MISSING;
1036 $wsize += $esize{$hostpart};
1039 elsif($dump_started{$hostpart} == 1 &&
1040 $dump_finished{$hostpart} == -1) {
1041 if( defined $opt_failed ) {
1042 printf "%8s ", $datestamp if defined $opt_date;
1043 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1044 print " ", $error{$hostpart};
1045 if( defined $starttime ) {
1046 print " (", &showtime($dump_time{$hostpart}), ")";
1050 $exit_status |= $STATUS_FAILED;
1052 $fsize+=$esize{$hostpart};
1054 elsif($dump_started{$hostpart} == 1 &&
1055 $dump_finished{$hostpart} != 1) {
1056 if( defined $opt_dumping ) {
1057 printf "%8s ", $datestamp if defined $opt_date;
1058 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1059 printf "%9d$unit", $esize{$hostpart};
1060 printf " dumping %8d$unit", $size{$hostpart};
1061 if($size{$hostpart} != 0) {
1062 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1064 if( defined $starttime ) {
1065 print " (", &showtime($dump_time{$hostpart}), ")";
1067 if(defined $dump_roomq{$hostpart}) {
1068 print " " . $error{$hostpart};
1073 $dusize += $size{$hostpart};
1074 $duesize += $esize{$hostpart};
1076 elsif($dump_finished{$hostpart} == 1 &&
1077 $taper_started{$hostpart} != 1) {
1078 if( defined $opt_waittaper ) {
1079 printf "%8s ", $datestamp if defined $opt_date;
1080 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1081 printf "%9d$unit", $size{$hostpart};
1083 if( defined $starttime ) {
1084 print " (", &showtime($dump_time{$hostpart}), ")";
1086 print ", wait for writing to tape";
1087 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1089 $exit_status |= $STATUS_FAILED;
1094 $dsize += $size{$hostpart};
1095 $desize += $esize{$hostpart};
1097 $twsize += $size{$hostpart};
1098 $twesize += $esize{$hostpart};
1101 printf "%8s ", $datestamp if defined $opt_date;
1102 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1103 print " unknown state DUMPER\n";
1106 elsif(defined $flush{$hostpart}) {
1107 if( defined $opt_waittaper ) {
1108 printf "%8s ", $datestamp if defined $opt_date;
1109 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1110 printf "%9d$unit", $size{$hostpart};
1111 print " waiting to flush";
1112 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1114 $exit_status |= $STATUS_FAILED;
1119 $wfsize += $size{$hostpart};
1121 elsif(defined $level{$hostpart}) {
1122 printf "%8s ", $datestamp if defined $opt_date;
1123 printf "%-${maxnamelength}s%2d ", "$host:$partition", $level{$hostpart};
1124 print " unknown state\n";
1131 if (defined $opt_summary) {
1133 print "SUMMARY part real estimated\n";
1134 print " size size\n";
1135 printf "partition : %3d\n", $nb_partition;
1136 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1137 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1138 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1139 $fpartition , $fsize,
1140 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1141 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1142 $wpartition , $wsize,
1143 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1144 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1145 $dtpartition, $dtesize,
1146 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1147 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1148 $dupartition, $dusize, $duesize,
1149 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1150 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1151 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1152 $dpartition , $dsize , $desize,
1153 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1154 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1155 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1156 $twpartition, $twsize, $twesize,
1157 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1158 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1159 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1160 $wfpartition, $wfsize, $wfsize, 100, 0;
1161 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1162 $tapartition, $tasize, $taesize,
1163 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1164 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1165 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1166 $tfpartition, $tfsize, $tfesize,
1167 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1168 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1169 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1170 $tpartition , $tsize , $tesize,
1171 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1172 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1173 if($nb_tape > 1 || $tape_size != 0) {
1174 for($i=1; $i <= $nb_tape; $i++) {
1175 if($tape_size != 0) {
1176 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s",
1177 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1180 printf " tape %-3d : %3d %9d$unit %9d$unit %s",
1181 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1183 if(defined($ntchunk{$i}) && $ntchunk{$i} > 0) {
1184 printf " (%d chunks)", $ntchunk{$i};
1189 if($idle_dumpers == 0) {
1190 printf "all dumpers active\n";
1193 $c1 = ($idle_dumpers == 1) ? "" : "s";
1194 $c2 = ($idle_dumpers < 10) ? " " : "";
1195 $c3 = ($idle_dumpers == 1) ? " " : "";
1196 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1198 if($status_taper eq "writing" && defined($qlen{"tapeq:"})) {
1199 printf "taper writing, tapeq: %d\n", $qlen{"tapeq:"};
1202 printf "taper idle\n";
1204 if (defined ($free{"kps:"})) {
1205 printf "network free kps: %9d\n", $free{"kps:"};
1207 if (defined ($free{"space:"})) {
1208 if ($holding_space) {
1209 $hs = ($free{"space:"} * 1.0 / $holding_space) * 100;
1213 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space:"}/$unitdivisor), $hs;
1217 if(defined $opt_stats) {
1218 if(defined($current_time) && $current_time != $start_time) {
1219 $total_time=$current_time-$start_time;
1220 foreach $key (sort byprocess keys %busy_time) {
1221 printf "%8s busy : %8s (%6.2f%%)\n",
1222 $key, &busytime($busy_time{$key}),
1223 ($busy_time{$key} * 1.0 / $total_time) * 100;
1225 for ($d = 0; $d <= $#dumpers_active; $d++) {
1226 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1227 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1228 &busytime($dumpers_active[$d]),
1229 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1232 $s2 = " " x length($l);
1233 $r = $dumpers_held[$d];
1234 foreach $key (sort valuesort keys %$r) {
1236 unless $dumpers_held[$d]{$key} >= 1;
1237 printf "%s%20s: %8s (%6.2f%%)\n",
1240 &busytime($dumpers_held[$d]{$key}),
1241 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1253 sub make_hostpart() {
1254 local($host,$partition,$datestamp) = @_;
1256 if(! defined($hosts{$host})) {
1261 foreach $pp (sort @$host) {
1262 $new_part = 0 if ($pp eq $partition);
1264 push @$host, $partition if $new_part==1;
1266 my($hostpart) = "$host$partition$datestamp";
1267 if(!defined $datestamp{$datestamp}) {
1268 $datestamp{$datestamp} = 1;
1269 push @datestamp, $datestamp;
1276 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1277 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1278 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1282 $r->{$b} <=> $r->{$a};
1286 local($filename) = @_;
1289 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1290 $atime,$mtime,$ctime,$blksize,$blocks);
1291 while ($filename ne "") {
1292 $filename = "$filename.tmp" if (!(-e "$filename"));
1293 $filename = "/dev/null" if (!(-e "$filename"));
1294 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1295 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1296 $size=$size-32768 if $size > 32768;
1298 open(DUMP,$filename);
1301 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1302 last if /^To restore, position tape at start of file and run/;
1317 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1318 'Jul','Aug','Sep','Oct','Nov','Dec');
1320 # Preset an array of values in case some parts are not passed as
1321 # arguments. This lets the date, etc, be omitted and default to
1330 # See if this argument looks like a month name.
1336 $month = $month + 1;
1343 # See if this is a day of the month.
1345 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1350 # See if the next argument looks like a time.
1352 if ($a =~ /^(\d+):(\d+)/) {
1355 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1361 # See if this is a year.
1363 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1369 $time = &timelocal (@tl);
1374 sub set_starttime() {
1379 # Preset an array of values in case some parts are not passed as
1380 # arguments. This lets the date, etc, be omitted and default to
1386 $tl[5] = substr($date, 0, 4) if(length($date) >= 4);
1387 $tl[4] = substr($date, 4, 2)-1 if(length($date) >= 6);
1388 $tl[3] = substr($date, 6, 2) if(length($date) >= 8);
1389 $tl[2] = substr($date, 8, 2) if(length($date) >= 10);
1390 $tl[1] = substr($date, 10, 2) if(length($date) >= 12);
1391 $tl[0] = substr($date, 12, 2) if(length($date) >= 14);
1393 $time = &timelocal (@tl);
1401 my($oneday)=24*60*60;
1403 @now=localtime($starttime+$delta);
1404 if($delta > $oneday) {
1405 $result=sprintf("%d+",$delta/$oneday);
1409 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1415 my($oneday)=24*60*60;
1417 if($busy > $oneday) {
1418 $days=int($busy/$oneday);
1419 $result=sprintf("%d+",$busy/$oneday);
1420 $busy-=$days*$oneday;
1424 $hours=int($busy/60/60);
1425 $busy-=$hours*60*60;
1426 $minutes=int($busy/60);
1429 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1434 print "amstatus [--config] config [--file amdump_file]\n";
1435 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1436 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1437 print " [--estimate] [--gestimate] [--stats] [--date] [--locale-independent-date-format]\n";