Parse PD devices

This commit is contained in:
Georg Schönberger
2014-09-19 15:15:23 +02:00
parent 357c15c273
commit 27a5d04ab1

View File

@@ -48,7 +48,7 @@ use constant {
};
our @ldmap_a = ('DG/VD','TYPE','State','Access','Consist','Cache','Cac','sCC','Size');
our @pdmap_a = ('EID:Slt','DID','State','DG','Size','Intf','Med','SED','PI','SeSz','Model','Sp');
# Always return the highest state level
sub getExitState {
@@ -409,16 +409,14 @@ sub getLogicalDeviceStatus {
# Returns information about:
# - Physical device status
sub getPhysDeviceStatus {
my $sudo = $_[0];
my $storcli = $_[1];
my $controller = $_[2];
my @enclosures = @{($_[3])};
my @physDevices = @{($_[4])};
my @physicalDeviceTemperature_w = @{($_[5])};
my @physicalDeviceTemperature_c = @{($_[6])};
my $action = $_[7];
my $command = "$sudo $storcli /c$controller";
my $command = $storcli;
my $status = 0;
my $statusMessage = '';
@@ -435,184 +433,33 @@ sub getPhysDeviceStatus {
$command .= " show $action";
my @output = `$command`;
my @physDevs;
if(checkCommandStatus(\@output)) {
if($action eq "all") {
my $output_enc = -1;
my $output_dev = -1;
my $flag = -1;
foreach my $line (@output) {
if($flag > 0) {
$flag--;
} elsif($line =~ /^Drive\s\/c$controller\/e([0-9]*)\/s([0-9]*)\s\:/) {
# Check the overall drive state
$output_enc = $1;
$output_dev = $2;
$flag = 5;
} elsif($line =~ /^Drive\s\/c$controller\/e([0-9]*)\/s([0-9]*)\sState\s\:/) {
# Check the drive state in block Detailed information
$output_enc = $1;
$output_dev = $2;
$flag = 1;
} elsif($flag eq 0 && ($line =~ /^\-{5,}$/ || $line =~ /^\s*$/)) {
# Detect the end of the block which was last checked
$flag = -1;
} elsif($flag eq 0) {
my @values = split(' ',$line);
if($values[0] =~ /^[0-9]*:[0-9]*/) {
# Check the overall drive state
if($values[2] eq "Offln") {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Physical drive is offline, "; }
if ($VERBOSITY >= 1) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc is offline, "; }
} elsif($values[2] eq "UBad") {
$status = getExitState($status, STATE_CRITICAL);
if ($VERBOSITY == 0) {$statusMessage .= "Physical drive state is Unconfigured Bad, "; }
if ($VERBOSITY >= 1) {$statusMessage .= "Physical drive $output_dev state in enclosure $output_enc is Unconfigured Bad, "; }
}
} elsif($values[0] =~ /^[a-zA-Z\.]*/) {
# Check the drive state in block Detailed information
if($values[0] eq "Shield") {
if($values[3] > $ignerr_s) {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Shield counter (phys. drive) $values[3] (>$ignerr_s), "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: shield counter $values[3] (>$ignerr_s), "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: shield counter $values[3] (>$ignerr_s), "; }
}
}
elsif($values[0] eq "Media") {
if($values[4] > $ignerr_m) {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Media error count (phys. drive) $values[4] (>$ignerr_m), "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: media error count $values[4] (>$ignerr_m), "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: media error count $values[4] (>$ignerr_m), "; }
}
}
elsif($values[0] eq "Other") {
if($values[4] > $ignerr_o) {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Other error count (phys. drive) $values[4] (>$ignerr_o), "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: other error count $values[4] (>$ignerr_o), "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: other error count $values[4] (>$ignerr_o), "; }
}
}
elsif($values[0] eq "Drive") {
chop($values[3]);
# check if temp is really a number, could be N/A also
if($values[3] =~ /^[-+]?[0-9]*\.?[0-9]+$/){
my $temp = $values[3];
my $crit = 0;
# check for warn range
if($physicalDeviceTemperature_w[0] eq "in") {
if(($temp >= $physicalDeviceTemperature_w[1]) && ($temp <= $physicalDeviceTemperature_w[2])) {
# is in warn range, so also check if in critical error range
if($physicalDeviceTemperature_c[0] eq "in") {
if(($temp >= $physicalDeviceTemperature_c[1]) && ($temp <= $physicalDeviceTemperature_c[2])) {
# critical error
$crit = 1;
$status = getExitState($status, STATE_CRITICAL);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature critical, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
} else {
if(($temp < $physicalDeviceTemperature_c[1]) || ($temp > $physicalDeviceTemperature_c[2])) {
# critical error
$crit = 1;
$status = getExitState($status, STATE_CRITICAL);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature critical, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
}
if($crit eq 0) { # only warn if not already given a critical error
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature warning, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
}
} else {
if(($temp < $physicalDeviceTemperature_w[1]) || ($temp > $physicalDeviceTemperature_w[2])) {
# is in warn range, so also check if in critical error range
if($physicalDeviceTemperature_c[0] eq "in") {
if(($temp >= $physicalDeviceTemperature_c[1]) && ($temp <= $physicalDeviceTemperature_c[2])) {
# critical error
$crit = 1;
$status = getExitState($status, STATE_CRITICAL);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature critical, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
} else {
if(($temp < $physicalDeviceTemperature_c[1]) || ($temp > $physicalDeviceTemperature_c[2])) {
# critical error
$crit = 1;
$status = getExitState($status, STATE_CRITICAL);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature critical, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
}
if($crit eq 0) { # only warn if not already given a critical error
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive temperature warning, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: temperature is ${temp}C, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: temperature is ${temp}C, "; }
}
}
}
}
}
elsif($values[0] eq "Predictive") {
if($values[4] > $ignerr_p) {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive Predictive Fail Count $values[4] (>$ignerr_p), "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: Predictive Fail Count $values[4] (>$ignerr_p), "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: Predictive Fail Count $values[4] (>$ignerr_p), "; }
}
}
elsif($values[0] eq "S.M.A.R.T") {
if($values[6] ne "No") {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "S.M.A.R.T alert flagged by drive, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: S.M.A.R.T alert flagged, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: S.M.A.R.T alert flagged, "; }
}
}
} else {
$flag = -1;
}
my $currBlock;
foreach my $line(@output){
my @splittedLine;
if($line =~ /^Drive \/(c[0-9]*\/e[0-9]*\/s[0-9]*) \:$/){
$currBlock = $1;
next;
}
}
} else {
# Check initialization or rebuild output
my $output_enc = -1;
my $output_dev = -1;
foreach my $line (@output) {
if($line =~ /^\/c$controller\/e([0-9]*)\/s([0-9]*)/) {
$output_enc = $1;
$output_dev = $2;
}
if(($output_enc ne -1) && ($output_dev ne -1)) {
#grep for status and floating point number
if($line =~ /^\/c$controller\/e$output_enc\/s$output_dev\s*([\-]{1}|[0-9]*\.?[0-9]*)\s*([\w\s]*)$/){
my $inProgress = $1;
my $state = $2;
if($state =~ m/^In progress/) {
$status = getExitState($status, STATE_WARNING);
if ($VERBOSITY == 0) {$statusMessage .= "Phys. drive: $action in progress, "; }
if ($VERBOSITY == 1) {$statusMessage .= "Physical drive $output_dev: $action in progress, "; }
if ($VERBOSITY >= 2) {$statusMessage .= "Physical drive $output_dev in enclosure $output_enc: $action in progress (percentage: $inProgress), "; }
}
if(defined($currBlock)){
if($line =~ /^\d+\:\d+\s+\d+\s+\w+\s+\d+.*/){
@splittedLine = map { s/^\s*//; s/\s*$//; $_; } split(/\s+/,$line);
my %lineValues_h;
# The current block is the c0/e252/s0 name
$lineValues_h{'pd'} = $currBlock;
for(my $i = 0; $i < @ldmap_a; $i++){
$lineValues_h{$ldmap_a[$i]} = $splittedLine[$i];
}
push @physDevs, \%lineValues_h;
}
}
}
}
return ($status, $statusMessage);
} else {
print "Invalid StorCLI command! ($command)\n";
exit(STATE_UNKNOWN);
}
use Data::Dumper;
print Dumper(@physDevs);
}
# Returns information about: