=================================================================== RCS file: /cvs/nagios/check_bioctl/check_bioctl,v retrieving revision 1.10 retrieving revision 1.16 diff -u -r1.10 -r1.16 --- nagios/check_bioctl/check_bioctl 2009/11/12 18:54:38 1.10 +++ nagios/check_bioctl/check_bioctl 2009/11/23 22:25:15 1.16 @@ -1,5 +1,5 @@ #!/usr/bin/perl -T -# $RedRiver: check_bioctl,v 1.9 2009/11/09 20:22:43 andrew Exp $ +# $RedRiver: check_bioctl,v 1.15 2009/11/23 22:24:45 andrew Exp $ ######################################################################## # check_bioctl *** A nagios check for OpenBSD bioctl # @@ -8,9 +8,9 @@ use strict; use warnings; -%ENV = (); +local %ENV = (); -use constant NAGIOS_OUTPUT => 1; +my $NAGIOS_OUTPUT = 1; my $License = <<'EOL'; Copyright (c) 2009 Andrew Fresh @@ -27,22 +27,23 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. EOL -my $PROGNAME = "check_bioctl"; +my $PROGNAME = 'check_bioctl'; my $BIOCTL = '/sbin/bioctl'; use POSIX; my $PREFIX; + BEGIN { ## no critic 'warnings' no warnings 'uninitialized'; - $PREFIX = "${PREFIX}" || '/usr/local'; # Magic for OpenBSD ports tree + $PREFIX = "${PREFIX}" || '/usr/local'; # Magic for OpenBSD ports tree } use lib $PREFIX . '/libexec/nagios'; use utils qw($TIMEOUT %ERRORS &support); $SIG{'ALRM'} = sub { - print ("ERROR: $PROGNAME timeout\n"); - exit $ERRORS{'UNKNOWN'}; + print "ERROR: $PROGNAME timeout\n"; + exit $ERRORS{'UNKNOWN'}; }; alarm($TIMEOUT); @@ -63,8 +64,6 @@ Invalid => 'CRITICAL', ); -my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK -my %states; # This stores the count of states; my @devices; my $opt_h; my $opt_V; @@ -82,43 +81,103 @@ } if ($opt_V) { - print_revision( $PROGNAME, '$Revision: 1.10 $ ' ); + print_revision( $PROGNAME, '$Revision: 1.16 $ ' ); exit $ERRORS{'OK'}; } -if ( $opt_h || not @devices ) { +if ( $opt_h || !@devices ) { print_help(); exit $ERRORS{'OK'}; } -my %VOLUMES; -foreach my $device (@devices) { - open my $bioctl, '-|', $BIOCTL, $device or die "Couldn't open bioctl: $!"; - my $volume_id; +my %VOLUMES = read_bioctl( \@devices ); +my %STATES = check_status( \%VOLUMES ); - while (<$bioctl>) { - chomp; +my $have_results = 0; +my $state = 'OK'; +foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) { + if ( exists $STATES{$error} ) { + $have_results++; + $state = $error if $ERRORS{$state} < $ERRORS{$error}; + if ($NAGIOS_OUTPUT) { + print "$error (" . scalar( @{ $STATES{$error} } ) . ")"; + if ( $error ne 'OK' ) { + print '
'; + print map {" - $_
"} @{ $STATES{$error} }; + } + } + else { + print "$error (" . scalar( @{ $STATES{$error} } ) . "):\n"; + print map {" $_\n"} @{ $STATES{$error} }; + } + } +} +if ( $have_results == 0 ) { + print "No results found\n"; +} +exit $ERRORS{$state}; + +sub read_bioctl { + my ($devices) = @_; + my %volumes; + + foreach my $d ( @{$devices} ) { + open my $bioctl, q{-|}, $BIOCTL, $d + or die "Couldn't open bioctl: $!\n"; + LINE: while ( my $line = <$bioctl> ) { + my ( $i, $item ) = parse_bioctl_line($line); + next LINE if !defined $i; + $volumes{$d}{$i} = $item; + } + ## no critic 'die' + close $bioctl + or die $! + ? "Error closing bioctl pipe: $!\n" + : "Exit status $? from bioctl \n"; + } + + foreach my $d ( keys %volumes ) { + foreach my $i ( keys %{ $volumes{$d} } ) { + my $item = $volumes{$d}{$i}; + if ( $item->{device} =~ /^\d+:\d+/xms ) { + $item->{'volume'} = $volumes{$d}{ $item->{volume_id} }; + } + } + } + + return %volumes; +} + +{ + my $vid; + my $controller; + + sub parse_bioctl_line { + my ($line) = @_; + chomp $line; + # Do these by columns cuZ that is the easiest for now - my @o = unpack( "A6 A1 A11 A15 A7 A9 A*", $_ ); - next if $o[0] eq 'Volume'; + my @o = unpack( "A6 A1 A11 A15 A7 A9 A*", $line ); + return if $o[0] eq 'Volume'; foreach (@o) { - s/^\s+//; - s/\s+$//; + s/^\s+//xms; + s/\s+$//xms; } - my ( $controller, $id, $status, $size, $dev, $details, $name ) = @o; + my ( $c, $id, $status, $size, $dev, $details, $name ) = @o; my $index = $id; - if ($controller) { - $volume_id = $id; + if ($c) { + $vid = $id; + $controller = $c; } else { - $index = "$volume_id.$id"; + $index = "$vid.$id"; } - $VOLUMES{$device}{$index} = { - type => 'volume', + return $index, + { controller => $controller, id => $id, status => $status, @@ -126,69 +185,31 @@ device => $dev, details => $details, name => $name, - }; - - if ( $dev =~ /^\d+:\d+/ ) { - $VOLUMES{$device}{$index}{'volume'} - = $VOLUMES{$device}{$volume_id}; - } - + volume_id => $vid, + }; } - close $bioctl; } -foreach my $device ( sort keys %VOLUMES ) { - foreach my $index ( sort keys %{ $VOLUMES{$device} } ) { - my $cur_state - = $Status_Map{ $VOLUMES{$device}{$index}{'status'} } - ? $Status_Map{ $VOLUMES{$device}{$index}{'status'} } - : 'UNKNOWN'; +sub check_status { + my ($volumes) = @_; - if ( $VOLUMES{$device}{$index}{'device'} =~ /^\d+:\d/ ) { - push @{ $states{$cur_state} }, + my %states; + foreach my $d ( sort keys %{$volumes} ) { + foreach my $i ( sort { $a <=> $b } keys %{ $volumes->{$d} } ) { + my $volume = $volumes->{$d}->{$i}; + my $state = $Status_Map{ $volume->{'status'} } || 'UNKNOWN'; + + push @{ $states{$state} }, sprintf( "%5s %-7s %-11s %s", - $VOLUMES{$device}{$index}{'volume'}{'controller'}, - $VOLUMES{$device}{$index}{'device'}, - $VOLUMES{$device}{$index}{'status'}, - $VOLUMES{$device}{$index}{'name'} + $volume->{'controller'}, $volume->{'device'}, + $volume->{'status'}, $volume->{'name'} ); } - else { - push @{ $states{$cur_state} }, - sprintf( "%5s %-7s %s", - $VOLUMES{$device}{$index}{'controller'}, - $VOLUMES{$device}{$index}{'device'}, - $VOLUMES{$device}{$index}{'status'} ); - } } + return %states; } -my $have_results = 0; -$state = 'OK'; -foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) { - if ( exists $states{$error} ) { - $have_results++; - $state = $error if $ERRORS{$state} < $ERRORS{$error}; - - if (NAGIOS_OUTPUT) { - print "$error (" . scalar( @{ $states{$error} } ) . ")"; - if ( $error ne 'OK' ) { - print '
'; - print map {" - $_
"} @{ $states{$error} }; - } - } - else { - print "$error (" . scalar( @{ $states{$error} } ) . "):\n"; - print map {" $_\n"} @{ $states{$error} }; - } - } -} -if ( $have_results == 0 ) { - print "No results found\n"; -} -exit $ERRORS{$state}; - sub print_help { print <<"EOL"; $PROGNAME plugin for Nagios monitors bioctl on OpenBSD @@ -202,15 +223,18 @@ EOL - print_revision( $PROGNAME, '$Revision: 1.10 $' ); + print_revision( $PROGNAME, '$Revision: 1.16 $' ); print $License; + + return 1; } - sub print_revision { - my ($prog, $rev) = @_; + my ( $prog, $rev ) = @_; $rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms; print "$prog $rev\n"; + + return 1; }