Rev 77 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
68 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * VNag - Nagios Framework for PHP |
||
5 | * Developed by Daniel Marschall, ViaThinkSoft <www.viathinksoft.com> |
||
6 | * Licensed under the terms of the Apache 2.0 license |
||
7 | * |
||
79 | daniel-mar | 8 | * Revision 2023-10-13 |
68 | daniel-mar | 9 | */ |
10 | |||
11 | declare(ticks=1); |
||
12 | |||
13 | class MegaRaidCheck extends VNag { |
||
71 | daniel-mar | 14 | private $argCmd = null; |
68 | daniel-mar | 15 | |
16 | public function __construct() { |
||
17 | parent::__construct(); |
||
18 | |||
19 | if ($this->is_http_mode()) { |
||
20 | // Don't allow the standard arguments via $_REQUEST |
||
21 | $this->registerExpectedStandardArguments(''); |
||
22 | } else { |
||
23 | $this->registerExpectedStandardArguments('Vhtv'); |
||
24 | } |
||
25 | |||
71 | daniel-mar | 26 | $this->addExpectedArgument($this->argCmd = new VNagArgument('E', 'executable', VNagArgument::VALUE_OPTIONAL, 'executable', 'The path to the MegaCli64 executable.', '/opt/MegaRAID/MegaCli/MegaCli64')); |
27 | |||
68 | daniel-mar | 28 | $this->getHelpManager()->setPluginName('vnag_megaraid'); |
79 | daniel-mar | 29 | $this->getHelpManager()->setVersion('2023-10-13'); |
68 | daniel-mar | 30 | $this->getHelpManager()->setShortDescription('This plugin checks the controller and disk status of a MegaRAID controller (using MegaCli64).'); |
31 | $this->getHelpManager()->setCopyright('Copyright (C) 2011-$CURYEAR$ Daniel Marschall, ViaThinkSoft.'); |
||
32 | $this->getHelpManager()->setSyntax('$SCRIPTNAME$'); |
||
33 | $this->getHelpManager()->setFootNotes('If you encounter bugs, please contact ViaThinkSoft at www.viathinksoft.com'); |
||
34 | } |
||
35 | |||
36 | private function megacli_logical_disk_status($adapter='ALL') { |
||
37 | $mock_file = __DIR__.'/status_ld.mock'; |
||
38 | |||
39 | if (file_exists($mock_file)) { |
||
40 | $out = explode("\n", file_get_contents($mock_file)); |
||
41 | } else { |
||
71 | daniel-mar | 42 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -LDInfo -Lall '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 43 | $out = array(); |
44 | exec($cmd, $out, $ec); |
||
45 | |||
46 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
47 | } |
||
48 | |||
49 | $drives = []; |
||
50 | $cur_drive_id = '???'; |
||
51 | $cur_drive_name = ''; |
||
52 | foreach ($out as $line) { |
||
53 | if (preg_match('@Virtual Drive: (\d+)@', $line, $m)) $cur_drive_id = $m[1]; |
||
54 | if (preg_match('@Name\s*:([^\n]*)@', $line, $m)) $cur_drive_name = trim($m[1]); |
||
55 | if (preg_match('@State\s*:([^\n]*)@', $line, $m)) { |
||
56 | $drives[] = [$cur_drive_id, $cur_drive_name, trim($m[1])]; |
||
57 | $cur_drive_id = '???'; |
||
58 | $cur_drive_name = ''; |
||
59 | } |
||
60 | } |
||
61 | |||
69 | daniel-mar | 62 | $drives_ok = 0; |
63 | $drives_fail = 0; |
||
64 | |||
68 | daniel-mar | 65 | foreach ($drives as list($cur_drive_id, $cur_drive_name, $cur_drive_status)) { |
66 | if (strtolower($cur_drive_status) == 'offline') $status = VNag::STATUS_CRITICAL/*?*/; |
||
67 | else if (strpos($cur_drive_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL; |
||
68 | else if (strtolower($cur_drive_status) == 'optimal') $status = VNag::STATUS_OK; |
||
69 | else if (strtolower($cur_drive_status) == 'initialize') $status = VNag::STATUS_WARNING; |
||
70 | else if (strtolower($cur_drive_status) == 'checkconsistency') $status = VNag::STATUS_WARNING; |
||
71 | else $status = VNag::STATUS_UNKNOWN; |
||
72 | |||
69 | daniel-mar | 73 | if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; } |
74 | |||
68 | daniel-mar | 75 | $cur_drive_hf_name = $cur_drive_id . (!empty($cur_drive_name) ? " ($cur_drive_name)" : ""); |
76 | $msg = "Logical drive $cur_drive_hf_name: $cur_drive_status"; |
||
77 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
78 | $this->addVerboseMessage($msg, $verbosity); |
||
79 | $this->setStatus($status); |
||
80 | } |
||
69 | daniel-mar | 81 | |
82 | $drives_total = $drives_ok + $drives_fail; |
||
83 | return "$drives_fail/$drives_total arrays with problems"; |
||
68 | daniel-mar | 84 | } |
85 | |||
86 | private function megacli_smart_disk_status($adapter='ALL') { |
||
87 | $mock_file = __DIR__.'/status_pd.mock'; |
||
88 | |||
89 | if (file_exists($mock_file)) { |
||
90 | $out = explode("\n", file_get_contents($mock_file)); |
||
91 | } else { |
||
71 | daniel-mar | 92 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -PDList '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 93 | $out = array(); |
94 | exec($cmd, $out, $ec); |
||
95 | |||
96 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
97 | } |
||
98 | |||
99 | $drives = []; |
||
100 | $cur_drive_id = '???'; |
||
101 | foreach ($out as $line) { |
||
102 | if (preg_match('@Slot Number: (\d+)@', $line, $m)) $cur_drive_id = $m[1]; |
||
103 | if (preg_match('@Drive has flagged a S.M.A.R.T alert\s*:([^\n]*)@', $line, $m)) { |
||
104 | $drives[] = [$cur_drive_id, trim($m[1])]; |
||
105 | $cur_drive_id = '???'; |
||
106 | } |
||
107 | } |
||
108 | |||
69 | daniel-mar | 109 | $drives_ok = 0; |
110 | $drives_fail = 0; |
||
111 | |||
68 | daniel-mar | 112 | foreach ($drives as list($cur_drive_id, $cur_drive_status)) { |
113 | if (strtolower($cur_drive_status) == 'no') $status = VNag::STATUS_OK; |
||
114 | else $status = VNag::STATUS_CRITICAL; // unsure if there will be a "yes" or any other output |
||
115 | |||
69 | daniel-mar | 116 | if ($status == VNag::STATUS_OK) { $drives_ok++; } else { $drives_fail++; } |
117 | |||
68 | daniel-mar | 118 | $msg = "Physical drive $cur_drive_id: SMART alert? $cur_drive_status"; |
119 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
120 | $this->addVerboseMessage($msg, $verbosity); |
||
121 | $this->setStatus($status); |
||
122 | } |
||
69 | daniel-mar | 123 | |
124 | $drives_total = $drives_ok + $drives_fail; |
||
125 | return "$drives_fail/$drives_total drives have SMART alerts"; |
||
68 | daniel-mar | 126 | } |
127 | |||
128 | private function megacli_battery_status($adapter='ALL') { |
||
129 | $mock_file = __DIR__.'/status_battery.mock'; |
||
130 | |||
131 | if (file_exists($mock_file)) { |
||
132 | $out = explode("\n", file_get_contents($mock_file)); |
||
133 | } else { |
||
71 | daniel-mar | 134 | $cmd = escapeshellcmd($this->argCmd->getValue()).' -AdpBbuCmd '.escapeshellarg('-a'.$adapter).' -NoLog'; |
68 | daniel-mar | 135 | $out = array(); |
136 | exec($cmd, $out, $ec); |
||
137 | |||
138 | // DEBUG: file_put_contents($mock_file, implode("\n", $out)); |
||
139 | } |
||
140 | |||
141 | $battery_status = '???'; |
||
142 | foreach ($out as $line) { |
||
143 | if (preg_match('@Battery State\s*:([^\n]*)@', $line, $m)) { |
||
144 | $battery_status = trim($m[1]); |
||
145 | } |
||
146 | } |
||
147 | |||
148 | if (strtolower($battery_status) == 'missing') $status = VNag::STATUS_WARNING; |
||
149 | else if (strtolower($battery_status) == 'optimal') $status = VNag::STATUS_OK; |
||
150 | else if (strtolower($battery_status) == 'failed') $status = VNag::STATUS_CRITICAL; |
||
151 | else if (strtolower($battery_status) == 'learning') $status = VNag::STATUS_WARNING; |
||
152 | else if (strpos($battery_status, 'degraded') !== false) $status = VNag::STATUS_CRITICAL; |
||
153 | else $status = VNag::STATUS_UNKNOWN; |
||
154 | |||
155 | $msg = "Battery Status: $battery_status"; |
||
156 | $verbosity = $status == VNag::STATUS_OK ? VNag::VERBOSITY_ADDITIONAL_INFORMATION : VNag::VERBOSITY_SUMMARY; |
||
157 | $this->addVerboseMessage($msg, $verbosity); |
||
158 | $this->setStatus($status); |
||
69 | daniel-mar | 159 | |
160 | return $status == VNag::STATUS_OK ? "Battery OK" : "Battery has problems"; |
||
68 | daniel-mar | 161 | } |
162 | |||
163 | protected function cbRun() { |
||
69 | daniel-mar | 164 | $headlines = ''; |
165 | $headlines .= $this->megacli_logical_disk_status() . ', '; |
||
166 | $headlines .= $this->megacli_smart_disk_status() . ', '; |
||
167 | $headlines .= $this->megacli_battery_status(); |
||
168 | $this->setHeadline($headlines, true); |
||
68 | daniel-mar | 169 | } |
170 | } |