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

Diff for /nagios/check_bioctl/check_bioctl between version 1.2 and 1.14

version 1.2, 2006/07/27 02:08:13 version 1.14, 2009/11/23 21:58:04
Line 1 
Line 1 
 #!/usr/bin/perl -T  #!/usr/bin/perl -T
 # $RedRiver: check_bioctl,v 1.1 2006/07/27 00:02:43 andrew Exp $  # $RedRiver: check_bioctl,v 1.13 2009/11/23 21:57:31 andrew Exp $
 ########################################################################  ########################################################################
 # check_bioctl *** A nagios check for OpenBSD bioctl  # check_bioctl *** A nagios check for OpenBSD bioctl
 #  #
 # 2006.07.26 #*#*# andrew fresh <andrew@mad-techies.org>  # 2006.07.26 #*#*# andrew fresh <andrew@afresh1.com>
 ########################################################################  ########################################################################
 # TODO:  
 #   Really need real documentation.  
 ########################################################################  
 use strict;  use strict;
 use warnings;  use warnings;
   
 #use Data::Dumper;  local %ENV = ();
   
 %ENV = ();  my $NAGIOS_OUTPUT = 1;
   
 use constant NAGIOS_OUTPUT => 1;  my $License = <<'EOL';
   Copyright (c) 2009 Andrew Fresh <andrew@afresh1.com>
   Permission to use, copy, modify, and distribute this software for any
   purpose with or without fee is hereby granted, provided that the above
   copyright notice and this permission notice appear in all copies.
   
   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   EOL
   
   my $PROGNAME = 'check_bioctl';
   my $BIOCTL   = '/sbin/bioctl';
   
 use POSIX;  use POSIX;
 use lib "/usr/local/libexec/nagios";  my $PREFIX;
 use utils qw($TIMEOUT %ERRORS &print_revision &support);  
   
   BEGIN {
       ## no critic 'warnings'
       no warnings 'uninitialized';
       $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'};
   };
   alarm($TIMEOUT);
   
 use Getopt::Long;  use Getopt::Long;
 Getopt::Long::Configure('bundling');  Getopt::Long::Configure('bundling');
   
 my $PROGNAME = "check_bioctl";  # This maps the status we get from bioctl to something nagios can use
 my $BIOCTL = '/sbin/bioctl';  
   
 my %Status_Map = (  my %Status_Map = (
         Online      => 'OK',      Online      => 'OK',
         Offline     => 'WARNING',      Offline     => 'CRITICAL',
         Degraded    => 'CRITICAL',      Degraded    => 'CRITICAL',
         Failed      => 'CRITICAL',      Failed      => 'CRITICAL',
         Building    => 'WARNING',      Building    => 'WARNING',
         Rebuild     => 'WARNING',      Rebuild     => 'WARNING',
         'Hot spare' => 'OK',      'Hot spare' => 'OK',
         Unused      => 'OK',      Unused      => 'OK',
         Scrubbing   => 'WARNING',      Scrubbing   => 'WARNING',
         Invalid     => 'CRITICAL',      Invalid     => 'CRITICAL',
 );  );
   
   my $state = 'UNKNOWN';    # tells whether the it is warning, critical, or OK
 my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK  
 my %states; # This stores the count of states;  
 my @devices;  my @devices;
 my $opt_h;  my $opt_h;
 my $opt_V;  my $opt_V;
   
 #Option checking  #Option checking
 my $status = GetOptions(  my $status = GetOptions(
         "version|V"    => \$opt_V,      "version|V"  => \$opt_V,
         "help|h"       => \$opt_h,      "help|h"     => \$opt_h,
         "device|d=s"   => \@devices,      "device|d=s" => \@devices,
 );  );
   
 if ($status == 0) {  if ( $status == 0 ) {
         print_help() ;      print_help();
         exit $ERRORS{'OK'};      exit $ERRORS{'OK'};
 }  }
   
 if ($opt_V) {  if ($opt_V) {
         print_revision($PROGNAME,'$Revision$ ');      print_revision( $PROGNAME, '$Revision$ ' );
         exit $ERRORS{'OK'};      exit $ERRORS{'OK'};
 }  }
   
 if ($opt_h || not @devices) {  if ( $opt_h || !@devices ) {
         print_help();      print_help();
         exit $ERRORS{'OK'};      exit $ERRORS{'OK'};
 }  }
   
 my %VOLUMES;  my %VOLUMES = read_bioctl( \@devices );
 foreach my $device (@devices) {  my %STATES  = check_status( \%VOLUMES );
         open my $bioctl, "-|", $BIOCTL, $device or die "Couldn't open bioctl: $!";  
         my ($controller, $volume_id);  
   
         while (<$bioctl>) {  my $have_results = 0;
                 chomp;  $state = 'OK';
                 # Do these by columns cuZ that is the easiest for now  foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) {
                 # Volume  Status     Size           Device      if ( exists $STATES{$error} ) {
                 my @o = unpack("A6 A1 A11 A15 A7 A9 A*",  $_);          $have_results++;
                 next if $o[0] eq 'Volume';          $state = $error if $ERRORS{$state} < $ERRORS{$error};
   
                 foreach (@o) {          if ($NAGIOS_OUTPUT) {
                         s/^\s+//;              print "$error (" . scalar( @{ $STATES{$error} } ) . ")";
                         s/\s+$//;              if ( $error ne 'OK' ) {
                 }                  print '<br>';
                   print map {" - $_<br>"} @{ $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};
   
                 #print Dumper \@o;  sub read_bioctl {
       my ($devices) = @_;
       my %volumes;
   
                 my ($c, $id, $status, $size, $dev, $details, $name) = @o;      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";
       }
   
                 my $index = $id;      foreach my $d ( keys %volumes ) {
                 if ($c) {          foreach my $i ( keys %{ $volumes{$d} } ) {
                         $controller = $c;              my $item = $volumes{$d}{$i};
                         $volume_id  = $id;              if ( $item->{device} =~ /^\d+:\d+/xms ) {
                 } else {                  $item->{'volume'} = $volumes{$d}{ $item->{volume_id} };
                         $index = "$volume_id.$id";              }
                 }          }
       }
   
                 $VOLUMES{$controller}{$index} = {      return %volumes;
                         type       => 'volume',  }
                         controller => $controller,  
                         id         => $id,  
                         status     => $status,  
                         size       => $size,  
                         device     => $dev,  
                         details    => $details,  
                         name       => $name,  
                 };  
   
                 if ($dev =~ /^\d+:\d+/) {  {
                         $VOLUMES{$controller}{$index}{'volume'} =      my $vid;
                                 $VOLUMES{$controller}{$volume_id};  
                 }  
   
         }      sub parse_bioctl_line {
         close $bioctl;          my ($line) = @_;
 }          chomp $line;
   
 #print Dumper \%VOLUMES;          # Do these by columns cuZ that is the easiest for now
           my @o = unpack( "A6 A1 A11 A15 A7 A9 A*", $line );
           return if $o[0] eq 'Volume';
   
 foreach my $controller (sort keys %VOLUMES) {          foreach (@o) {
         foreach my $index (sort keys %{ $VOLUMES{$controller} }) {              s/^\s+//xms;
                 my $cur_state = $Status_Map{ $VOLUMES{$controller}{$index}{'status'} } ?              s/\s+$//xms;
                         $Status_Map{ $VOLUMES{$controller}{$index}{'status'} } :          }
                         'UNKNOWN';  
   
                 if ($VOLUMES{$controller}{$index}{'device'} =~ /^\d+:\d/) {          my ( $controller, $id, $status, $size, $dev, $details, $name ) = @o;
                         push @{ $states{$cur_state} }, sprintf("%5s %-7s %-11s %s",          my $index = $id;
                                 $VOLUMES{$controller}{$index}{'volume'}{'controller'},          if ($controller) {
                                 $VOLUMES{$controller}{$index}{'device'},              $vid = $id;
                                 $VOLUMES{$controller}{$index}{'status'},          }
                                 $VOLUMES{$controller}{$index}{'name'}          else {
                         );              $index = "$vid.$id";
                 } else {          }
                         push @{ $states{$cur_state} }, sprintf("%5s %-7s %s",  
                                 $VOLUMES{$controller}{$index}{'controller'},          my %item = (
                                 $VOLUMES{$controller}{$index}{'device'},              type       => 'volume',
                                 $VOLUMES{$controller}{$index}{'status'}              controller => $controller,
                         );              id         => $id,
                 }              status     => $status,
         }              size       => $size,
               device     => $dev,
               details    => $details,
               name       => $name,
               volume_id  => $vid,
           );
   
           return $index, \%item;
       }
 }  }
   
   sub check_status {
       my ($volumes) = @_;
   
 #print Dumper \%states;      my %states;
       foreach my $device ( sort keys %{$volumes} ) {
           foreach my $index ( sort keys %{ $volumes->{$device} } ) {
               my $cur_volume = $volumes->{$device}->{$index};
               my $cur_state  = $Status_Map{ $cur_volume->{'status'} }
                   || 'UNKNOWN';
   
 $state = 'OK';              if ( $cur_volume->{'device'} =~ /^\d+:\d/xms ) {
 my $have_results = 0;                  push @{ $states{$cur_state} },
 foreach my $error (sort { $ERRORS{$a} <=> $ERRORS{$b} } keys %ERRORS) {                      sprintf(
         if (exists $states{$error}) {                      "%5s %-7s %-11s %s",
                 $have_results++;                      $cur_volume->{'volume'}{'controller'},
                 $state = $error;                      $cur_volume->{'device'},
         }                      $cur_volume->{'status'},
                       $cur_volume->{'name'}
                       );
               }
               else {
                   push @{ $states{$cur_state} },
                       sprintf( "%5s %-7s %s",
                       $cur_volume->{'controller'},
                       $cur_volume->{'device'},
                       $cur_volume->{'status'} );
               }
           }
       }
       return %states;
 }  }
 foreach my $error (sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS) {  
         if (exists $states{$error}) {  
                 if (NAGIOS_OUTPUT) {  
                         print "$error (" . scalar(@{ $states{ $error } }) . ")";  
                         unless ($error eq 'OK') {  
                                 print '<br>';  
                                 print map { " - $_<br>" } @{ $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 {  sub print_help {
         print <<EOL;      print <<"EOL";
 $PROGNAME plugin for Nagios monitors bioctl on OpenBSD  $PROGNAME plugin for Nagios monitors bioctl on OpenBSD
     $PROGNAME -d <device> [ -d <device2> [ -d ... ] ]      $PROGNAME -d <device> [ -d <device2> [ -d ... ] ]
   
 Usage:  Usage:
     -d, --device=DEVICE      -d, --device=DEVICE
         DEVICE to check.  Can either be a disk, as in sd0          DEVICE to check.  Can be any device that bioctl(8) accepts
                 or a raid card like ami0  
     -h (--help)       usage help      -h (--help)       usage help
         -V (--version)    version information          -V (--version)    version information
   
 EOL  EOL
   
         print_revision($PROGNAME, '$Revision$');      print_revision( $PROGNAME, '$Revision$' );
   
       print $License;
   
       return 1;
 }  }
   
   sub print_revision {
       my ( $prog, $rev ) = @_;
       $rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms;
   
       print "$prog $rev\n";
   
       return 1;
   }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.14

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