#!/usr/bin/perl -w # # Copyright (c) 2004 # Chris Adams # ######################################################################## # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. ######################################################################## # # Check the status of LSI MegaRAID logical and physical drives. # The state is stored in /var/run/megacheck.state; if this is called # non-interactively (i.e. from a cron job) and the state has not changed, # nothing will be output. # # History: # 1.0 - 2004-09-16 # initial version # use strict; my $path = "/proc/megaraid"; my $state = "/var/run/megacheck.state"; my $exit = 0; # Get old state (assume OKAY on first run or after a reboot) my $old = "OKAY"; if (-f $state) { open (STATE, $state) or die "open($state): $!\n"; $old = join ("", ); close (STATE); } # Get new state my $new = ""; opendir (MEGA, $path) or die "opendir($path): $!\n"; while (defined (my $hba = readdir (MEGA))) { next if ($hba =~ /^\.{1,2}$/); my $hpath = $path . "/" . $hba; # Check each adapter opendir (HBA, $hpath) or die "opendir($hpath): $!\n"; while (defined (my $f = readdir (HBA))) { my $fpath = $hpath . "/" . $f; if ($f =~ /^diskdrives-ch(\d+)$/) { # Check physical drives my $chan = $1; open (CH, $fpath) or die "open($fpath): $!\n"; while () { if (/ Id: (\d+) State: (\S+)/) { my $id = $1; my $state = $2; if ($state ne "Online.") { $new .= "Disk problem: " . $hba . " chan " . $chan . " id " . $id . ": state " . $state . "\n"; $exit ++; } } } close (CH); } elsif ($f =~ /^raiddrives-\d+-\d+$/) { # Check logical drives open (RD, $fpath) or die "open($fpath): $!\n"; while () { if (/^Logical drive: (\d+):, state: (\S+)/) { my $drive = $1; my $state = $2; $state =~ s/[,\.].*$//; if ($state ne "optimal") { $new .= "RAIDdrive problem: " . $hba . " drive " . $drive . ": state " . $state . "\n"; $exit ++; } } } close (RD); } } closedir (HBA); } closedir (MEGA); $new ||= "OKAY\n"; # Check state if ($old eq $new) { # No change, only print when run from a terminal print $new if (-t STDOUT); exit $exit; } # State changed, save and print it print "MegaRAID state changed from:\n"; print " ", join ("\n ", split (/\n/, $old)), "\n"; print "to:\n"; print " ", join ("\n ", split (/\n/, $new)), "\n"; open (STATE, "> $state") or die "open(>$state): $!\n"; print STATE $new; close (STATE); exit $exit;