#!/usr/bin/perl -w

# by Harry Mangalam <harry.mangalam@uci.edu>
# This is explicitly released into the Public Domain, altho if you use it and extend it, I'd
# appreciate a note.

# typically add this to a daily crontab, like this (without the leading '#' of course.
##m   h   dom mon dow   command
#49  3    *   *   *    /where/you/put/sectorchek.pl

# you'll also need a working 'mutt' to have it mail you.

# Usage:  sectorchek.pl [DEBUG]
# if append 'DEBUG', it will spew some debugging info to the 
# Assumptions:  only supports recentn 3ware controllers; only 1 3ware controller per host.
$DEBUG = 0;
$ARG = shift;
if ((defined $ARG) && ($ARG eq "DEBUG")) {$DEBUG = 1;}

$SILENT = "YES"; # change to NO if you want reports even if no bad news

$RECIPS = "recipient_1\@uci.edu,recipient_2\@uci.edu,recipient_3\@uci.edu"; # need the '\@' notation
$HOST = `hostname -s`; chomp $HOST;
$TWCLI = "/opt/3ware/CLI/tw_cli"; # or wherever you installed it


# the following shouldn't be changed if the controller is a recent 3ware.
# tested on 9570 and 9650SE if it does fail to detect the right controller, 
# you'll have to make local corrections

# set the controller # 
$CN = `$TWCLI show | grep ^c |cut -f1 -d' '`; chomp $CN;


# processed output of the tw_cli cmd to provide a string with all the ports occupied
$RAW_TW = `$TWCLI /$CN show all |grep ^p | cut -f1 -d' '|tr '\n' ' '`;
@PORTS = split(/ /, $RAW_TW);  # and put them in an array for easy iteration
$BODY = "TYPE\tHost\tPort\tStatus/# Rallocs\n";

$ERRCNT = 0; # will record the number of disks with sector errors
foreach $disk (@PORTS) {
	if ($DEBUG) { print STDERR "$disk ";}  # debugging assist
	$str =  `$TWCLI /$CN/$disk show status rasect`;  # get the port info
#	print STDERR "$TWCLI /${CN}/${disk} show rasect\n";
	@seplnes = split (/\n/, $str);
	@stat = split (/ = /, $seplnes[0]); # test disk status
	if ($stat[1] !~ /OK/) {
		$ERRCNT++; $BODY .= "STATUS:\t$HOST\t$disk\t$stat[1]\n"; 
	} 
	@l = split (/ = /, $seplnes[1]); # test # of realloc sectors
	if ($l[1] != 0) {
		$ERRCNT++; $BODY .= "RALLOC:$HOST\t$disk\t$l[1]\n";
	}
}

# and send off the error report to the $RECIPS
if ($ERRCNT > 0) {
	$SUBJ = "$HOST: !!WARN!![$ERRCNT] DISK w/ REALLOC SECTORS DETECTED";
	system ("echo \"$BODY\" |mutt -s \"$SUBJ\" $RECIPS");
} elsif ($SILENT eq "NO") {
	$SUBJ = "$HOST: INFO: NO DISK ERRORS DETECTED";
	system ("echo \"NO ERRORS DETECTED\" |mutt -s \"$SUBJ\" $RECIPS");
}
if ($DEBUG) { print STDERR "\n\nSummary Info [$ERRCNT] disks found with sector problems\n$BODY\n\n";} # for interactive use
