Annotation of nagios/check_bioctl/check_bioctl, Revision 1.23
1.1 andrew 1: #!/usr/bin/perl -T
1.23 ! andrew 2: # $AFresh1: check_bioctl,v 1.22 2017/02/08 17:34:23 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;
1.19 andrew 10: use 5.010;
1.1 andrew 11:
1.11 andrew 12: local %ENV = ();
13:
1.16 andrew 14: my $NAGIOS_OUTPUT = 1;
1.1 andrew 15:
1.9 andrew 16: my $License = <<'EOL';
17: Copyright (c) 2009 Andrew Fresh <andrew@afresh1.com>
18: Permission to use, copy, modify, and distribute this software for any
19: purpose with or without fee is hereby granted, provided that the above
20: copyright notice and this permission notice appear in all copies.
21:
22: THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
23: WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
24: MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
25: ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
27: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
28: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29: EOL
30:
1.11 andrew 31: my $PROGNAME = 'check_bioctl';
1.10 andrew 32: my $BIOCTL = '/sbin/bioctl';
1.22 andrew 33: my @DOAS = ( '/usr/bin/doas', '-n' );
1.10 andrew 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.19 andrew 47: say "ERROR: $PROGNAME timeout";
1.11 andrew 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.2 andrew 69: my @devices;
1.1 andrew 70: my $opt_h;
71: my $opt_V;
72:
73: #Option checking
74: my $status = GetOptions(
1.7 andrew 75: "version|V" => \$opt_V,
76: "help|h" => \$opt_h,
77: "device|d=s" => \@devices,
1.1 andrew 78: );
79:
1.7 andrew 80: if ( $status == 0 ) {
81: print_help();
82: exit $ERRORS{'OK'};
1.1 andrew 83: }
84:
85: if ($opt_V) {
1.19 andrew 86: print_revision();
1.7 andrew 87: exit $ERRORS{'OK'};
1.1 andrew 88: }
89:
1.11 andrew 90: if ( $opt_h || !@devices ) {
1.7 andrew 91: print_help();
92: exit $ERRORS{'OK'};
1.1 andrew 93: }
94:
1.11 andrew 95: my %VOLUMES = read_bioctl( \@devices );
96: my %STATES = check_status( \%VOLUMES );
1.1 andrew 97:
98: my $have_results = 0;
1.15 andrew 99: my $state = 'OK';
1.7 andrew 100: foreach my $error ( sort { $ERRORS{$b} <=> $ERRORS{$a} } keys %ERRORS ) {
1.11 andrew 101: if ( exists $STATES{$error} ) {
1.7 andrew 102: $have_results++;
1.6 andrew 103: $state = $error if $ERRORS{$state} < $ERRORS{$error};
1.5 andrew 104:
1.11 andrew 105: if ($NAGIOS_OUTPUT) {
106: print "$error (" . scalar( @{ $STATES{$error} } ) . ")";
1.8 andrew 107: if ( $error ne 'OK' ) {
1.7 andrew 108: print '<br>';
1.11 andrew 109: print map {" - $_<br>"} @{ $STATES{$error} };
1.7 andrew 110: }
111: }
112: else {
1.11 andrew 113: print "$error (" . scalar( @{ $STATES{$error} } ) . "):\n";
114: print map {" $_\n"} @{ $STATES{$error} };
1.7 andrew 115: }
116: }
1.1 andrew 117: }
1.7 andrew 118: if ( $have_results == 0 ) {
1.19 andrew 119: say 'No results found';
1.1 andrew 120: }
121: exit $ERRORS{$state};
122:
1.23 ! andrew 123: sub fail {
! 124: my ($message) = @_;
! 125: print $message;
! 126: exit $ERRORS{'UNKNOWN'};
! 127: }
! 128:
1.11 andrew 129: sub read_bioctl {
130: my ($devices) = @_;
131: my %volumes;
132:
133: foreach my $d ( @{$devices} ) {
1.22 andrew 134: open my $bioctl, q{-|}, @DOAS, $BIOCTL, $d
1.23 ! andrew 135: or fail("Couldn't open bioctl: $!\n");
1.13 andrew 136: LINE: while ( my $line = <$bioctl> ) {
1.11 andrew 137: my ( $i, $item ) = parse_bioctl_line($line);
1.13 andrew 138: next LINE if !defined $i;
1.11 andrew 139: $volumes{$d}{$i} = $item;
140: }
141: close $bioctl
1.23 ! andrew 142: or fail( $!
1.11 andrew 143: ? "Error closing bioctl pipe: $!\n"
1.23 ! andrew 144: : "Exit status $? from bioctl\n" );
1.11 andrew 145: }
146:
147: foreach my $d ( keys %volumes ) {
148: foreach my $i ( keys %{ $volumes{$d} } ) {
149: my $item = $volumes{$d}{$i};
150: if ( $item->{device} =~ /^\d+:\d+/xms ) {
1.12 andrew 151: $item->{'volume'} = $volumes{$d}{ $item->{volume_id} };
1.11 andrew 152: }
153: }
154: }
155:
156: return %volumes;
157: }
158:
1.19 andrew 159: sub parse_bioctl_line {
160: ($_) = @_;
161: chomp;
162:
163: my @o = map { s/^\s+|\s+$//g; $_ } split;
164: return if $o[0] eq 'Volume';
165:
166: state $vid = '';
167: state $controller;
168:
169: my $index = "$vid.$o[0]";
170: if ( $o[0] !~ /^\d+$/ ) {
171: $controller = shift @o;
172: $vid = $o[0];
173: $index = $vid;
174: }
1.11 andrew 175:
1.19 andrew 176: return $index, {
177: controller => $controller,
178: volume_id => $vid,
179: id => shift @o,
180: status => shift @o,
181: size => shift @o,
182: device => shift @o,
183: name => shift @o,
184: description => join ' ', @o,
185: };
1.11 andrew 186: }
187:
188: sub check_status {
189: my ($volumes) = @_;
190:
191: my %states;
1.15 andrew 192: foreach my $d ( sort keys %{$volumes} ) {
193: foreach my $i ( sort { $a <=> $b } keys %{ $volumes->{$d} } ) {
194: my $volume = $volumes->{$d}->{$i};
195: my $state = $Status_Map{ $volume->{'status'} } || 'UNKNOWN';
196:
197: push @{ $states{$state} },
198: sprintf(
199: "%5s %-7s %-11s %s",
200: $volume->{'controller'}, $volume->{'device'},
201: $volume->{'status'}, $volume->{'name'}
202: );
1.11 andrew 203: }
204: }
205: return %states;
206: }
207:
1.1 andrew 208: sub print_help {
1.9 andrew 209: print <<"EOL";
1.1 andrew 210: $PROGNAME plugin for Nagios monitors bioctl on OpenBSD
1.2 andrew 211: $PROGNAME -d <device> [ -d <device2> [ -d ... ] ]
1.1 andrew 212:
213: Usage:
214: -d, --device=DEVICE
1.3 andrew 215: DEVICE to check. Can be any device that bioctl(8) accepts
1.1 andrew 216: -h (--help) usage help
217: -V (--version) version information
218:
219: EOL
1.7 andrew 220:
1.19 andrew 221: print_revision();
1.9 andrew 222:
223: print $License;
1.11 andrew 224:
225: return 1;
1.1 andrew 226: }
227:
1.9 andrew 228: sub print_revision {
1.23 ! andrew 229: my $rev = '$Revision: 1.22 $';
1.9 andrew 230: $rev =~ s/^\D+([\d\.]+)\D+$/v$1/xms;
231:
1.19 andrew 232: say "$PROGNAME $rev";
1.11 andrew 233:
234: return 1;
1.9 andrew 235: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>