dsa-check-soas: fix error when 0 (or more than 1) records returned
[mirror/dsa-nagios.git] / dsa-nagios-checks / checks / dsa-check-raid-sw
1 #!/usr/bin/perl -w
2 # ------------------------------------------------------------------------------
3 # File Name:            chech_raid.pl
4 # Author:               Thomas Nilsen - Norway
5 # Date:                 14/06/2003
6 # Version:              0.1
7 # Description:          This script will check to see if any software raid
8 #                       devices are down.
9 # Email:                thomas.nilsen@doc-s.co.uk
10 # WWW:                  www.doc-s.co.uk
11 # ------------------------------------------------------------------------------
12 # Copyright 2003 (c) Thomas Nilsen
13 # Credits go to Ethan Galstad for coding Nagios
14 # License GPL
15 # ------------------------------------------------------------------------------
16 # Date          Author          Reason
17 # ----          ------          ------
18 # 2008-03-31    Peter Palfrader Return warning on running resync
19 # 2007-11-07    Peter Palfrader Return unknown if /proc/mdstat does not exist
20 # 05/10/2004    Peter Palfrader Make it work without that 'use util (vars)'
21 # 14/06/2003    TN              Initial Release
22 #                               - Format of mdstat assumed to be "2 line" per
23 #                                 device with [??] on the second line.
24 # ------------------------------------------------------------------------------
25
26 use strict;
27 use warnings;
28 use Getopt::Long;;
29 use vars qw($opt_V $opt_h $opt_t $opt_F $PROGNAME);
30 use lib '/usr/local/nagios/libexec/';
31 my $TIMEOUT=15;
32 my %ERRORS = ( OK => 0, WARNING => 1, CRITICAL => 2, UNKNOWN => -1 );
33
34
35 $PROGNAME="check_raid";
36
37 sub print_help ();
38 sub print_usage ();
39
40 $ENV{'PATH'}='';
41 $ENV{'BASH_ENV'}='';
42 $ENV{'ENV'}='';
43 my ( $line, $stat, $state ,@device, $msg, $status, $timeout);
44
45 $stat="/proc/mdstat";
46
47 #Option checking
48 Getopt::Long::Configure('bundling');
49 $status = GetOptions(
50                 "V"   => \$opt_V, "version"    => \$opt_V,
51                 "h"   => \$opt_h, "help"       => \$opt_h,
52                 "F"   => \$opt_F, "filename"   => \$opt_F,
53                 "t"   => \$opt_t, "timeout"  => \$opt_t);
54 # Version
55 if ($opt_V) {
56         print($PROGNAME,': $Revision: 0.1 $');
57         exit $ERRORS{'OK'};
58 }
59 # Help 
60 if ($opt_h) {
61         print_help();
62         exit $ERRORS{'OK'};
63 }
64 # Filename supplied
65 if ($opt_F) {
66         $opt_F = shift; 
67         $stat = $1 if ($opt_F =~ /^(.*)$/);
68
69         if ( ! -r $stat ) {
70                 print "Invalid mdstat file: $opt_F\n";
71                 exit $ERRORS{'UNKNOWN'};
72         }
73 }
74
75 $timeout = $TIMEOUT;
76 ($opt_t) && ($opt_t =~ /^([0-9]+)$/) && ($timeout = $1);
77
78 # Just in case of problems, let's not hang Nagios
79 $SIG{'ALRM'} = sub {
80         print ("ERROR: No response (alarm)\n");
81         exit $ERRORS{'UNKNOWN'};
82 };
83 alarm($timeout);
84
85 # Start checking the file...
86 open (FH, $stat) or print("UNKNOWN: Cannot open $stat: $!\n"), exit $ERRORS{'UNKNOWN'};
87
88 my @failed = ();
89 my @resyncing = ();
90 my $device = '';
91
92 # Now check the mdstat file..
93 while (<FH>) {
94         $line = $_;
95         if ($line =~ /^(md\S*) /) {
96                 $device = $1;
97         } elsif( $line =~ / \[_|_\]|U_|_U /) {
98                 push @failed, $device;
99         }
100         elsif ( $line =~ / resync /) {
101                 #       [==>..................]  resync = 10.3% (15216320/146994624) finish=2153.2min speed=1018K/sec
102                 my ($percent) = ($line =~ m# resync = ([0-9.]+%)#);
103                 my ($finish)  = ($line =~ m# finish=([0-9.]+min)#);
104                 my ($speed)   = ($line =~ m# speed=([0-9.]+K/sec)#);
105                 push @resyncing, "$device ($percent done, finish in $finish at $speed)";
106         }
107 }
108 close (FH);
109
110 if (scalar @failed > 0) {
111         if (scalar @failed == 1) {
112                 print "CRITICAL - Device $failed[0] has failed.\n";
113         } else {
114                 print "CRITICAL - Devices ".join(", ", @failed)." have failed.\n"
115         };
116         exit $ERRORS{'CRITICAL'};
117 } elsif (scalar @resyncing > 0 ) {
118         print "WARNING: Resyncing: ".(join "; ", @resyncing)."\n";
119         exit $ERRORS{'WARNING'};
120 } else {
121         print "OK - All devices are online\n";
122         exit $ERRORS{'OK'};
123 };
124
125
126 sub print_usage () {
127         print "Usage: $PROGNAME -t <timeout> -F <filename>\n";
128 }
129
130 sub print_help () {
131         print_revision($PROGNAME,'$Revision: 0.1 $');
132         print "Copyright (c) 2003 Thomas Nilsen/Karl DeBisschop\n";
133         print "\n";
134         print_usage();
135         print "Checks the mdstat file for errors on any configured software raid.\n
136 -t ( --timeout=INTEGER)
137         Seconds before script times out (default: 10)\n
138 -F ( --filename=FILE)
139         Full path and name to mdstat file (usually '/proc/mdstat') \n\n";
140 }