&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();