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