LSI SAS RAID tools: MegaCLI, MegaRAID Storage Manager, MegaRAID SAS SNMP
http://www.delltechcenter.com/page/Linux+RAID+and+Storage
http://www.bigdbahead.com/?p=574
http://wiki.debian.org/LinuxRaidForAdmins
http://hwraid.le-vert.net/wiki
http://www.lsi.com/Search/Pages/downloads.aspx?k=MegaCLI%20-%20Linux
http://tools.rapidsoft.de/perc/perc-cheat-sheet.html
Determine RAID level:
$raid_level_mapping = array();
$raid_level_mapping['Primary-0, Secondary-0, RAID Level Qualifier-0'] = '0';
$raid_level_mapping['Primary-1, Secondary-0, RAID Level Qualifier-0'] = '1';
$raid_level_mapping['Primary-5, Secondary-0, RAID Level Qualifier-3'] = '5';
$raid_level_mapping['Primary-1, Secondary-3, RAID Level Qualifier-0'] = '10';
Source:
http://tools.rapidsoft.de/perc/rs_check ... ss.php.txt
- Code: Select all
<?php
/**
* PERC5/i RAID check for rs_check package
*
* @package rs_check
* @author Moritz Mertinkat ([email protected])
* @copyright rapidsoft GmbH
*/
class rs_check_raid_perc5i extends rs_check {
var $name = 'raid_perc5i';
function run_command($command, &$output, &$return_value) {
return exec($command . ' 2>&1', $output, $return_value);
}
function check() {
$output = array();
$info = $this->run_command('lspci -n|grep 1028 2>&1', $output, $return_value);
if ($return_value != 0 && count($output) > 0) {
$this->add_critical('Error running lspci command (apt-get install pciutils)');
return;
}
if (!preg_match('/1028:0015/i', $info)) {
// No PERC5 found (vendor id = 0x1028, product id = 0015)
$this->add_critical('No PERC5 found');
return;
}
$output = array();
$this->run_command('/opt/MegaRAID/MegaCli/MegaCli -adpCount', $output, $return_value);
if (count($output) < 2) {
$this->add_critical('Error running MegaCli -adpCount');
return;
}
$controller_count = $return_value;
if ($controller_count == 0) {
$this->add_critical('No controllers found');
return;
}
for ($controller_i = 0; $controller_i < $controller_count; ++$controller_i) {
$controller_id = 'a' . $controller_i;
// Virtual disk information
$output = array();
$this->run_command('/opt/MegaRAID/MegaCli/MegaCli -LdPdInfo -a' . $controller_i, $output, $return_value);
if ($return_value != 0 || count($output) < 3) {
$this->add_critical('Error running MegaCli command (MegaCli -LDInfo -Lall -a' . $controller_i . ')');
return;
}
$logicaldisk_id = NULL;
$logicaldisk_list = array();
$physicaldisk_i = -1;
$physicaldisk_checked_list = array();
$vd_start = false;
$pd_start = false;
for ($i = 0; $i < count($output); ++$i) {
$line = trim($output[$i]);
if ($line == '' || preg_match('/^(Number of Spans|Span):/i', $line)) {
continue;
}
$matches = array();
if (preg_match('/^(Virtual Disk: (\d+))/i', $line, $matches)) {
$vd_start = true;
$pd_start = false;
$logicaldisk_id = $controller_id . 'd' . $matches[2];
$line = $matches[1]; // we need the "Virtual Disk" entry
$physicaldisk_i = -1;
}
$matches = array();
if (preg_match('/^PD: (\d+) Information/i', $line, $matches)) {
$vd_start = false;
$pd_start = true;
if ($physicaldisk_i == -1 || $physicaldisk_i > -1 && isset($logicaldisk_list[$logicaldisk_id]['physicaldisk_list'][$physicaldisk_i])) {
// only increase in case of -1 or if previous physical disk entry was not empty
$physicaldisk_i ++;
}
continue;
}
if ($logicaldisk_id !== NULL) {
if (!isset($logicaldisk_list[$logicaldisk_id])) {
$logicaldisk_list[$logicaldisk_id] = array();
}
$matches = array();
if (preg_match('/^(.*?):\s*(.*)$/i', $line, $matches)) {
if ($vd_start) {
$logicaldisk_list[$logicaldisk_id][$matches[1]] = $matches[2];
} else if ($pd_start) {
if (!isset($logicaldisk_list[$logicaldisk_id]['physicaldisk_list'][$physicaldisk_i])) {
$logicaldisk_list[$logicaldisk_id]['physicaldisk_list'][$physicaldisk_i] = array();
}
$logicaldisk_list[$logicaldisk_id]['physicaldisk_list'][$physicaldisk_i][$matches[1]] = $matches[2];
}
}
}
}
$raid_level_mapping = array();
$raid_level_mapping['Primary-0, Secondary-0, RAID Level Qualifier-0'] = '0';
$raid_level_mapping['Primary-1, Secondary-0, RAID Level Qualifier-0'] = '1';
$raid_level_mapping['Primary-5, Secondary-0, RAID Level Qualifier-3'] = '5';
$raid_level_mapping['Primary-1, Secondary-3, RAID Level Qualifier-0'] = '10';
foreach ($logicaldisk_list as $logicaldisk_id => $logicaldisk_record) {
if (!isset($logicaldisk_record['Name']) || !isset($logicaldisk_record['RAID Level']) ||
!isset($logicaldisk_record['Size']) || !isset($logicaldisk_record['State']) ||
!isset($logicaldisk_record['Current Cache Policy']) || !isset($logicaldisk_record['physicaldisk_list'])) {
$this->add_critical('Logical disk list columns must a least contain: Name, RAID Level, Size, State, Current Cache Policy and physicaldisk_list');
}
if (isset($raid_level_mapping[$logicaldisk_record['RAID Level']])) {
$logicaldisk_record['RAID Level'] = $raid_level_mapping[$logicaldisk_record['RAID Level']];
} else {
$this->add_critical('Unknown RAID Level for ' . $logicaldisk_id);
}
if (!preg_match('/No Write Cache if Bad BBU/i', $logicaldisk_record['Current Cache Policy'])) {
$this->add_critical('Write cache enabled in case of bad BBU for ' . $logicaldisk_id . ' (disable with "MegaCli -LDSetProp -NoCachedBadBBU -L' . $logicaldisk_record['Virtual Disk'] . ' -a' . $controller_i . '")');
}
if (!is_array($logicaldisk_record['physicaldisk_list']) || count($logicaldisk_record['physicaldisk_list']) == 0) {
$this->add_critical('No physical disks found for ' . $logicaldisk_id);
}
if ($logicaldisk_record['State'] != 'Optimal') {
// State is not optimal (i.e. degraded)
// We now check whether a rebuild is in progress and thus only a warning is emitted.
// If we find physical disks in states other than "online", "rebuild" and "hotspare" we emitt a critical error.
$total_count = count($logicaldisk_record['physicaldisk_list']);
$online_count = 0;
$rebuild_count = 0;
$critical_message_list = array();
for ($i = 0; $i < $total_count; ++$i) {
$physicaldisk_record = $logicaldisk_record['physicaldisk_list'][$i];
$physicaldisk_id = $controller_id . 'e' . $physicaldisk_record['Enclosure Device ID'] . 's' . $physicaldisk_record['Slot Number'];
$physicaldisk_checked_list[$physicaldisk_id] = true;
if (!isset($physicaldisk_record['Enclosure Device ID']) || !isset($physicaldisk_record['Slot Number']) ||
!isset($physicaldisk_record['Device Id']) || !isset($physicaldisk_record['Firmware state'])) {
$critical_message_list[] = 'Physical disk list (1) columns must a least contain: Enclosure Device ID, Slot Number, Device Id and Firmware state';
continue;
}
if (!in_array($physicaldisk_record['Firmware state'], array('Online', 'Rebuild', 'Hotspare'))) {
$critical_message_list[] = 'State for ' . $physicaldisk_id . ' (' . $logicaldisk_id . '): ' . $physicaldisk_record['Firmware state'];
} else if ($physicaldisk_record['Firmware state'] == 'Online') {
$online_count ++;
} else if ($physicaldisk_record['Firmware state'] == 'Rebuild') {
$rebuild_count ++;
}
}
if ($online_count == $total_count) {
// Degraded, but all physical disks are "online" -- maybe a disk is missing?
$this->add_critical('State for ' . $logicaldisk_id . ' (RAID ' . $logicaldisk_record['RAID Level'] . ', ' . $logicaldisk_record['Size'] . '): ' . $logicaldisk_record['State'] . ' (missing disks?)');
} else if ($online_count + $rebuild_count == $total_count) {
$this->add_warning('State for ' . $logicaldisk_id . ' (RAID ' . $logicaldisk_record['RAID Level'] . ', ' . $logicaldisk_record['Size'] . '): ' . $logicaldisk_record['State'] . ' (rebuilding)');
} else {
$this->add_critical('State for ' . $logicaldisk_id . ' (RAID ' . $logicaldisk_record['RAID Level'] . ', ' . $logicaldisk_record['Size'] . '): ' . $logicaldisk_record['State']);
}
for ($i = 0; $i < count($critical_message_list); ++$i) {
$this->add_critical($critical_message_list[$i]);
}
}
}
// Physical disk information
$output = array();
$this->run_command('/opt/MegaRAID/MegaCli/MegaCli -PDList -a' . $controller_i, $output, $return_value);
if ($return_value != 0 || count($output) < 3) {
$this->add_critical('Error running MegaCli command (MegaCli -PDList -a' . $controller_i . ')');
return;
}
$physicaldisk_id = NULL;
$physicaldisk_list = array();
for ($i = 0; $i < count($output); ++$i) {
$line = trim($output[$i]);
$matches = array();
if (preg_match('/^Enclosure Device ID: (\d+)/i', $line, $matches)) {
if ($physicaldisk_id === NULL) {
$physicaldisk_id = 0;
} else {
$physicaldisk_id ++;
}
$physicaldisk_list[$physicaldisk_id] = array();
}
if ($physicaldisk_id !== NULL) {
$matches = array();
if (preg_match('/^(.*?):\s*(.*)$/i', $line, $matches)) {
$physicaldisk_list[$physicaldisk_id][$matches[1]] = $matches[2];
}
}
}
foreach ($physicaldisk_list as $physicaldisk_record) {
if (!isset($physicaldisk_record['Enclosure Device ID']) || !isset($physicaldisk_record['Slot Number']) ||
!isset($physicaldisk_record['Device Id']) || !isset($physicaldisk_record['Firmware state'])) {
$this->add_critical('Physical disk list columns must a least contain: Enclosure Device ID, Slot Number, Device Id and Firmware state');
}
$physicaldisk_id = $controller_id . 'e' . $physicaldisk_record['Enclosure Device ID'] . 's' . $physicaldisk_record['Slot Number'];
if (isset($physicaldisk_checked_list[$physicaldisk_id])) {
continue;
}
if ($physicaldisk_record['Firmware state'] != 'Online' && $physicaldisk_record['Firmware state'] != 'Hotspare') {
$this->add_critical('State for ' . $physicaldisk_id . ': ' . $physicaldisk_record['Firmware state']);
}
}
// BBU information
$output = array();
$this->run_command('/opt/MegaRAID/MegaCli/MegaCli -AdpBbuCmd -GetBbuStatus -a' . $controller_i, $output, $return_value);
if ($return_value != 0 || count($output) < 3) {
$this->add_critical('Error running MegaCli command (MegaCli -AdpBbuCmd -GetBbuStatus -a' . $controller_i . ')');
return;
}
$bbu_info = array();
for ($i = 0; $i < count($output); ++$i) {
$line = trim($output[$i]);
if (preg_match('/^(.*?)\s*:\s*(.+)$/i', $line, $matches)) {
$bbu_info[$matches[1]] = $matches[2];
}
}
if (!isset($bbu_info['BatteryType']) || !isset($bbu_info['Fully Charged']) ||
!isset($bbu_info['Initialized']) || !isset($bbu_info['Over Temperature']) ||
!isset($bbu_info['Charger Status']) || !isset($bbu_info['isSOHGood'])) {
$this->add_critical('BBU info columns must a least contain: BatteryType, Fully Charged, Initialized, Over Temperature, Charger Status and isSOHGood');
}
if ($bbu_info['BatteryType'] != 'BBU') {
$this->add_critical('BBU a' . $controller_i . 'bbu has an unknown battery type');
}
if ($bbu_info['Fully Charged'] != 'Yes') {
$this->add_critical('BBU a' . $controller_i . 'bbu not fully charged');
}
if ($bbu_info['Initialized'] != 'Yes') {
$this->add_critical('BBU a' . $controller_i . 'bbu is not initialized');
}
if ($bbu_info['Over Temperature'] != 'No') {
$this->add_critical('BBU a' . $controller_i . 'bbu is over temperature');
}
if ($bbu_info['isSOHGood'] != 'Yes') {
$this->add_critical('BBU a' . $controller_i . 'bbu has a problem (isSOHGood)');
}
}
}
}
return new rs_check_raid_perc5i();