5 eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}'
6 & eval 'exec @PERL@ -S $0 $argv:q'
9 require "newgetopt.pl";
11 use lib '@amperldir@';
17 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'};
18 $ENV{'PATH'} = "/bin:/usr/bin:/usr/sbin:/sbin"; # force known path
20 $confdir="@CONFIG_DIR@";
22 $prefix=$prefix; # avoid warnings about possible typo
23 $exec_prefix="@exec_prefix@";
24 $exec_prefix=$exec_prefix; # ditto
27 my $Amanda_process = Amanda::Process->new(0);
28 $Amanda_process->load_ps_table();
36 $result = &NGetOpt ( "summary",
39 "waitdumping|wdumping",
46 "gestimate|gettingestimate",
50 "locale-independent-date-format",
56 if( defined $opt_config ) {
68 #untaint user input $ARGV[0]
70 if ($conf =~ /^([\w.-]+)$/) { # $1 is untainted
73 die "filename '$conf' has invalid characters.\n";
76 if ( ! -e "$confdir/$conf" ) {
77 print "Configuration directory '$confdir/$conf' doesn't exist\n";
80 if ( ! -d "$confdir/$conf" ) {
81 print "Configuration directory '$confdir/$conf' is not a directory\n";
88 chdir "$confdir/$conf";
90 $logdir=`$sbindir/amgetconf logdir`;
93 $errfile="$logdir/amdump";
95 $nb_options = defined( $opt_summary ) +
96 defined( $opt_stats ) +
97 defined( $opt_dumping ) +
98 defined( $opt_waitdumping ) +
99 defined( $opt_waittaper ) +
100 defined( $opt_dumpingtape ) +
101 defined( $opt_writingtape ) +
102 defined( $opt_finished ) +
103 defined( $opt_estimate ) +
104 defined( $opt_gestimate ) +
105 defined( $opt_failed );
107 if($nb_options == 0 ) {
111 $opt_waitdumping = 1;
113 $opt_dumpingtape = 1;
114 $opt_writingtape = 1;
121 $unit=`$sbindir/amgetconf displayunit`;
123 $unit =~ tr/A-Z/a-z/;
128 elsif($unit eq 'm') {
131 elsif($unit eq 'g') {
132 $unitdivisor = 1024*1024;
134 elsif($unit eq 't') {
135 $unitdivisor = 1024*1024*1024;
144 if( defined $opt_file) {
145 if( $opt_file =~ m,^/, ) {
146 $errfile = $opt_file;
148 $errfile = "$pwd/$opt_file";
149 $errfile = "$logdir/$opt_file" if ( ! (-f $errfile ));
153 $errfile="$logdir/amflush" if(! (-f $errfile));
155 if (-f "$logdir/amflush.1" && -f "$logdir/amdump.1" &&
156 -M "$logdir/amflush.1" < -M "$logdir/amdump.1") {
157 $errfile="$logdir/amflush.1";
159 $errfile="$logdir/amdump.1";
165 open(AMDUMP,"<$errfile") || die("$errfile: $!");
166 print "Using $errfile\n";
168 my $taper_status_file;
170 $start_degraded_mode = 0;
172 $label = ""; # -w fodder
173 $origsize = 0; # -w fodder
176 $status_taper = "Searching for a new tape";
180 @dumpers_active = ();
182 $ntpartition{$nb_tape} = 0;
183 $ntsize{$nb_tape} = 0;
184 $ntesize{$nb_tape} = 0;
186 $driver_finished = 0;
187 $generating_schedule = 0;
189 while($lineX = <AMDUMP>) {
191 $lineX =~ s/[:\s]+$//g; #remove separator at end of line
192 next if $lineX eq "";
193 @line = "ewords('[:\s]+', 0, $lineX);
194 next if !defined $line[0];
196 if($line[0] eq "amdump" || $line[0] eq "amflush") {
197 if ($line[1] eq "start" && $line[2] eq "at") {
199 $datestr =~ s/.*start at //g;
200 if (!defined $opt_locale_independent_date_format) {
201 print "From " . $datestr . "\n";
203 } elsif($line[1] eq "datestamp") {
204 $gdatestamp = $line[2];
205 if(!defined $datestamp{$gdatestamp}) {
206 $datestamp{$gdatestamp} = 1;
207 push @datestamp, $gdatestamp;
209 } elsif($line[1] eq "starttime") {
210 $starttime=&set_starttime($line[2]);
211 } elsif($line[1] eq "starttime-locale-independent") {
212 if (defined $opt_locale_independent_date_format) {
213 printf "From " . $line[2] . " " . $line[3] . ":" . $line[4] . ":" . $line[5] . " " . $line[6] . "\n";
216 if($line[0] eq "amflush") {
219 } elsif($line[0] eq "planner") {
220 if($line[1] eq "timestamp") {
221 $gdatestamp = $line[2];
222 if(!defined $datestamp{$gdatestamp}) {
223 $datestamp{$gdatestamp} = 1;
224 push @datestamp, $gdatestamp;
227 elsif($line[1] eq "FAILED") {
228 #2:host 3:disk 4:datestamp 5:level 6:errmsg
232 $hostpart=&make_hostpart($host,$partition,$datestamp);
233 $dump_started{$hostpart}=-1;
234 $level{$hostpart}=$line[5];
235 $error{$hostpart}="planner: " . $line[6];
236 } elsif($line[1] eq "time") {
237 if($line[3] eq "got") {
238 if($line[4] eq "result") {
240 $partition = $line[9];
241 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
242 $estimate{$hostpart}=1;
243 $level{$hostpart}=$line[10];
244 $line[12] =~ /(\d+)K/;
245 $esize{$hostpart}=$1 / $unitdivisor;
246 $partialestimate{$hostpart}=0;
247 $getest{$hostpart} = "";
248 } elsif($line[4] eq "partial") {
250 $partition = $line[10];
251 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
253 $line[13] =~ /(-?\d+)K/;
256 $line[16] =~ /(-?\d+)K/;
259 $line[19] =~ /(-?\d+)K/;
261 if($size1 > 0 || $size2 > 0 || $size3 > 0) {
262 $estimate{$hostpart}=1;
263 $level{$hostpart}=$line[11];
264 $esize{$hostpart}=$size1 / $unitdivisor;
265 $partialestimate{$hostpart}=1;
266 if($size1 > 0) { $getest{$hostpart} =~ s/:$level1://; }
267 if($size2 > 0) { $getest{$hostpart} =~ s/:$level2://; }
268 if($size3 > 0) { $getest{$hostpart} =~ s/:$level3://; }
269 if($getest{$hostpart} eq "") {$partialestimate{$hostpart}=0;}
272 } elsif($line[3] eq "getting" &&
273 $line[4] eq "estimates" &&
274 $line[5] eq "took") {
278 } elsif($line[0] eq "setup_estimate") {
280 $partition = $line[2];
281 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
282 $estimate{$hostpart}=0;
284 $degr_level{$hostpart}=-1;
286 $dump_started{$hostpart}=0;
287 $dump_finished{$hostpart}=0;
288 $taper_started{$hostpart}=0;
289 $taper_finished{$hostpart}=0;
290 $partialestimate{$hostpart}=0;
291 $error{$hostpart}="";
292 if($line[7] eq "last_level") {
293 $getest{$hostpart}="";
297 if($level1 != -1) { $getest{$hostpart} .= ":$level1:" };
298 if($level2 != -1) { $getest{$hostpart} .= ":$level2:" };
299 if($level3 != -1) { $getest{$hostpart} .= ":$level3:" };
301 } elsif($line[0] eq "GENERATING" &&
302 $line[1] eq "SCHEDULE") {
303 $generating_schedule=1;
304 } elsif($line[0] eq "--------") {
305 if ($generating_schedule == 1) {
306 $generating_schedule = 2;
307 } elsif ($generating_schedule == 2) {
308 $generating_schedule = 3;
310 } elsif($line[0] eq "DUMP") {
311 if($generating_schedule == 2 ) {
313 $partition = $line[3];
314 $datestamp = $line[4];
315 $hostpart=&make_hostpart($host,$partition,$datestamp);
316 $level{$hostpart}=$line[6];
317 $esize=$line[14]; #compressed size
318 $esize=32 if $esize<32;
319 $esize{$hostpart}=$esize / $unitdivisor;
320 if(!defined($line[25])) {
321 $degr_level{$hostpart}=-1;
323 $degr_level{$hostpart}=$line[17];
324 $esize=$line[25]; #compressed size
325 $esize=32 if $esize<32;
326 $degr_size{$hostpart}=$esize / $unitdivisor;
329 } elsif($line[0] eq "FLUSH") {
331 $partition = $line[2];
332 $datestamp = $line[3];
334 $holding_file = $line[5];
335 $hostpart=&make_hostpart($host,$partition,$datestamp);
337 $dump_finished{$hostpart}=0;
338 $holding_file{$hostpart}=$holding_file;
339 $level{$hostpart}=$level;
340 } elsif($line[0] eq "driver") {
341 if($line[1] eq "pid") {
343 if (! $Amanda_process->process_alive($pid, "driver")) {
347 elsif($line[1] eq "start" && $line[2] eq "time") {
348 $start_time=$line[3];
349 $current_time=$line[3];
350 $dumpers_active[0]=0;
354 elsif($line[1] eq "tape" && $line[2] eq "size") {
355 $lineX =~ /^driver: start time (\S+)/;
356 $tape_size = $line[3] / $unitdivisor;
358 elsif($line[1] eq "adding" &&
359 $line[2] eq "holding" &&
360 $line[3] eq "disk") {
361 $holding_space += $line[8];
363 elsif($line[1] eq "send-cmd" && $line[2] eq "time") {
364 #print "send-cmd: " , $line[5] . " " . $line[6] . " " . $line[7] . "\n" if defined $line[5] && defined $line[6] && defined $line[7];
365 $current_time = $line[3];
366 if($line[5] =~ /dumper\d*/) {
368 if($line[6] eq "PORT-DUMP") {
369 #7:handle 8:port 9:host 10:amfeatures 11:disk 12:device 13:level ...
371 $partition = $line[11];
372 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
374 $dump_started{$hostpart}=1;
375 $dump_time{$hostpart}=$current_time;
376 $dump_finished{$hostpart}=0;
377 if( $level{$hostpart} != $line[13] &&
378 $degr_level{$hostpart} == $line[13]) {
379 $level{$hostpart}=$degr_level{$hostpart};
380 $esize{$hostpart}=$degr_size{$hostpart};
382 if(! defined($busy_time{$dumper})) {
383 $busy_time{$dumper}=0;
385 $running_dumper{$dumper} = $hostpart;
386 $error{$hostpart}="";
387 $size{$hostpart} = 0;
389 if(! defined($dumpers_active[$dumpers_active])) {
390 $dumpers_active[$dumpers_active]=0;
392 if(! defined($dumpers_held[$dumpers_active])) {
393 $dumpers_held[$dumpers_active]={};
397 elsif($line[5] =~ /chunker\d*/) {
398 if($line[6] eq "PORT-WRITE") {
400 $partition=$line[11];
401 $hostpart=&make_hostpart($host,$partition,$gdatestamp);
403 $serial{$serial}=$hostpart;
404 $holding_file{$hostpart}=$line[8];
405 #$chunk_started{$hostpart}=1;
406 $chunk_time{$hostpart}=$current_time;
407 #$chunk_finished{$hostpart}=0;
408 $size{$hostpart} = 0;
410 elsif($line[6] eq "CONTINUE") {
411 #7:handle 8:filename 9:chunksize 10:use
413 $hostpart=$serial{$serial};
414 if($hostpart ne "") {
415 $dump_roomq{$hostpart}=undef;
416 $error{$hostpart}="";
420 elsif($line[5] =~ /taper/) {
421 if($line[6] eq "START-TAPER") {
423 $gdatestamp=$line[7];
424 if(!defined $datestamp{$gdatestamp}) {
425 $datestamp{$gdatestamp} = 1;
426 push @datestamp, $gdatestamp;
428 $status_taper = "Searching for a new tape";
430 elsif($line[6] eq "NEW-TAPE") {
431 $status_taper = "Searching for a new tape";
433 elsif($line[6] eq "NO-NEW-TAPE") {
437 $status_taper = $error;
439 elsif($line[6] eq "FILE-WRITE") {
440 #7:handle 8:filename 9:host 10:disk 11:level 12:datestamp 13:splitsize
443 $partition=$line[10];
445 $ldatestamp=$line[12];
446 $status_taper = "Writing $host:$partition";
447 if(!defined $datestamp{$ldatestamp}) {
448 $datestamp{$ldatestamp} = 1;
449 push @datestamp, $ldatestamp;
451 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
452 $serial{$serial}=$hostpart;
453 if(!defined $level{$hostpart}) {
454 $level{$hostpart} = $level;
456 $taper_started{$hostpart}=1;
457 $taper_finished{$hostpart}=0;
458 $taper_time{$hostpart}=$current_time;
461 elsif($line[6] eq "PORT-WRITE") {
462 #7:handle 8:host 9:disk 10:level 11:datestamp 12:splitsize 13:diskbuffer 14:fallback_splitsize
467 $ldatestamp=$line[11];
468 $status_taper = "Writing $host:$partition";
469 $hostpart=&make_hostpart($host,$partition,$ldatestamp);
470 $serial{$serial}=$hostpart;
471 $taper_started{$hostpart}=1;
472 $taper_finished{$hostpart}=0;
473 $taper_time{$hostpart}=$current_time;
474 $size{$hostpart} = 0;
479 elsif($line[1] eq "result" && $line[2] eq "time") {
480 #print "result: " , $line[5] . " " . $line[6] . " " . $line[7] . "\n" if defined $line[5] && defined $line[6] && defined $line[7];
481 $current_time = $line[3];
482 if($line[5] =~ /dumper\d+/) {
483 if($line[6] eq "FAILED" || $line[6] eq "TRY-AGAIN") {
487 $hostpart=$serial{$serial};
488 if ($taper_started{$hostpart} == 1) {
489 $dump_finished{$hostpart}=-1;
491 $dump_finished{$hostpart}=-3;
493 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
494 $running_dumper{$line[5]} = "0";
495 $dump_time{$hostpart}=$current_time;
496 $error{$hostpart}="dumper: $error";
500 elsif($line[6] eq "DONE") {
501 #7:handle 8:origsize 9:size ...
503 $origsize=$line[8] / $unitdivisor;
504 $outputsize=$line[9] / $unitdivisor;
505 $hostpart=$serial{$serial};
506 $size{$hostpart}=$outputsize;
507 $dump_finished{$hostpart}=1;
508 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
509 $running_dumper{$line[5]} = "0";
510 $dump_time{$hostpart}=$current_time;
511 $error{$hostpart}="";
514 elsif($line[6] eq "ABORT-FINISHED") {
517 $hostpart=$serial{$serial};
518 $dump_started{$hostpart}=0;
519 if ($taper_started{$hostpart} == 1) {
520 $dump_finished{$hostpart}=-1;
522 $dump_finished{$hostpart}=-3;
524 $busy_time{$line[5]}+=($current_time-$dump_time{$hostpart});
525 $running_dumper{$line[5]} = "0";
526 $dump_time{$hostpart}=$current_time;
527 $error{$hostpart}="dumper: (aborted)";
531 elsif($line[5] =~ /chunker\d+/) {
532 if($line[6] eq "DONE" || $line[6] eq "PARTIAL") {
535 $outputsize=$line[8] / $unitdivisor;
536 $hostpart=$serial{$serial};
537 $size{$hostpart}=$outputsize;
538 if ($line[6] eq "DONE") {
539 $dump_finished{$hostpart}=1;
541 $dump_finished{$hostpart}=-3;
543 $busy_time{$line[5]}+=($current_time-$chunk_time{$hostpart});
544 $running_dumper{$line[5]} = "0";
545 $chunk_time{$hostpart}=$current_time;
546 if ($line[6] eq "PARTIAL") {
547 $partial{$hostpart} = 1;
550 $partial{$hostpart} = 0;
551 $error{$hostpart}="";
554 elsif($line[6] eq "FAILED") {
556 $hostpart=$serial{$serial};
557 $dump_finished{$hostpart}=-1;
558 $busy_time{$line[5]}+=($current_time-$chunk_time{$hostpart});
559 $running_dumper{$line[5]} = "0";
560 $chunk_time{$hostpart}=$current_time;
561 $error{$hostpart}="chunker: " .$line[8] if $error{$hostpart} eq "";
563 elsif($line[6] eq "RQ-MORE-DISK") {
566 $hostpart=$serial{$serial};
567 $dump_roomq{$hostpart}=1;
568 $error{$hostpart}="(waiting for holding disk space)";
571 elsif($line[5] eq "taper") {
572 if($line[6] eq "DONE" || $line[6] eq "PARTIAL") {
573 #7:handle 8:label 9:filenum 10:errstr
576 $status_taper = "Idle";
577 $hostpart=$serial{$serial};
578 $line[10] =~ /sec (\S+) kb (\d+) kps/;
579 $size=$2 / $unitdivisor;
580 $taper_finished{$hostpart}=1;
581 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
582 $taper_time{$hostpart}=$current_time;
583 if(!defined $size{$hostpart}) {
584 $size{$hostpart}=$size;
586 $ntpartition{$nb_tape}++;
587 $ntsize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
588 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
589 $ntesize{$nb_tape} += $esize{$hostpart} - $ntchunk_size;
592 $ntesize{$nb_tape} += $size{$hostpart} - $ntchunk_size;
594 if ($line[6] eq "PARTIAL") {
595 $partial{$hostpart} = 1;
598 $partial{$hostpart} = 0;
600 if ($ntchunk_size > 0) {
601 $ntchunk{$nb_tape}++;
603 undef $taper_status_file;
605 elsif($line[6] eq "PARTDONE") {
606 #7:handle 8:label 9:filenum 10:ksize 11:errstr
608 $hostpart=$serial{$serial};
609 #$line[11] =~ /.*kb (\d*) kps/;
610 #$size=$1 / $unitdivisor;
611 $size=$line[10] / $unitdivisor;
612 $tapedsize{$hostpart} += $size;
613 $ntchunk{$nb_tape}++;
614 $ntsize{$nb_tape} += $size;
615 $ntesize{$nb_tape} += $size;
616 $ntchunk_size += $size;
618 elsif($line[6] eq "REQUEST-NEW-TAPE") {
621 $old_status_taper = $status_taper;
622 $status_taper = "Asking for a new tape";
623 $hostpart=$serial{$serial};
624 if (defined $hostpart) {
625 $olderror{$hostpart} = $error{$hostpart};
626 $error{$hostpart} = "waiting for a new tape";
629 elsif($line[6] eq "NEW-TAPE") {
632 $status_taper = $old_status_taper;
633 $hostpart=$serial{$serial};
634 if (defined $hostpart) {
635 $error{$hostpart} = $olderror{$hostpart};
638 elsif($line[6] eq "TAPER-OK") {
639 $status_taper = "Idle";
641 elsif($line[6] eq "TRY-AGAIN" || $line[6] eq "TAPE-ERROR") {
645 $status_taper = $error;
646 $hostpart=$serial{$serial};
647 if(defined $hostpart) {
648 $taper_finished{$hostpart}= $line[6] eq 'TAPE-ERROR' ? -2 : -1;
649 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
650 $taper_time{$hostpart}=$current_time;
651 $error{$hostpart}="taper: $error";
653 $exit_status |= $STATUS_TAPE;
655 undef $taper_status_file;
657 elsif($line[6] eq "FAILED") {
658 #7:handle 8:INPUT- 9:TAPE- 10:input_message 11:tape_message
660 $hostpart=$serial{$serial};
661 if(defined $hostpart) {
662 if($line[9] eq "TAPE-ERROR") {
664 $taper_finished{$hostpart} = -2;
665 $status_taper = $error;
669 $taper_finished{$hostpart} = -1;
670 $status_taper = "Idle";
672 $busy_time{"taper"}+=($current_time-$taper_time{$hostpart});
673 $taper_time{$hostpart}=$current_time;
674 $error{$hostpart}="$error";
676 undef $taper_status_file;
680 elsif($line[1] eq "finished-cmd" && $line[2] eq "time") {
681 $current_time=$line[3];
682 if($line[4] =~ /dumper\d+/) {
685 elsif($line[1] eq "dump" && $line[2] eq "failed") {
686 #3:handle 4: 5: 6:"too many dumper retry"
688 $hostpart=$serial{$serial};
689 $dump_started{$hostpart}=-1;
690 $dump_finished{$hostpart}=-2;
691 $error{$hostpart} .= "(" . $line[6] . ")";
693 elsif($line[1] eq "tape" && $line[2] eq "failed") {
694 #3:handle 4: 5: 6:"too many dumper retry"
696 $hostpart=$serial{$serial};
697 $taper_started{$hostpart}=-1;
698 $taper_finished{$hostpart}=-2;
699 $error{$hostpart} .= "(" . $line[6] . ")";
701 elsif($line[1] eq "state" && $line[2] eq "time") {
702 #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
703 $current_time=$line[3];
704 $idle_dumpers=$line[12];
706 $free{"kps"} = $line[6];
707 $free{"space"} = $line[8];
708 $qlen{"tapeq"} = $line[15];
709 $qlen{"runq"} = $line[17];
710 $qlen{"roomq"} = $line[19];
712 if(defined($dumpers_active)) {
713 if($status_driver ne "") {
714 $dumpers_active[$dumpers_active_prev]
715 +=$current_time-$state_time_prev;
716 $dumpers_held[$dumpers_active_prev]{$status_driver}
717 +=$current_time-$state_time_prev;
719 $state_time_prev=$current_time;
720 $dumpers_active_prev=$dumpers_active;
721 $status_driver=$line[23];
722 if(! defined($dumpers_held[$dumpers_active]{$status_driver})) {
723 $dumpers_held[$dumpers_active]{$status_driver}=0;
727 elsif($line[1] eq "FINISHED") {
728 $driver_finished = 1;
731 elsif($line[0] eq "dump") {
732 if($line[1] eq "of" &&
733 $line[2] eq "driver" &&
734 $line[3] eq "schedule" &&
735 $line[4] eq "after" &&
736 $line[5] eq "start" &&
737 $line[6] eq "degraded" &&
738 $line[7] eq "mode") {
739 $start_degraded_mode=1;
742 elsif($line[0] eq "taper") {
743 if($line[1] eq "slot") {
744 #2:slot 3:"wrote" 4:"label" 5:corrupted...
746 $lineX =~ /wrote label `(\S*)'/;
748 $ntlabel{$nb_tape} = $label;
749 $ntpartition{$nb_tape} = 0;
750 $ntsize{$nb_tape} = 0;
751 $ntesize{$nb_tape} = 0;
753 elsif($line[1] eq "wrote") {
754 #1:"wrote" 2:"label" 3:corrupted
756 $lineX =~ /wrote label `(\S*)'/;
758 $ntlabel{$nb_tape} = $label;
759 $ntpartition{$nb_tape} = 0;
760 $ntsize{$nb_tape} = 0;
761 $ntesize{$nb_tape} = 0;
763 elsif($line[1] eq "using") {
764 #1:"using" #2:"label" #3:`label' #4:date #5 `timestamp'
766 $lineX =~ /using label `(\S*)'/;
768 $ntlabel{$nb_tape} = $label;
769 $ntpartition{$nb_tape} = 0;
770 $ntsize{$nb_tape} = 0;
771 $ntesize{$nb_tape} = 0;
773 elsif($line[1] eq "status" && $line[2] eq "file") {
774 #1:"status" #2:"file:" #3:hostname #4:diskname #5:filename
775 $taper_status_file = $line[5];
778 elsif($line[0] eq "splitting" &&
779 $line[1] eq "chunk" &&
780 $line[2] eq "that" &&
781 $line[3] eq "started" &&
783 $line[6] eq "after") {
784 $line[7] =~ /(\d*)kb/;
786 $ntchunk{$nb_tape}++;
787 $ntsize{$nb_tape} += $size / $unitdivisor;
788 $ntesize{$nb_tape} += $size / $unitdivisor;
789 $ntchunk_size += $size / $unitdivisor;
792 #print "Ignoring: $lineX\n";
798 if(defined $current_time) {
799 for ($d = 0; $d < $#dumpers_active; $d++) {
800 $the_dumper = "dumper$d";
801 if(defined($running_dumper{$the_dumper}) &&
802 $running_dumper{$the_dumper} ne "0") {
803 $busy_time{$the_dumper}+=($current_time-$dump_time{$running_dumper{$the_dumper}});
847 foreach $host (sort @hosts) {
848 foreach $partition (sort @$host) {
849 foreach $datestamp (sort @datestamp) {
850 $hostpart=&make_hostpart($host,$partition,$datestamp);
851 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
852 if(length("$host:$partition") > $maxnamelength) {
853 $maxnamelength = length("$host:$partition");
859 foreach $host (sort @hosts) {
860 foreach $partition (sort @$host) {
861 $qpartition = Amanda::Util::quote_string($partition);
862 foreach $datestamp (sort @datestamp) {
863 $hostpart=&make_hostpart($host,$partition,$datestamp);
864 next if(!defined $estimate{$hostpart} && !defined $flush{$hostpart});
866 if( (!defined $size{$hostpart} || $size{$hostpart} == 0) &&
867 defined $holding_file{$hostpart}) {
868 $size{$hostpart} = &dump_size($holding_file{$hostpart}) / (1024 * $unitdivisor);
871 if($estimate_done != 1 && !defined $flush{$hostpart}) {
872 if(defined $estimate{$hostpart}) {
873 if($estimate{$hostpart} != 1) {
874 if( defined $opt_gestimate ||
875 defined $opt_failed && $dead_run != 0) {
876 printf "%8s ", $datestamp if defined $opt_date;
877 printf "%-${maxnamelength}s", "$host:$qpartition";
880 print " failed: killed while";
881 $exit_status |= $STATUS_FAILED;
883 print " getting estimate\n";
887 if(defined $opt_estimate ||
888 (defined $opt_gestimate && $partialestimate{$hostpart} == 1) ||
889 (defined $opt_failed && $dead_run != 0 && $partialestimate{$hostpart} == 1)) {
890 printf "%8s ", $datestamp if defined $opt_date;
891 printf "%-${maxnamelength}s", "$host:$qpartition";
892 printf "%2d ", $level{$hostpart};
893 printf "%9d$unit", $esize{$hostpart};
894 if($partialestimate{$hostpart} == 1) {
896 print " failed: killed while";
897 $exit_status |= $STATUS_FAILED;
901 print " estimate done\n";
904 $estsize += $esize{$hostpart};
909 if(defined $estimate{$hostpart}) {
910 if($estimate{$hostpart} == 1) {
912 $estsize += $esize{$hostpart};
914 elsif (!defined $dump_started{$hostpart} || $dump_started{$hostpart} == 0) {
915 if( defined $opt_failed) {
916 printf "%8s ", $datestamp if defined $opt_date;
917 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
918 printf " no estimate\n";
920 $exit_status |= $STATUS_FAILED;
922 $fsize+=$esize{$hostpart};
927 $flsize += $size{$hostpart};
930 if(defined $taper_started{$hostpart} &&
931 $taper_started{$hostpart}==1 &&
932 $dump_finished{$hostpart}!=-3) {
933 if(defined $dump_started{$hostpart} &&
934 $dump_started{$hostpart} == 1 &&
935 $dump_finished{$hostpart} == -1) {
936 if(defined $opt_failed) {
937 printf "%8s ", $datestamp if defined $opt_date;
938 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
939 printf "%9d$unit", $esize{$hostpart};
940 print " dump to tape failed: " . $error{$hostpart};
943 $exit_status |= $STATUS_FAILED;
945 $fsize+=$esize{$hostpart};
946 } elsif(defined $dump_started{$hostpart} &&
947 $dump_started{$hostpart} == 1 &&
948 $dump_finished{$hostpart} == 0 &&
949 $taper_started{$hostpart} == 1) {
950 if( defined $opt_dumpingtape ||
951 defined $opt_failed && $dead_run != 0) {
952 printf "%8s ", $datestamp if defined $opt_date;
953 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
954 printf "%9d$unit", $esize{$hostpart};
956 print " failed: killed while";
957 $exit_status |= $STATUS_FAILED;
959 print " dumping to tape";
960 $size = $tapedsize{$hostpart};
961 if ($taper_status_file && -f $taper_status_file &&
962 open FF, "<$taper_status_file") {
966 $value = $line / ($unitdivisor * 1024);
968 $size = $value if (!defined($size) || $value > $size);
974 printf " (%d$unit done (%0.2f%%))", $size, 100.0 * $size/$esize{$hostpart};
977 if( defined $starttime ) {
978 print " (", &showtime($taper_time{$hostpart}), ")";
983 $dtesize += $esize{$hostpart};
985 elsif($taper_finished{$hostpart} == 0) {
986 if( defined $opt_writingtape ||
987 defined $opt_failed && $dead_run != 0) {
988 printf "%8s ", $datestamp if defined $opt_date;
989 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
990 printf "%9d$unit", $size{$hostpart};
992 print " failed: killed while";
993 $exit_status |= $STATUS_FAILED;
996 print " writing to tape";
999 print " flushing to tape";
1001 $size = $tapedsize{$hostpart};
1002 if ($taper_status_file && -f $taper_status_file &&
1003 open FF, "<$taper_status_file") {
1005 if (defined $line) {
1007 $value = $line / ($unitdivisor * 1024);
1009 $size = $value if (!defined($size) || $value > $size);
1014 if(defined($size)) {
1015 printf " (%d$unit done (%0.2f%%))", $size, 100.0 * $size/$size{$hostpart};
1017 if( defined $starttime ) {
1018 print " (", &showtime($taper_time{$hostpart}), ")";
1020 print ", ", $error{$hostpart} if (defined($error{$hostpart}) &&
1021 $error{$hostpart} ne "");
1025 $tasize += $size{$hostpart};
1026 if(defined $esize{$hostpart}) {
1027 $taesize += $esize{$hostpart};
1030 $taesize += $size{$hostpart};
1032 if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
1034 $dsize += $size{$hostpart};
1035 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1036 $desize += $esize{$hostpart};
1038 $desize += $size{$hostpart};
1042 elsif($taper_finished{$hostpart} < 0) {
1044 if(defined $size{$hostpart}) {
1045 $xsize = $size{$hostpart};
1047 elsif(defined $esize{$hostpart}) {
1048 $xsize = $esize{$hostpart};
1054 if(defined $esize{$hostpart}) {
1055 $exsize += $esize{$hostpart};
1061 if( defined $opt_failed ||
1062 (defined $opt_waittaper && ($taper_finished{$hostpart} == -1))) {
1063 printf "%8s ", $datestamp if defined $opt_date;
1064 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1065 printf "%9d$unit", $xsize;
1066 if($in_flush == 0) {
1067 print " failed to tape";
1070 print " failed to flush";
1072 print ": ",$error{$hostpart} if defined $error{$hostpart};
1074 print " (will retry)" unless $taper_finished{$hostpart} < -1;
1075 if( defined $starttime ) {
1076 print " (", &showtime($taper_time{$hostpart}), ")";
1080 $exit_status |= $STATUS_TAPE;
1084 $tfesize += $exsize;
1086 if($in_flush == 0) {
1089 $twesize += $exsize;
1095 if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
1097 $dsize += $size{$hostpart};
1098 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1099 $desize += $esize{$hostpart};
1101 $desize += $size{$hostpart};
1105 elsif($taper_finished{$hostpart} == 1) {
1106 if( defined $opt_finished ) {
1107 printf "%8s ", $datestamp if defined $opt_date;
1108 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1109 printf "%9d$unit", $size{$hostpart};
1110 if($in_flush == 0) {
1116 if( defined $starttime ) {
1117 print " (", &showtime($taper_time{$hostpart}), ")";
1119 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1121 $exit_status |= $STATUS_FAILED;
1125 if (defined $dump_finished{$hostpart} && $dump_finished{$hostpart} == 1) {
1127 $dsize += $size{$hostpart};
1128 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1129 $desize += $esize{$hostpart};
1131 $desize += $size{$hostpart};
1135 $tsize += $size{$hostpart};
1136 if(defined $esize{$hostpart} && $esize{$hostpart} > 1) {
1137 $tesize += $esize{$hostpart};
1140 $tesize += $size{$hostpart};
1144 printf "%8s ", $datestamp if defined $opt_date;
1145 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1146 print " unknown state TAPER\n";
1149 elsif(defined $dump_started{$hostpart}) {
1150 if($dump_started{$hostpart} == -1) {
1151 if( defined $opt_failed ) {
1152 printf "%8s ", $datestamp if defined $opt_date;
1153 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1154 printf "failed: " . $error{$hostpart} . "\n";
1156 $exit_status |= $STATUS_FAILED;
1159 $fsize+=$esize{$hostpart};
1161 elsif($dump_started{$hostpart} == 0) {
1162 if($estimate{$hostpart} == 1) {
1163 if( defined $opt_waitdumping ) {
1164 printf "%8s ", $datestamp if defined $opt_date;
1165 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1166 printf "%9d$unit", $esize{$hostpart};
1168 print " failed: process terminated while";
1169 $exit_status |= $STATUS_FAILED;
1171 print " waiting for dumping $error{$hostpart}\n";
1173 if($driver_finished == 1) {
1174 $exit_status |= $STATUS_MISSING;
1177 $wsize += $esize{$hostpart};
1180 elsif($dump_started{$hostpart} == 1 &&
1181 ($dump_finished{$hostpart} == -1 ||
1182 $dump_finished{$hostpart} == -3)) {
1183 if( defined $opt_failed ) {
1184 printf "%8s ", $datestamp if defined $opt_date;
1185 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1186 print "backup failed: ", $error{$hostpart};
1187 if( defined $starttime ) {
1188 print " (", &showtime($dump_time{$hostpart}), ")";
1192 $exit_status |= $STATUS_FAILED;
1194 $fsize+=$esize{$hostpart};
1196 elsif($dump_started{$hostpart} == 1 &&
1197 $dump_finished{$hostpart} == 0) {
1198 if( defined $opt_dumping ||
1199 defined $opt_failed && $dead_run != 0) {
1200 printf "%8s ", $datestamp if defined $opt_date;
1201 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1202 printf "%9d$unit", $esize{$hostpart};
1204 print " failed: killed while";
1205 $exit_status |= $STATUS_FAILED;
1207 printf " dumping %8d$unit", $size{$hostpart};
1208 if($size{$hostpart} != 0) {
1209 printf " (%6.2f%%)", (100.0*$size{$hostpart})/$esize{$hostpart};
1211 if( defined $starttime ) {
1212 print " (", &showtime($dump_time{$hostpart}), ")";
1214 if(defined $dump_roomq{$hostpart}) {
1215 print " " . $error{$hostpart};
1220 $dusize += $size{$hostpart};
1221 $duesize += $esize{$hostpart};
1223 elsif($dump_finished{$hostpart} == 1 &&
1224 $taper_started{$hostpart} != 1) {
1225 if( defined $opt_waittaper ) {
1226 printf "%8s ", $datestamp if defined $opt_date;
1227 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1228 printf "%9d$unit", $size{$hostpart};
1230 if( defined $starttime ) {
1231 print " (", &showtime($dump_time{$hostpart}), ")";
1235 print " process terminated while";
1237 print " waiting for writing to tape";
1238 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1240 $exit_status |= $STATUS_FAILED;
1245 $dsize += $size{$hostpart};
1246 $desize += $esize{$hostpart};
1248 $twsize += $size{$hostpart};
1249 $twesize += $esize{$hostpart};
1252 printf "%8s ", $datestamp if defined $opt_date;
1253 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1254 print " unknown state DUMPER\n";
1257 elsif(defined $flush{$hostpart}) {
1258 if( defined $opt_waittaper ) {
1259 printf "%8s ", $datestamp if defined $opt_date;
1260 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1261 printf "%9d$unit", $size{$hostpart};
1263 print " process terminated while";
1265 print " waiting to flush";
1266 if(defined $partial{$hostpart} && $partial{$hostpart} == 1) {
1268 $exit_status |= $STATUS_FAILED;
1273 $wfsize += $size{$hostpart};
1275 elsif(defined $level{$hostpart}) {
1276 printf "%8s ", $datestamp if defined $opt_date;
1277 printf "%-${maxnamelength}s%2d ", "$host:$qpartition", $level{$hostpart};
1278 print " unknown state\n";
1285 if (defined $opt_summary) {
1287 print "SUMMARY part real estimated\n";
1288 print " size size\n";
1289 printf "partition : %3d\n", $nb_partition;
1290 printf "estimated : %3d %20d$unit\n", $epartition , $estsize;
1291 printf "flush : %3d %9d$unit\n", $flpartition, $flsize;
1292 printf "failed : %3d %20d$unit (%6.2f%%)\n",
1293 $fpartition , $fsize,
1294 $estsize ? ($fsize * 1.0 / $estsize) * 100 : 0.0;
1295 printf "wait for dumping: %3d %20d$unit (%6.2f%%)\n",
1296 $wpartition , $wsize,
1297 $estsize ? ($wsize * 1.0 / $estsize) * 100 : 0.0;
1298 if(defined($dtsize)) {
1299 printf "dumping to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1300 $dtpartition, $dtsize, $dtesize,
1301 $dtsize ? ($dtsize * 1.0 / $dtesize) * 100 : 0.0,
1302 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1304 printf "dumping to tape : %3d %20d$unit (%6.2f%%)\n",
1305 $dtpartition, $dtesize,
1306 $estsize ? ($dtesize * 1.0 / $estsize) * 100 : 0.0;
1308 printf "dumping : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1309 $dupartition, $dusize, $duesize,
1310 $duesize ? ($dusize * 1.0 / $duesize) * 100 : 0.0,
1311 $estsize ? ($dusize * 1.0 / $estsize) * 100 : 0.0;
1312 printf "dumped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1313 $dpartition , $dsize , $desize,
1314 $desize ? ($dsize * 1.0 / $desize) * 100 : 0.0,
1315 $estsize ? ($dsize * 1.0 / $estsize) * 100 : 0.0;
1316 printf "wait for writing: %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1317 $twpartition, $twsize, $twesize,
1318 $twesize ? ($twsize * 1.0 / $twesize) * 100 : 0.0,
1319 $estsize ? ($twsize * 1.0 / $estsize) * 100 : 0.0;
1320 printf "wait to flush : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1321 $wfpartition, $wfsize, $wfsize, 100, 0;
1322 printf "writing to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1323 $tapartition, $tasize, $taesize,
1324 $taesize ? ($tasize * 1.0 / $taesize) * 100 : 0.0,
1325 $estsize ? ($tasize * 1.0 / $estsize) * 100 : 0.0;
1326 printf "failed to tape : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1327 $tfpartition, $tfsize, $tfesize,
1328 $tfesize ? ($tfsize * 1.0 / $tfesize) * 100 : 0.0,
1329 $estsize ? ($tfsize * 1.0 / $estsize) * 100 : 0.0;
1330 printf "taped : %3d %9d$unit %9d$unit (%6.2f%%) (%6.2f%%)\n",
1331 $tpartition , $tsize , $tesize,
1332 $tesize ? ($tsize * 1.0 / $tesize) * 100 : 0.0,
1333 ($estsize+$flsize) ? ($tsize * 1.0 / ($estsize + $flsize)) * 100 : 0.0;
1334 if($nb_tape > 1 || $tape_size != 0) {
1335 for($i=1; $i <= $nb_tape; $i++) {
1336 if($tape_size != 0) {
1337 printf " tape %-3d : %3d %9d$unit %9d$unit (%6.2f%%) %s",
1338 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, 100*$ntsize{$i}/$tape_size, $ntlabel{$i};
1341 printf " tape %-3d : %3d %9d$unit %9d$unit %s",
1342 $i, $ntpartition{$i}, $ntsize{$i}, $ntesize{$i}, $ntlabel{$i};
1344 if(defined($ntchunk{$i}) && $ntchunk{$i} > 0) {
1345 printf " (%d chunks)", $ntchunk{$i};
1350 if($idle_dumpers == 0) {
1351 printf "all dumpers active\n";
1354 $c1 = ($idle_dumpers == 1) ? "" : "s";
1355 $c2 = ($idle_dumpers < 10) ? " " : "";
1356 $c3 = ($idle_dumpers == 1) ? " " : "";
1357 printf "%d dumper%s idle%s %s: %s\n", $idle_dumpers, $c1, $c2, $c3, $status_driver;
1360 printf "taper status: $status_taper\n";
1361 if (defined $qlen{"tapeq"}) {
1362 printf "taper qlen: %d\n", $qlen{"tapeq"};
1364 if (defined ($free{"kps"})) {
1365 printf "network free kps: %9d\n", $free{"kps"};
1367 if (defined ($free{"space"})) {
1368 if ($holding_space) {
1369 $hs = ($free{"space"} * 1.0 / $holding_space) * 100;
1373 printf "holding space : %9d$unit (%6.2f%%)\n", ($free{"space"}/$unitdivisor), $hs;
1377 if(defined $opt_stats) {
1378 if(defined($current_time) && $current_time != $start_time) {
1379 $total_time=$current_time-$start_time;
1380 foreach $key (sort byprocess keys %busy_time) {
1381 printf "%8s busy : %8s (%6.2f%%)\n",
1382 $key, &busytime($busy_time{$key}),
1383 ($busy_time{$key} * 1.0 / $total_time) * 100;
1385 for ($d = 0; $d <= $#dumpers_active; $d++) {
1386 $l = sprintf "%2d dumper%s busy%s : %8s (%6.2f%%)",
1387 $d, ($d == 1) ? "" : "s", ($d == 1) ? " " : "",
1388 &busytime($dumpers_active[$d]),
1389 ($dumpers_active[$d] * 1.0 / $total_time) * 100;
1392 $s2 = " " x length($l);
1393 $r = $dumpers_held[$d];
1394 foreach $key (sort valuesort keys %$r) {
1396 unless $dumpers_held[$d]{$key} >= 1;
1397 printf "%s%20s: %8s (%6.2f%%)\n",
1400 &busytime($dumpers_held[$d]{$key}),
1401 ($dumpers_held[$d]{$key} * 1.0 / $dumpers_active[$d]) * 100;
1413 sub make_hostpart() {
1414 local($host,$partition,$datestamp) = @_;
1416 if(! defined($hosts{$host})) {
1421 foreach $pp (sort @$host) {
1422 $new_part = 0 if ($pp eq $partition);
1424 push @$host, $partition if $new_part==1;
1426 my($hostpart) = "$host$partition$datestamp";
1427 if(!defined $datestamp{$datestamp}) {
1428 $datestamp{$datestamp} = 1;
1429 push @datestamp, $datestamp;
1436 my(@tmp_a) = split(/(\d*)$/, $a, 2);
1437 my(@tmp_b) = split(/(\d*)$/, $b, 2);
1438 return ($tmp_a[0] cmp $tmp_b[0]) || ($tmp_a[1] <=> $tmp_b[1]);
1442 $r->{$b} <=> $r->{$a};
1446 local($filename) = @_;
1449 local($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1450 $atime,$mtime,$ctime,$blksize,$blocks);
1451 while ($filename ne "") {
1452 $filename = "$filename.tmp" if (!(-e "$filename"));
1453 $filename = "/dev/null" if (!(-e "$filename"));
1454 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
1455 $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
1456 $size=$size-32768 if $size > 32768;
1458 open(DUMP,$filename);
1461 if(/^CONT_FILENAME=(.*)$/) { $filename = $1; last }
1462 last if /^To restore, position tape at start of file and run/;
1477 @MoY = ('Jan','Feb','Mar','Apr','May','Jun',
1478 'Jul','Aug','Sep','Oct','Nov','Dec');
1480 # Preset an array of values in case some parts are not passed as
1481 # arguments. This lets the date, etc, be omitted and default to
1490 # See if this argument looks like a month name.
1496 $month = $month + 1;
1503 # See if this is a day of the month.
1505 if ($a =~ /^\d+$/ && $a >= 1 && $a <= 32) {
1510 # See if the next argument looks like a time.
1512 if ($a =~ /^(\d+):(\d+)/) {
1515 if ($a =~ /^(\d+):(\d+):(\d+)/) {
1521 # See if this is a year.
1523 if ($a =~ /^\d\d\d\d$/ && $a >= 1900) {
1529 $time = &timelocal (@tl);
1534 sub set_starttime() {
1539 # Preset an array of values in case some parts are not passed as
1540 # arguments. This lets the date, etc, be omitted and default to
1546 $tl[5] = substr($date, 0, 4) if(length($date) >= 4);
1547 $tl[4] = substr($date, 4, 2)-1 if(length($date) >= 6);
1548 $tl[3] = substr($date, 6, 2) if(length($date) >= 8);
1549 $tl[2] = substr($date, 8, 2) if(length($date) >= 10);
1550 $tl[1] = substr($date, 10, 2) if(length($date) >= 12);
1551 $tl[0] = substr($date, 12, 2) if(length($date) >= 14);
1553 $time = &timelocal (@tl);
1561 my($oneday)=24*60*60;
1563 @now=localtime($starttime+$delta);
1564 if($delta > $oneday) {
1565 $result=sprintf("%d+",$delta/$oneday);
1569 $result.=sprintf("%d:%02d:%02d",$now[2],$now[1],$now[0]);
1575 my($oneday)=24*60*60;
1577 if($busy > $oneday) {
1578 $days=int($busy/$oneday);
1579 $result=sprintf("%d+",$busy/$oneday);
1580 $busy-=$days*$oneday;
1584 $hours=int($busy/60/60);
1585 $busy-=$hours*60*60;
1586 $minutes=int($busy/60);
1589 $result.=sprintf("%d:%02d:%02d",$hours,$minutes,$seconds);
1594 print "amstatus [--config] config [--file amdump_file]\n";
1595 print " [--summary] [--dumping] [--waitdumping] [--waittaper]\n";
1596 print " [--dumpingtape] [--writingtape] [--finished] [--failed]\n";
1597 print " [--estimate] [--gestimate] [--stats] [--date] [--locale-independent-date-format]\n";