#!/usr/bin/perl -w

# $Id$

# check_mptsas v1.0 - Check LSI Fusion RAID status
# Copyright (c) 2010, John Morrissey <jwm@horde.net>
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301
# USA.

# Requires mpt-status(8), from http://www.drugphish.ch/~ratz/mpt-status/

use strict;

my %ERRORS = (
	'OK' => 0,
	'WARNING' => 1,
	'CRITICAL' => 2,
	'UNKNOWN' => 3,
	'DEPENDENT' => 4,
);

# You may need to update this if your mpt-status(8) is in a different
# location.
$ENV{'PATH'} = "$ENV{'PATH'}:/sbin:/usr/sbin";

# Query the controller for all logical volume IDs, then each
# logical volume for its physical disks.
if (!open(MPT_STAT, 'mpt-status --autoload -p |')) {
	print "ERROR: could not execute 'mpt-status -p'.\n";
	exit $ERRORS{'UNKNOWN'};
}
my $logical_id = -1;
my $logical_is_optimal = 0;
my $phys_all_online = 1;
my $status_output = '';
while (<MPT_STAT>) {
	if (!/Found.*id=([0-9]+)/) {
		next;
	}
	$logical_id = $1;

	# Dunno whether it's strictly necessary to interrogate
	# mpt-status(8) separately for each logical volume.
	# Unfortunately, I don't have a machine with multiple
	# volumes handy to check.
	if (!open(MPT_STAT_LOGICAL, "mpt-status --autoload -si $logical_id |")) {
		print "ERROR: could not execute 'mpt-status -si $logical_id'.\n";
		exit $ERRORS{'UNKNOWN'};
	}
	while (<MPT_STAT_LOGICAL>) {
		$status_output .= $_;

		if (/^\s*log_id\s+[0-9]+\s+OPTIMAL(?:\s+|$)/) {
			$logical_is_optimal = 1;
			next;
		}

		if (/^\s*phys_id\s+[0-9]+\s+([A-Z]+)(\s+|$)/) {
			if ($1 ne 'ONLINE') {
				$phys_all_online = 0;
			}
		}
	}
	if (!$logical_is_optimal || !$phys_all_online) {
		print $status_output;
		exit $ERRORS{'WARNING'};
	}
	close(MPT_STAT_LOGICAL);
}
if ($logical_id == -1) {
	print "ERROR: could not find any devices.\n";
	print $status_output;
	exit $ERRORS{'UNKNOWN'};
}

print "OK\n";
print $status_output;
exit $ERRORS{'OK'};
