[BACK]Return to check_bioctl CVS log [TXT][DIR] Up to [local] / nagios / check_bioctl

Annotation of nagios/check_bioctl/check_bioctl, Revision 1.11

1.1       andrew      1: #!/usr/bin/perl -T
1.11    ! andrew      2: # $RedRiver: check_bioctl,v 1.10 2009/11/12 18:54:38 andrew Exp $
1.1       andrew      3: ########################################################################
                      4: # check_bioctl *** A nagios check for OpenBSD bioctl
1.7       andrew      5: #
1.9       andrew      6: # 2006.07.26 #*#*# andrew fresh <andrew@afresh1.com>
1.1       andrew      7: ########################################################################
                      8: use strict;
                      9: use warnings;
                     10:
1.11    ! andrew     11: use 5.010;
1.1       andrew     12:
1.11    ! andrew     13: local %ENV = ();
        !            14:
        !            15: my $NAGIOS_OUTPUT => 1;
1.1       andrew     16:
1.9       andrew     17: my $License = <<'EOL';
                     18: Copyright (c) 2009 Andrew Fresh <andrew@afresh1.com>
                     19: Permission to use, copy, modify, and distribute this software for any
                     20: purpose with or without fee is hereby granted, provided that the above
                     21: copyright notice and this permission notice appear in all copies.
                     22:
                     23: THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     24: WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     25: MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     26: ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     27: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     28: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     29: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     30: EOL
                     31:
1.11    ! andrew     32: my $PROGNAME = 'check_bioctl';
1.10      andrew     33: my $BIOCTL   = '/sbin/bioctl';
                     34:
1.1       andrew     35: use POSIX;
1.10      andrew     36: my $PREFIX;
1.11    ! andrew     37:
1.10      andrew     38: BEGIN {
                     39:     ## no critic 'warnings'
                     40:     no warnings 'uninitialized';
1.11    ! andrew     41:     $PREFIX = "${PREFIX}" || '/usr/local';    # Magic for OpenBSD ports tree
1.10      andrew     42: }
                     43: use lib $PREFIX . '/libexec/nagios';
1.9       andrew     44: use utils qw($TIMEOUT %ERRORS &support);
1.1       andrew     45:
1.10      andrew     46: $SIG{'ALRM'} = sub {
1.11    ! andrew     47:     say "ERROR: $PROGNAME timeout";
        !            48:     exit $ERRORS{'UNKNOWN'};
1.10      andrew     49: };
                     50: alarm($TIMEOUT);
                     51:
1.1       andrew     52: use Getopt::Long;
                     53: Getopt::Long::Configure('bundling');
                     54:
1.3       andrew     55: # This maps the status we get from bioctl to something nagios can use
1.1       andrew     56: my %Status_Map = (
1.7       andrew     57:     Online      => 'OK',
                     58:     Offline     => 'CRITICAL',
                     59:     Degraded    => 'CRITICAL',
                     60:     Failed      => 'CRITICAL',
                     61:     Building    => 'WARNING',
                     62:     Rebuild     => 'WARNING',
                     63:     'Hot spare' => 'OK',
                     64:     Unused      => 'OK',
                     65:     Scrubbing   => 'WARNING',
                     66:     Invalid     => 'CRITICAL',
1.1       andrew     67: );
                     68:
1.7       andrew     69: my $state = 'UNKNOWN';    # tells whether the it is warning, critical, or OK
1.2       andrew     70: my @devices;
1.1       andrew     71: my $opt_h;
                     72: my $opt_V;
                     73:
                     74: #Option checking
                     75: my $status = GetOptions(
1.7       andrew     76:     "version|V"  => \$opt_V,
                     77:     "help|h"     => \$opt_h,
                     78:     "device|d=s" => \@devices,
1.1       andrew     79: );
                     80:
1.7       andrew     81: if ( $status == 0 ) {
                     82:     print_help();
                     83:     exit $ERRORS{'OK'};
1.1       andrew     84: }
                     85:
                     86: if ($opt_V) {
1.11    ! andrew     87:     print_revision( $PROGNAME, '$Revision: 1.10 $ ' );
1.7       andrew     88:     exit $ERRORS{'OK'};
1.1       andrew     89: }
                     90:
1.11    ! andrew     91: if ( $opt_h || !@devices ) {
1.7       andrew     92:     print_help();
                     93:     exit $ERRORS{'OK'};
1.1       andrew     94: }
                     95:
1.11    ! andrew     96: my %VOLUMES = read_bioctl( \@devices );
        !            97: my %STATES  = check_status( \%VOLUMES );
1.1       andrew     98:
                     99: my $have_results = 0;
1.8       andrew    100: $state = 'OK';
1.7       andrew    101: foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) {
1.11    ! andrew    102:     if ( exists $STATES{$error} ) {
1.7       andrew    103:         $have_results++;
1.6       andrew    104:         $state = $error if $ERRORS{$state} < $ERRORS{$error};
1.5       andrew    105:
1.11    ! andrew    106:         if ($NAGIOS_OUTPUT) {
        !           107:             print "$error (" . scalar( @{ $STATES{$error} } ) . ")";
1.8       andrew    108:             if ( $error ne 'OK' ) {
1.7       andrew    109:                 print '<br>';
1.11    ! andrew    110:                 print map {" - $_<br>"} @{ $STATES{$error} };
1.7       andrew    111:             }
                    112:         }
                    113:         else {
1.11    ! andrew    114:             print "$error (" . scalar( @{ $STATES{$error} } ) . "):\n";
        !           115:             print map {"    $_\n"} @{ $STATES{$error} };
1.7       andrew    116:         }
                    117:     }
1.1       andrew    118: }
1.7       andrew    119: if ( $have_results == 0 ) {
                    120:     print "No results found\n";
1.1       andrew    121: }
                    122: exit $ERRORS{$state};
                    123:
