#!/usr/bin/perl

# Script perl permettant de checker le status du RAID et des disques.
# 
# Ce script parse l'output de la commande "/usr/local/sbin/megarc -dispCfg -a0"
# pour obtenir les informations interessantes. Ces informations sont ensuite
# écrites dans un fichier /var/tmp/raid.status qui sera lu par snmpd.
#
# On ne peut pas directement appeler ce script par snmpd car le temps d'execution
# est élevé (~6-8 secondes) ce qui provoquerait le timeout des requetes SNMP.
#
# 2005.07.12 - Yann Grossel
#

use strict;
use warnings;

##
## A CHANGER PAR LE REPERTOIRE WEB DU SERVEUR
##
my $status = '/var/www/raid.status';
##
##

die "/proc/devices is not readable !\n" unless -r '/proc/devices';
die "/usr/local/sbin/megarc is missing or not executable !\n" unless -x '/usr/local/sbin/megarc';

my $major;

open F, '/proc/devices' or die "Can't open /proc/devices: $!\n";

while (<F>) { $major = $1, last if m/\s*(\d+)\s+megadev/o; }

close F;

die "'megadev' is not present in /proc/devices !\n" unless defined($major);

my @s;

@s = stat '/dev/megadev0';

if (@s)
{
	undef @s unless (($s[6] & 0xff) == 0 and ($s[6] >> 8) == $major);
}

if (not @s)
{
	print "Recreating device /dev/megadev0...\n";
	system("/bin/mknod /dev/megadev0 c $major 0");
	chmod 0600, '/dev/megadev0';
}

chdir "/var/tmp" or die "Can't chdir /var/tmp: $!\n";

open F, "/usr/local/sbin/megarc -dispCfg -a0 |";

my $ld_status;
my %pd_status;
my $dds = 0;

while (<F>)
{
	chomp;
	next if m/^\s+$/o;
	s/^\s+//o;
	$ld_status = $1, next if (m/^Logical Drive : \d+\( Adapter: \d+ \):  Status: (\S+)/);
	$dds = 1, next if (m/^----  ------  ----------   ------      ----------------------.$/o);
	next unless $dds;
	$pd_status{"$1.$2"} = $3 if (m/^(\d+)\s+(\d+)\s+[\dxa-f]+\s+[\dxa-f]+\s+(\S+)/);

	#
	
	if (m/^\s*HotSpare Disk at Channel No\. (\d+) and ID No\. (\d+)/)
	{
		my $id = sprintf "%d.%.2d", $1, $2;
		$pd_status{$id} = "HOTSPARE";
	}
}

close F;

unlink "megarc.log";

open F, "> $status" or die "Can't open $status: $!\n";

print F "$ld_status ";

foreach my $d (sort keys %pd_status)
{
    print F "$d=$pd_status{$d} ";
}

print F "\n";

close F;

chmod 0644, $status;

exit 0;

# vim: set ts=3 sw=3:
