8 # check status of various hardware devices (fans, temp, dimms, powersupply)
11 # Copyright (c) 2009 Stephen Gran <steve@lobefin.net>
13 # Permission is hereby granted, free of charge, to any person obtaining
14 # a copy of this software and associated documentation files (the
15 # "Software"), to deal in the Software without restriction, including
16 # without limitation the rights to use, copy, modify, merge, publish,
17 # distribute, sublicense, and/or sell copies of the Software, and to
18 # permit persons to whom the Software is furnished to do so, subject to
19 # the following conditions:
21 # The above copyright notice and this permission notice shall be
22 # included in all copies or substantial portions of the Software.
24 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 'SHOW DIMM' => \&do_dimm,
42 'SHOW FANS' => \&do_fans,
43 'SHOW POWERSUPPLY' => \&do_powersupply,
44 'SHOW TEMP' => \&do_temp,
50 my $USAGE = "PROGRAM_NAME: Usage: $PROGRAM_NAME [--help] [--ps-no-redundant] [--fan-no-redundant] [--fan-high] [--dimm-na] [--fan-ignore-not-present]\n";
51 Getopt::Long::config('bundling');
53 '--help' => \$params->{'help'},
54 '--ps-no-redundant' => \$params->{'ps-no-redundant'},
55 '--fan-no-redundant' => \$params->{'fan-no-redundant'},
56 '--fan-high' => \$params->{'fan-high'},
57 '--dimm-na' => \$params->{'dimm-na'},
58 '--fan-ignore-not-present' => \$params->{'fan-ignore-not-present'},
62 if ($params->{'help'}) {
64 print "Checks hp hardware health.\n";
69 my $prompt = "hpasmcli>";
75 my $dimm_num = my $status = my $return = my $message = '';
76 my $in_block = my $header_seen = my $num_dimms = 0;
78 for my $line (@output) {
80 unless ($header_seen) {
81 next until ($line eq "$prompt SHOW DIMM");
86 if ($line =~ /(^\s*$|-----)/) {
88 unless (($status eq 'Ok') ||
89 ($params->{'dimm-na'} && $status eq 'N/A')) {
90 $message = sprintf("DIMM%d: %s ", $dimm_num, $status);
93 $return .= $message if ($message);
94 $message = $status = '';
100 if ($line =~ /^Module #:\s+(\d)/) {
103 } elsif ($line =~ /Status:\s+(\S+(\s*(.*)?))/) {
105 } elsif ($line =~ /$prompt/) {
111 return "DIMMS OK ($num_dimms) ";
119 my $fan_num = my $status = my $present = my $return = my $message = '';
120 my $header_seen = my $num_fans = 0;
122 for my $line (@output) {
124 unless ($header_seen) {
125 next until ($line eq "$prompt SHOW FANS");
130 if ($line =~ /^#(\d+)/) {
132 $return .= $message if ($message);
138 my @line = split /\s+/, $line;
140 if ($line[1] eq 'VIRTUAL') { # blade, etc
141 $message = 'FAN1: (virtual) OK ';
145 if ($line[2] ne 'Yes') {
146 $message = sprintf("FAN%d: status=%s ", $fan_num, $line[2]);
147 $exit_status |= 2 unless ($params->{'fan-ignore-not-present'});
148 } elsif ($line[3] ne 'NORMAL') {
149 $message = sprintf("FAN%d: speed=%s ", $fan_num, $line[3]);
150 $exit_status |= 1 unless ($line[3] eq 'HIGH' && $params->{'fan-high'});
151 } elsif ($line[5] ne 'Yes') {
152 $message = sprintf("FAN%d: redundant=%s ",$fan_num, $line[5]);
153 $exit_status |= 1 unless ($params->{'fan-no-redundant'});
155 } elsif ($line =~ /($prompt|^\s*$)/) {
159 $return .= $message if ($message);
162 return "FANS OK ($num_fans) ";
170 my $ps_num = my $return = my $message = '';
171 my $header_seen = my $num_ps = 0;
173 for my $line (@output) {
175 unless ($header_seen) {
176 next until ($line eq "$prompt SHOW POWERSUPPLY");
181 if ($line =~ /^Power supply #(\d+)/) {
183 $return .= $message if ($message);
188 } elsif ($line =~ /\s+Present\s*:\s+(.*)/) {
190 if ($present ne 'Yes') {
191 $message = sprintf("PS%d missing ", $ps_num);
194 } elsif ($line =~ /\s+Condition\s*:\s+(.*)/) {
196 if ($status ne 'Ok') {
197 $message = sprintf("PS%d: %s ", $ps_num, $status);
200 } elsif ($line =~ /\s+Redundant\s*:\s+(.*)/) {
202 if ($redundant ne 'Yes') {
203 $message = sprintf("PS%d not redundant ", $ps_num);
204 $exit_status |= 1 unless ($params->{'ps-no-redundant'});
206 } elsif ($line =~ /($prompt|^\s*$)/) {
210 $return .= $message if ($message);
213 return "POWER OK ($num_ps) ";
221 my $temp_num = my $return = my $message = '';
222 my $header_seen = my $num_temp = 0;
224 for my $line (@output) {
226 unless ($header_seen) {
227 next until ($line eq "$prompt SHOW TEMP");
232 if ($line =~ /^#(\d+)/) {
234 $return .= $message if ($message);
239 my @line = split /\s+/, $line;
242 my $current_temp = $line[2];
243 my $threshold = $line[3];
245 $current_temp =~ s/(.*)C.*/$1/;
246 $threshold =~ s/(.*)C.*/$1/;
247 next if ($threshold eq '-');
250 if ($current_temp ne '-') {
251 my $off = $threshold - $current_temp;
253 $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
255 } elsif ($off < ($threshold/10)) {
256 $message = sprintf("TEMP zone=%s %sC/%sC ", $zone, $current_temp, $threshold);
260 } elsif ($line =~ /($prompt|^\s*$)/) {
264 $return .= $message if ($message);
266 return "TEMP OK ($num_temp) ";
272 my @output = `echo "$command"|sudo hpasmcli 2>&1`;
273 if (($? >> 8) != 0) {
274 print "UNKNOWN: Can't exec hpasmcli: @output\n";
278 for my $line (@output) {
280 for my $check (sort keys %callbacks) {
281 if ($line eq "$prompt $check") {
282 $ret .= &{$callbacks{$check}}(@output);
287 if ($exit_status & 2) {
288 print "CRTICAL: $ret\n";
290 } elsif ($exit_status & 1) {
291 print "WARNING: $ret\n";