8 # check status of various hardware devices (fans, temp, dimms, powersupply)
11 # Copyright (c) 2009 Stephen Gran <steve@lobefin.net>
12 # Copyright (c) 2009,2010,2012 Peter Palfrader
14 # Permission is hereby granted, free of charge, to any person obtaining
15 # a copy of this software and associated documentation files (the
16 # "Software"), to deal in the Software without restriction, including
17 # without limitation the rights to use, copy, modify, merge, publish,
18 # distribute, sublicense, and/or sell copies of the Software, and to
19 # permit persons to whom the Software is furnished to do so, subject to
20 # the following conditions:
22 # The above copyright notice and this permission notice shall be
23 # included in all copies or substantial portions of the Software.
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 'SHOW DIMM' => \&do_dimm,
43 'SHOW FANS' => \&do_fans,
44 'SHOW POWERSUPPLY' => \&do_powersupply,
45 'SHOW TEMP' => \&do_temp,
51 my $USAGE = "PROGRAM_NAME: Usage: $PROGRAM_NAME [--help] [--ps-no-redundant] [--fan-no-redundant] [--fan-high] [--dimm-na] [--fan-ignore-not-present] [--ignore-failed=<S> [--ignore-failed=<S>]n";
52 Getopt::Long::config('bundling');
53 if (!GetOptions ($params,
59 '--fan-ignore-not-present',
64 if ($params->{'help'}) {
66 print "Checks hp hardware health.\n";
71 my $prompt = "hpasmcli>";
74 my %ignore_failed = map {$_ => 1} @{$params->{'ignore-failed'}};
78 my $dimm_num = my $status = my $return = my $message = '';
79 my $in_block = my $header_seen = my $num_dimms = 0;
81 for my $line (@output) {
83 unless ($header_seen) {
84 next until ($line eq "$prompt SHOW DIMM");
89 if ($line =~ /(^\s*$|-----)/) {
91 unless (($status eq 'Ok') ||
92 ($params->{'dimm-na'} && $status eq 'N/A')) {
93 my $what = sprintf("DIMM%d", $dimm_num);
94 $message = sprintf("%s: %s ", $what, $status);
95 $exit_status |= 2 unless (exists $ignore_failed{$what});
97 $return .= $message if ($message);
98 $message = $status = '';
104 if ($line =~ /^Module #:\s+(\d)/) {
107 } elsif ($line =~ /Status:\s+(\S+(\s*(.*)?))/) {
109 } elsif ($line =~ /$prompt/) {
115 return "DIMMS OK ($num_dimms) ";
123 my $fan_num = my $status = my $present = my $return = my $message = '';
124 my $header_seen = my $num_fans = 0;
126 for my $line (@output) {
128 unless ($header_seen) {
129 next until ($line eq "$prompt SHOW FANS");
134 if ($line =~ /^#(\d+)/) {
136 $return .= $message if ($message);
142 my @line = split /\s+/, $line;
144 if ($line[1] eq 'VIRTUAL') { # blade, etc
145 $message = 'FAN1: (virtual) OK ';
149 my $what = sprintf("FAN%d", $fan_num);
150 if ($line[2] ne 'Yes') {
151 $message = sprintf("%s: status=%s ", $what, $line[2]);
152 $exit_status |= 2 unless ($params->{'fan-ignore-not-present'} || (exists $ignore_failed{$what}));
153 } elsif ($line[3] ne 'NORMAL') {
154 $message = sprintf("%s: speed=%s ", $what, $line[3]);
155 $exit_status |= 1 unless ($line[3] eq 'HIGH' && $params->{'fan-high'} || (exists $ignore_failed{$what}));
156 } elsif ($line[5] ne 'Yes') {
157 $message = sprintf("%s: redundant=%s ", $what, $line[5]);
158 $exit_status |= 1 unless ($params->{'fan-no-redundant'} || (exists $ignore_failed{$what}));
160 } elsif ($line =~ /($prompt|^\s*$)/) {
164 $return .= $message if ($message);
167 return "FANS OK ($num_fans) ";
176 my $return = my $message = '';
177 my $header_seen = my $num_ps = 0;
179 for my $line (@output) {
181 unless ($header_seen) {
182 next until ($line eq "$prompt SHOW POWERSUPPLY");
187 my $what = sprintf("PS%s", $ps_num);
188 if ($line =~ /^Power supply #(\d+)/) {
190 $return .= $message if ($message);
195 } elsif ($line =~ /\s+Present\s*:\s+(.*)/) {
197 if ($present ne 'Yes') {
198 $message = sprintf("%s missing ", $what);
199 $exit_status |= 1 unless (exists $ignore_failed{$what});
201 } elsif ($line =~ /\s+Condition\s*:\s+(.*)/) {
203 if ($status ne 'Ok') {
204 $message = sprintf("%s: %s ", $what, $status);
205 $exit_status |= 2 unless (exists $ignore_failed{$what});
207 } elsif ($line =~ /\s+Redundant\s*:\s+(.*)/) {
209 if ($redundant ne 'Yes') {
210 $message = sprintf("%s not redundant ", $what);
211 $exit_status |= 1 unless ($params->{'ps-no-redundant'} || (exists $ignore_failed{$what}));
213 } elsif ($line =~ /($prompt|^\s*$)/) {
217 $return .= $message if ($message);
220 return "POWER OK ($num_ps) ";
228 my $temp_num = my $return = my $message = '';
229 my $header_seen = my $num_temp = 0;
231 for my $line (@output) {
233 unless ($header_seen) {
234 next until ($line eq "$prompt SHOW TEMP");
239 if ($line =~ /^#(\d+)/) {
241 $return .= $message if ($message);
246 my @line = split /\s+/, $line;
249 my $current_temp = $line[2];
250 my $threshold = $line[3];
252 $current_temp =~ s/(.*)C.*/$1/;
253 $threshold =~ s/(.*)C.*/$1/;
254 next if ($threshold eq '-');
257 my $what = sprintf("TEMP zone=%s", $zone);
258 if ($current_temp ne '-') {
259 my $off = $threshold - $current_temp;
261 $message = sprintf("%s %sC/%sC ", $what, $current_temp, $threshold);
262 $exit_status |= 2 unless (exists $ignore_failed{$what});
263 } elsif ($off < ($threshold/10)) {
264 $message = sprintf("%s %sC/%sC ", $what, $current_temp, $threshold);
265 $exit_status |= 1 unless (exists $ignore_failed{$what});
268 } elsif ($line =~ /($prompt|^\s*$)/) {
272 $return .= $message if ($message);
274 return "TEMP OK ($num_temp) ";
280 my @output = `echo "$command"|sudo hpasmcli 2>&1`;
281 if (($? >> 8) != 0) {
282 print "UNKNOWN: Can't exec hpasmcli: @output\n";
286 for my $line (@output) {
288 for my $check (sort keys %callbacks) {
289 if ($line eq "$prompt $check") {
290 $ret .= &{$callbacks{$check}}(@output);
295 if ($exit_status & 2) {
296 print "CRITICAL: $ret\n";
298 } elsif ($exit_status & 1) {
299 print "WARNING: $ret\n";