1.11    ! andrew    124: sub read_bioctl {
        !           125:     my ($devices) = @_;
        !           126:     my %volumes;
        !           127:
        !           128:     foreach my $d ( @{$devices} ) {
        !           129:         open my $bioctl, q{-|}, $BIOCTL, $d
        !           130:             or die "Couldn't open bioctl: $!\n";
        !           131:         while ( my $line = <$bioctl> ) {
        !           132:             my ( $i, $item ) = parse_bioctl_line($line);
        !           133:             $volumes{$d}{$i} = $item;
        !           134:         }
        !           135:         ## no critic 'die'
        !           136:         close $bioctl
        !           137:             or die $!
        !           138:             ? "Error closing bioctl pipe: $!\n"
        !           139:             : "Exit status $? from bioctl \n";
        !           140:     }
        !           141:
        !           142:     foreach my $d ( keys %volumes ) {
        !           143:         foreach my $i ( keys %{ $volumes{$d} } ) {
        !           144:             my $item = $volumes{$d}{$i};
        !           145:             if ( $item->{device} =~ /^\d+:\d+/xms ) {
        !           146:                 $item->{'volume'} = $volumes{$d}{ $i->{volume_id} };
        !           147:             }
        !           148:         }
        !           149:     }
        !           150:
        !           151:     return %volumes;
        !           152: }
        !           153:
        !           154: sub parse_bioctl_line {
        !           155:     my ($line) = @_;
        !           156:     state $vid;
        !           157:     chomp $line;
        !           158:
        !           159:     # Do these by columns cuZ that is the easiest for now
        !           160:     my @o = unpack( "A6 A1 A11 A15 A7 A9 A*", $line );
        !           161:     next if $o[0] eq 'Volume';
        !           162:
        !           163:     foreach (@o) {
        !           164:         s/^\s+//xms;
        !           165:         s/\s+$//xms;
        !           166:     }
        !           167:
        !           168:     my ( $controller, $id, $status, $size, $dev, $details, $name ) = @o;
        !           169:     my $index = $id;
        !           170:     if ($controller) {
        !           171:         $vid = $id;
        !           172:     }
        !           173:     else {
        !           174:         $index = "$vid.$id";
        !           175:     }
        !           176:
        !           177:     my %item = (
        !           178:         type       => 'volume',
        !           179:         controller => $controller,
        !           180:         id         => $id,
        !           181:         status     => $status,
        !           182:         size       => $size,
        !           183:         device     => $dev,
        !           184:         details    => $details,
        !           185:         name       => $name,
        !           186:         volume_id  => $vid,
        !           187:     );
        !           188:
        !           189:     return $index, \%item;
        !           190: }
        !           191:
        !           192: sub check_status {
        !           193:     my ($volumes) = @_;
        !           194:
        !           195:     my %states;
        !           196:     foreach my $device ( sort keys %{$volumes} ) {
        !           197:         foreach my $index ( sort keys %{ $volumes->{$device} } ) {
        !           198:             my $cur_volume = $volumes->{$device}->{$index};
        !           199:             my $cur_state  = $Status_Map{ $cur_volume->{'status'} }
        !           200:                 || 'UNKNOWN';
        !           201:
        !           202:             if ( $cur_volume->{'device'} =~ /^\d+:\d/xms ) {
        !           203:                 push @{ $states{$cur_state} },
        !           204:                     sprintf(
        !           205:                     "%5s %-7s %-11s %s",
        !           206:                     $cur_volume->{'volume'}{'controller'},
        !           207:                     $cur_volume->{'device'},
        !           208:                     $cur_volume->{'status'},
        !           209:                     $cur_volume->{'name'}
        !           210:                     );
        !           211:             }
        !           212:             else {
        !           213:                 push @{ $states{$cur_state} },
        !           214:                     sprintf( "%5s %-7s %s",
        !           215:                     $cur_volume->{'controller'},
        !           216:                     $cur_volume->{'device'},
        !           217:                     $cur_volume->{'status'} );
        !           218:             }
        !           219:         }
        !           220:     }
        !           221:     return %states;
        !           222: }
        !           223:
1.1       andrew    224: sub print_help {
1.9       andrew    225:     print <<"EOL";
1.1       andrew    226: $PROGNAME plugin for Nagios monitors bioctl on OpenBSD
1.2       andrew    227:     $PROGNAME -d <device> [ -d <device2> [ -d ... ] ]
1.1       andrew    228:
                    229: Usage:
                    230:     -d, --device=DEVICE
1.3       andrew    231:         DEVICE to check.  Can be any device that bioctl(8) accepts
1.1       andrew    232:     -h (--help)       usage help
                    233:        -V (--version)    version information
                    234:
                    235: EOL
1.7       andrew    236:
1.11    ! andrew    237:     print_revision( $PROGNAME, '$Revision: 1.10 $' );
1.9       andrew    238:
                    239:     print $License;
1.11    ! andrew    240:
        !           241:     return 1;
1.1       andrew    242: }
                    243:
1.9       andrew    244: sub print_revision {
1.11    ! andrew    245:     my ( $prog, $rev ) = @_;
1.9       andrew    246:     $rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms;
                    247:
1.11    ! andrew    248:     say "$prog $rev";
        !           249:
        !           250:     return 1;
1.9       andrew    251: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>