#!/usr/bin/perl -T # $RedRiver: check_bioctl,v 1.6 2009/11/09 17:58:29 andrew Exp $ ######################################################################## # check_bioctl *** A nagios check for OpenBSD bioctl # # 2006.07.26 #*#*# andrew fresh ######################################################################## # TODO: # Really need real documentation. ######################################################################## use strict; use warnings; %ENV = (); use constant NAGIOS_OUTPUT => 1; use POSIX; use lib "/usr/local/libexec/nagios"; use utils qw($TIMEOUT %ERRORS &print_revision &support); use Getopt::Long; Getopt::Long::Configure('bundling'); my $PROGNAME = "check_bioctl"; my $BIOCTL = '/sbin/bioctl'; # This maps the status we get from bioctl to something nagios can use my %Status_Map = ( Online => 'OK', Offline => 'CRITICAL', Degraded => 'CRITICAL', Failed => 'CRITICAL', Building => 'WARNING', Rebuild => 'WARNING', 'Hot spare' => 'OK', Unused => 'OK', Scrubbing => 'WARNING', 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; #Option checking my $status = GetOptions( "version|V" => \$opt_V, "help|h" => \$opt_h, "device|d=s" => \@devices, ); if ( $status == 0 ) { print_help(); exit $ERRORS{'OK'}; } if ($opt_V) { print_revision( $PROGNAME, '$Revision: 1.7 $ ' ); exit $ERRORS{'OK'}; } if ( $opt_h || not @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; while (<$bioctl>) { chomp; # 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'; foreach (@o) { s/^\s+//; s/\s+$//; } my ( $controller, $id, $status, $size, $dev, $details, $name ) = @o; my $index = $id; if ($controller) { $volume_id = $id; } else { $index = "$volume_id.$id"; } $VOLUMES{$device}{$index} = { type => 'volume', controller => $controller, id => $id, status => $status, size => $size, device => $dev, details => $details, name => $name, }; if ( $dev =~ /^\d+:\d+/ ) { $VOLUMES{$device}{$index}{'volume'} = $VOLUMES{$device}{$volume_id}; } } 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'; if ( $VOLUMES{$device}{$index}{'device'} =~ /^\d+:\d/ ) { push @{ $states{$cur_state} }, sprintf( "%5s %-7s %-11s %s", $VOLUMES{$device}{$index}{'volume'}{'controller'}, $VOLUMES{$device}{$index}{'device'}, $VOLUMES{$device}{$index}{'status'}, $VOLUMES{$device}{$index}{'name'} ); } else { push @{ $states{$cur_state} }, sprintf( "%5s %-7s %s", $VOLUMES{$device}{$index}{'controller'}, $VOLUMES{$device}{$index}{'device'}, $VOLUMES{$device}{$index}{'status'} ); } } } my $have_results = 0; 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} } ) . ")"; unless ( $error eq '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 < [ -d [ -d ... ] ] Usage: -d, --device=DEVICE DEVICE to check. Can be any device that bioctl(8) accepts -h (--help) usage help -V (--version) version information EOL print_revision( $PROGNAME, '$Revision: 1.7 $' ); }