#!/usr/bin/perl # check_areca_vols # Nagios/Icinga plugin to check the status of volumes on an # ARECA Raid controller under Linux. Requires cli32/cli64 # to be available -- see the $CLI variable at the top of # the script # # # Written by Joseph Dickson # for AJ BOGGS & CO # # Copyright 2011 by AJ BOGGS & CO # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # where we can expect to find the cli32/cli64 program. This example # assumes that you are granting access to run the cli64 program via # sudo $CLI = '/usr/bin/sudo /usr/sbin/cli64'; eval { my $exit_code = 0; my $primary_info = ""; my $extra_info = ""; $numvols = areca_count_volumes(); if ($numvols == 0) { die "no volumes available to check" } for (my $volid = 1; $volid <= $numvols; $volid++) { $vinfo = areca_get_vol_info($volid); # first lets add to our extra info text $extra_info .= "VOL $$vinfo{id} $$vinfo{state} ($$vinfo{name} $$vinfo{size} $$vinfo{lun}); "; # now let's figure out if this volume's state changes our values if (uc($$vinfo{state}) ne "NORMAL") { if ($exit_code == 0) { $exit_code = 2; $primary_info = "VOL $$vinfo{id} NON-NORMAL ($$vinfo{name} $$vinfo{raidlevel}); "; } } } if ($exit_code == 0) { $primary_info = "OK: $numvols VOLS OK; "; } print $primary_info; print $extra_info; exit($exit_code); }; if (my $excep = $@) { print "CHECK_FAIL: $excep\n"; exit(3); } # shouldn't make it here, but if we do, let's exit non-zero exit(3); # function: areca_get_vol_info # arguments: volid # # returns a hashref full of volume info about the specified volume id.. # should be executed within an eval, as it can throw an exception # sub areca_get_vol_info { my $volid = shift; my $vinfo = { }; $$vinfo{id} = $volid; open(CLI_PIPE, "$CLI vsf info vol=$volid|") || die "couldn't open pipe"; while () { if (/^Volume Set Name : (.+)$/) { $$vinfo{name} = $1; } if (/^Raid Set Name : (.+)$/) { $$vinfo{raidset} = $1; } if (/^Volume Capacity : (.+)$/) { $$vinfo{size} = $1; } if (/^SCSI Ch\/Id\/Lun : (.+)$/) { $$vinfo{lun} = $1; } if (/^Raid Level : (.+)$/) { $$vinfo{raidlevel} = $1; } if (/^Member Disks : (.+)$/) { $$vinfo{numdisks} = $1; } if (/^Volume State : (.+)$/) { $$vinfo{state} = $1; } } close(CLI_PIPE); return $vinfo; } # function: areca_count_volumes # arguments: none # # returns the number of volumes counted # # this routine does a vsf info command and counts the number of lines # in between the ==== lines to determine the number of volumes on # a controller. Can throw a text exception. sub areca_count_volumes { open(CLI_PIPE, "$CLI vsf info|") || die "couldn't open pipe"; my $counting = 0; my $count = 0; while () { if (/^========/) { if ($counting) { $counting = 0; } else { $counting = 1; } } else { $count++ if $counting; } } close(CLI_PIPE); return $count; }