X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=server-src%2Famoverview.pl;h=eb53a3f1475f5676a075bb65f491c01a5d18e90c;hb=HEAD;hp=35594e4eaf85b4ed033239cffb13e5ee40320547;hpb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;p=debian%2Famanda diff --git a/server-src/amoverview.pl b/server-src/amoverview.pl index 35594e4..eb53a3f 100644 --- a/server-src/amoverview.pl +++ b/server-src/amoverview.pl @@ -1,62 +1,53 @@ #!@PERL@ - -# Catch for sh/csh on systems without #! ability. -eval '(exit $?0)' && eval 'exec @PERL@ -S $0 ${1+"$@"}' - & eval 'exec @PERL@ -S $0 $argv:q' - if 0; - -require 5.001; - +# Copyright (c) 2010-2012 Zmanda Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300 +# Sunnyvale, CA 94086, USA, or: http://www.zmanda.com + +use lib '@amperldir@'; +use strict; +use warnings; + +use Amanda::Config qw( :init :getconf ); +use Amanda::Disklist; +use Amanda::DB::Catalog; use FileHandle; use Getopt::Long; -use Text::ParseWords; use Carp; use POSIX; -delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV', 'PATH'}; -$ENV{'PATH'} = "/usr/bin:/usr/sbin:/sbin:/bin"; - sub Usage { print STDERR < This script generates to standard output an overview of the filesystems dumped over time and the type of dump done on a particular day, such as a full dump, or an incremental, or if the dump failed. -You may override the default configuration `@DEFAULT_CONFIG@' by using -the -config command line option. On larger installations, this script -will take a while to run. In this case, run it with --verbose to see -how far along it is. +On larger installations, this script will take a while to run. In this case, +run it with --verbose to see how far along it is. END exit 1; } -# Default paths for this installation of Amanda. -my $prefix='@prefix@'; -$prefix=$prefix; # avoid warnings about possible typo -my $exec_prefix="@exec_prefix@"; -$exec_prefix=$exec_prefix; # ditto -my $amlibexecdir="@amlibexecdir@"; -my $sbindir="@sbindir@"; - -# The directory where configurations can be found. -my $confdir="@CONFIG_DIR@"; - -# The default configuration. -my $config="@DEFAULT_CONFIG@"; - -# Get the version suffix. -my $USE_VERSION_SUFFIXES = '@USE_VERSION_SUFFIXES@'; -my $suf = ''; -if ( $USE_VERSION_SUFFIXES =~ /^yes$/i ) { - $suf='-@VERSION@'; -} - -my $amadmin = "$sbindir/amadmin$suf"; - # overrideable defaults -my $opt_config = "$config"; +my $opt_version; +my $opt_config = undef; my $opt_hostwidth = 8; my $opt_diskwidth = 20; my $opt_skipmissed = 0; @@ -65,7 +56,8 @@ my $opt_num0 = 0; my $opt_togo0 = 0; my $opt_verbose = 0; -GetOptions('config=s' => \$opt_config, +GetOptions('version' => \$opt_version, + 'config=s' => \$opt_config, 'hostwidth=i' => \$opt_hostwidth, 'diskwidth=i' => \$opt_diskwidth, 'skipmissed' => \$opt_skipmissed, @@ -75,105 +67,69 @@ GetOptions('config=s' => \$opt_config, 'verbose' => \$opt_verbose) or Usage(); -if($#ARGV == 0) { - $opt_config = $ARGV[0]; -} -elsif($#ARGV > 0) { - Usage(); +if (defined $opt_version) { + print "amoverview-" . $Amanda::Constants::VERSION , "\n"; + exit 0; } -#untaint user input $ARGV[0] - -if ($opt_config =~ /^([\w.-]+)$/) { # $1 is untainted - $opt_config = $1; -} else { - die "filename '$opt_config' has invalid characters.\n"; +unless(defined($opt_config)) { + if (@ARGV == 1) { + $opt_config = $ARGV[0]; + } else { + Usage(); + } } - --d "$confdir/$opt_config" or - die "$0: directory `$confdir/$opt_config' does not exist.\n"; +#Initialize configuration +config_init($CONFIG_INIT_EXPLICIT_NAME, $opt_config); +my ($cfgerr_level, @cfgerr_errors) = config_errors(); +if ($cfgerr_level >= $CFGERR_WARNINGS) { + config_print_errors(); + if ($cfgerr_level >= $CFGERR_ERRORS) { + die("errors processing config file"); + } +} # read disklist +$cfgerr_level = Amanda::Disklist::read_disklist(); +die("Config errors") if ($cfgerr_level >= $CFGERR_WARNINGS); + my %disks = (); -$::host = ''; -$::disk = ''; -$opt_verbose and - print STDERR "Running $amadmin $opt_config disklist\n"; -my $dlfh = new FileHandle "$amadmin $opt_config disklist|" or - die "$0: error in opening `$amadmin $opt_config disklist' pipe: $!\n"; -$/ = ""; -while (<$dlfh>) { - ($host, $disk) = m/ host (.*?):.* disk (.*?):.*strategy (STANDARD|NOFULL|NOINC|HANOI|INCRONLY).*ignore NO/s; - next unless $host; - $disks{$host}{$disk}++; +foreach my $dle (Amanda::Disklist::all_disks()) { + $disks{$dle->{"host"}->{"hostname"}}{$dle->{"name"}}++; } -$/ = "\n"; -$dlfh->close or - die "$0: error in closing `$amadmin $opt_config disklist|' pipe: $!\n"; - -# Get backup dates -%::dates = (); -%::level = (); -$::level = ''; -my ($date, $tape, $file, $status); +# Get dumps +my %dates = (); +my %level = (); +my ($date, $host, $disk); $opt_verbose and - print STDERR "Running $amadmin $opt_config find\n"; -my $fh = new FileHandle "$amadmin $opt_config find|" or - die "$0: error in opening `$amadmin $opt_config find' pipe: $!\n"; -<$fh>; -while (<$fh>) { - chomp; - next if /found Amanda directory/; - next if /skipping cruft directory/; - next if /skip-incr/; - - ($date, $time, $host, $disk, $level, $tape, $file, $part, $status) = shellwords($_); - - next if $date eq 'date'; - next if $date eq 'Warning:'; - next if $date eq 'Scanning'; - next if $date eq ""; - - if($time !~/^\d\d:\d\d:\d\d$/) { - $status = $part; - $part = $file; - $file = $tape; - $tape = $level; - $level = $disk; - $disk = $host; - $host = $time; - } - - if ($date =~ /^\d\d\d\d-\d\d-\d\d$/) { - if(defined $disks{$host}{$disk}) { - defined($level{$host}{$disk}{$date}) or - $level{$host}{$disk}{$date} = ''; - $level{$host}{$disk}{$date} .= ($status eq 'OK') ? $level : 'E'; - $dates{$date}++; - } - } - else { - print "bad date $date in $_\n"; + print STDERR "Processing $opt_config dumps\n"; +foreach my $dump (Amanda::DB::Catalog::sort_dumps(['hostname','diskname','write_timestamp'],Amanda::DB::Catalog::get_dumps())) { + $host = $dump->{"hostname"}; + $disk = $dump->{"diskname"}; + $date = substr($dump->{"dump_timestamp"},0,8); + + if (defined $disks{$host}{$disk}) { + defined($level{$host}{$disk}{$date}) or + $level{$host}{$disk}{$date} = ''; + $level{$host}{$disk}{$date} .= ($dump->{"status"} eq 'OK') ? $dump->{"level"} : 'E'; + $dates{$date}++; } } -$fh->close or - die "$0: error in closing `$amadmin $opt_config find|' pipe: $!\n"; # Process the status to arrive at a "last" status if ($opt_last) { for $host (sort keys %disks) { for $disk (sort keys %{$disks{$host}}) { - $level{$host}{$disk}{"0000-LA-ST"} = ''; + $level{$host}{$disk}{"0000LAST"} = ''; for $date (sort keys %dates) { + next unless defined($level{$host}{$disk}{$date}); if ($level{$host}{$disk}{$date} eq "E" - && $level{$host}{$disk}{"0000-LA-ST"} =~ /^\d/ ) { - $level{$host}{$disk}{"0000-LA-ST"} .= $level{$host}{$disk}{$date}; - } elsif ($level{$host}{$disk}{$date} eq "") { - $level{$host}{$disk}{"0000-LA-ST"} =~ s/E//; + && $level{$host}{$disk}{"0000LAST"} =~ /^\d/ ) { + $level{$host}{$disk}{"0000LAST"} .= $level{$host}{$disk}{$date}; } else { - $level{$host}{$disk}{"0000-LA-ST"} = $level{$host}{$disk}{$date}; + $level{$host}{$disk}{"0000LAST"} = $level{$host}{$disk}{$date}; } } } @@ -184,10 +140,11 @@ if ($opt_last) { if ($opt_num0) { for $host (sort keys %disks) { for $disk (sort keys %{$disks{$host}}) { - $level{$host}{$disk}{'0000-NM-L0'} = 0; + $level{$host}{$disk}{'0000NML0'} = 0; for $date (sort keys %dates) { - if ($level{$host}{$disk}{$date} =~ /0/) { - $level{$host}{$disk}{'0000-NM-L0'} += 1; + if (defined($level{$host}{$disk}{$date}) + && $level{$host}{$disk}{$date} =~ /0/) { + $level{$host}{$disk}{'0000NML0'} += 1; } } } @@ -198,11 +155,12 @@ if ($opt_num0) { if ($opt_togo0) { for $host (sort keys %disks) { for $disk (sort keys %{$disks{$host}}) { - $level{$host}{$disk}{'0000-TO-GO'} = 0; + $level{$host}{$disk}{'0000TOGO'} = 0; my $togo=0; for $date (sort keys %dates) { - if ($level{$host}{$disk}{$date} =~ /0/) { - $level{$host}{$disk}{'0000-TO-GO'} = $togo; + if (defined($level{$host}{$disk}{$date}) + && $level{$host}{$disk}{$date} =~ /0/) { + $level{$host}{$disk}{'0000TOGO'} = $togo; } $togo++; } @@ -215,51 +173,59 @@ unless ($opt_skipmissed) { my ($start, $finish) = map { - my($y,$m,$d) = split /-/, $_; + my($y,$m,$d) = /(....)(..)(..)/; POSIX::mktime(0,0,0,$d,$m-1,$y-1900); } (sort keys %dates)[0,-1]; - while ($start < $finish) { - my @l = localtime $start; - $dates{sprintf("%d-%02d-%02d", 1900+$l[5], $l[4]+1, $l[3])}++; - $start += 86400; + # Special case of only one date + if (defined($finish)) { + while ($start < $finish) { + my @l = localtime $start; + $dates{sprintf("%d%02d%02d", 1900+$l[5], $l[4]+1, $l[3])}++; + $start += 86400; + } } } #Add the "last" entry -$dates{"0000-LA-ST"}=1 if ($opt_last); +$dates{"0000LAST"}=1 if ($opt_last); #Add the "Number of Level 0s" entry -$dates{"0000-NM-L0"}=1 if ($opt_num0); +$dates{"0000NML0"}=1 if ($opt_num0); #Add the "Runs to go" entry -$dates{"0000-TO-GO"}=1 if ($opt_togo0); +$dates{"0000TOGO"}=1 if ($opt_togo0); # make formats -my $top_format = "format TOP =\n\n" . - sprintf("%-0${opt_hostwidth}s %-0${opt_diskwidth}s ", '', 'date') . - join(' ', map((split(/-/, $_))[1], sort keys %dates)) . "\n" . - sprintf("%-0${opt_hostwidth}s %-0${opt_diskwidth}s ", 'host', 'disk') . - join(' ', map((split(/-/, $_))[2], sort keys %dates)) . "\n" . - "\n.\n"; +sub row { + my ($host, $disk, @cols) = @_; + $host = substr($host, 0, $opt_hostwidth); + $disk = substr($disk, 0, $opt_diskwidth); + print + sprintf("%-0${opt_hostwidth}s %-0${opt_diskwidth}s ", $host, $disk) . + join(" ", map(sprintf("%-2s ", $_), @cols)) . + "\n"; +} -my $out_format = "format STDOUT =\n" . - "@" . "<" x ($opt_hostwidth - 1) . ' ' . - "@" . "<" x ($opt_diskwidth - 1) . ' ' . - '@> ' x scalar(keys %dates) . "\n" . - join(', ', '$host', '$disk', - map("substr(\$level{\$host}{\$disk}{'$_'},-2)", sort keys %dates)) . "\n" . - ".\n"; +sub fmt_levels { + my ($host, $disk, $date) = @_; + my $levels = $level{$host}{$disk}{$date}; + + # no dumps on this date + $levels = '-' unless defined($levels); + + return substr($levels, -2); +} -eval $top_format; -die $@ if $@; -$^ = 'TOP'; -eval $out_format; -die $@ if $@; +# header +row('', 'date', map((/....(..) .. /x)[0], sort keys %dates)); +row('host', 'disk', map((/.... .. (..)/x)[0], sort keys %dates)); +# body for $host (sort keys %disks) { for $disk (sort keys %{$disks{$host}}) { - write; + row($host, $disk, + map(fmt_levels($host, $disk, $_), sort keys %dates)); } }