|
|
|
@ -27,20 +27,19 @@ use Getopt::Long; |
|
|
|
|
# |
|
|
|
|
# unused devices: <none> |
|
|
|
|
|
|
|
|
|
my $file = "/proc/mdstat"; |
|
|
|
|
my $file = "/proc/mdstat"; |
|
|
|
|
my $device = "all"; |
|
|
|
|
|
|
|
|
|
# Get command line options. |
|
|
|
|
GetOptions ('file=s' => \$file, |
|
|
|
|
'device=s' => \$device, |
|
|
|
|
'help' => sub { &usage() } ); |
|
|
|
|
GetOptions ( |
|
|
|
|
'file=s' => \$file, |
|
|
|
|
'device=s' => \$device, |
|
|
|
|
'help' => sub { &usage() } |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
## Strip leading "/dev/" from --device in case it has been given |
|
|
|
|
$device =~ s/^\/dev\///; |
|
|
|
|
|
|
|
|
|
## Return codes for Nagios |
|
|
|
|
my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); |
|
|
|
|
|
|
|
|
|
## This is a global return value - set to the worst result we get overall |
|
|
|
|
my $retval = 0; |
|
|
|
|
|
|
|
|
@ -50,78 +49,85 @@ my $result = 'OK'; |
|
|
|
|
|
|
|
|
|
open FILE, "< $file" or die "Can't open $file : $!"; |
|
|
|
|
while (<FILE>) { |
|
|
|
|
next if ! /^(md\d+)+\s*:/; |
|
|
|
|
next if $device ne "all" and $device ne $1; |
|
|
|
|
my $dev = $1; |
|
|
|
|
push @raids, $dev; |
|
|
|
|
|
|
|
|
|
my @array = split(/ /); |
|
|
|
|
$devs_total{$dev} = 0; |
|
|
|
|
my $devs_up = 0; |
|
|
|
|
my $missing = 0; |
|
|
|
|
for $_ (@array) { |
|
|
|
|
$level{$dev} = $1 if /^(raid\d+)$/; |
|
|
|
|
next if ! /(\w+)\[\d+\](\(.\))*/; |
|
|
|
|
$devs_total{$dev}++; |
|
|
|
|
if ($2 eq "(F)") { |
|
|
|
|
$failed_devs{$dev} .= "$1,"; |
|
|
|
|
} |
|
|
|
|
elsif ($2 eq "(S)") { |
|
|
|
|
$spare_devs{$dev} .= "$1,"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$active_devs{$dev} .= "$1,"; |
|
|
|
|
$devs_up++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (! defined($active_devs{$dev})) { $active_devs{$dev} = "none"; } |
|
|
|
|
else { $active_devs{$dev} =~ s/,$//; } |
|
|
|
|
if (! defined($spare_devs{$dev})) { $spare_devs{$dev} = "none"; } |
|
|
|
|
else { $spare_devs{$dev} =~ s/,$//; } |
|
|
|
|
if (! defined($failed_devs{$dev})) { $failed_devs{$dev} = "none"; } |
|
|
|
|
else { $failed_devs{$dev} =~ s/,$//; } |
|
|
|
|
|
|
|
|
|
$_ = <FILE>; |
|
|
|
|
/(\d+)\ blocks\ (.*)(\[.*\])\s?$/; |
|
|
|
|
$size{$dev} = int($1/1024); |
|
|
|
|
#print "$3\n"; |
|
|
|
|
$missing = 1 if ($3 =~ m/_/); |
|
|
|
|
if ($size{$dev} > 1024){ |
|
|
|
|
$size{$dev} = int($size{$dev}/1024)."GB"; |
|
|
|
|
} |
|
|
|
|
else{ |
|
|
|
|
$size{$dev} .= "MB"; |
|
|
|
|
} |
|
|
|
|
$_ = <FILE>; |
|
|
|
|
if (($devs_total{$dev} > $devs_up) || ($failed_devs{$dev} ne "none") || (($missing) && (!/recovery/))) { |
|
|
|
|
$status{$dev} = "Degraded"; |
|
|
|
|
$result = "CRITICAL"; |
|
|
|
|
$retval = $ERRORS{"CRITICAL"}; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$status{$dev} = "Optimal"; |
|
|
|
|
} |
|
|
|
|
if (/recovery|resync/){ |
|
|
|
|
$status{$dev} = "Rebuilding"; |
|
|
|
|
if ($result eq "OK"){ |
|
|
|
|
$result = "WARNING"; |
|
|
|
|
$retval = $ERRORS{"WARNING"}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
next if ! /^(md\d+)+\s*:/; |
|
|
|
|
next if $device ne "all" and $device ne $1; |
|
|
|
|
my $dev = $1; |
|
|
|
|
push @raids, $dev; |
|
|
|
|
|
|
|
|
|
my @array = split(/ /); |
|
|
|
|
$devs_total{$dev} = 0; |
|
|
|
|
my $devs_up = 0; |
|
|
|
|
my $missing = 0; |
|
|
|
|
for $_ (@array) { |
|
|
|
|
$level{$dev} = $1 if /^(raid\d+)$/; |
|
|
|
|
next if ! /(\w+)\[\d+\](\(.\))*/; |
|
|
|
|
$devs_total{$dev}++; |
|
|
|
|
if ($2 eq "(F)") { |
|
|
|
|
$failed_devs{$dev} .= "$1,"; |
|
|
|
|
} |
|
|
|
|
elsif ($2 eq "(S)") { |
|
|
|
|
$spare_devs{$dev} .= "$1,"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$active_devs{$dev} .= "$1,"; |
|
|
|
|
$devs_up++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (! defined($active_devs{$dev})){ |
|
|
|
|
$active_devs{$dev} = "none"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$active_devs{$dev} =~ s/,$//; |
|
|
|
|
} |
|
|
|
|
if (! defined($spare_devs{$dev})){ |
|
|
|
|
$spare_devs{$dev} = "none"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$spare_devs{$dev} =~ s/,$//; |
|
|
|
|
} |
|
|
|
|
if (! defined($failed_devs{$dev})){ |
|
|
|
|
$failed_devs{$dev} = "none"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$failed_devs{$dev} =~ s/,$//; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$_ = <FILE>; |
|
|
|
|
/(\d+)\ blocks\ (.*)(\[.*\])\s?$/; |
|
|
|
|
$size{$dev} = int($1/1024); |
|
|
|
|
$missing = 1 if ($3 =~ m/_/); |
|
|
|
|
if ($size{$dev} > 1024){ |
|
|
|
|
$size{$dev} = int($size{$dev}/1024)."GB"; |
|
|
|
|
} |
|
|
|
|
else{ |
|
|
|
|
$size{$dev} .= "MB"; |
|
|
|
|
} |
|
|
|
|
$_ = <FILE>; |
|
|
|
|
|
|
|
|
|
if (($devs_total{$dev} > $devs_up) || ($failed_devs{$dev} ne "none") || (($missing) && (!/recovery/))) { |
|
|
|
|
$status{$dev} = "Degraded"; |
|
|
|
|
$result = "CRITICAL"; |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
$status{$dev} = "Optimal"; |
|
|
|
|
} |
|
|
|
|
if (/(recovery|resync)\s*=\s*\d{1,2}(\.\d)?%/){ |
|
|
|
|
$status{$dev} = "Rebuilding"; |
|
|
|
|
if ($result eq "OK"){ |
|
|
|
|
$result = "WARNING"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
print "$result: "; |
|
|
|
|
foreach my $raid (@raids){ |
|
|
|
|
print "$raid:$level{$raid}:$devs_total{$raid} drives:$size{$raid}:$status{$raid} "; |
|
|
|
|
print "$raid:$level{$raid}:$devs_total{$raid} drives:$size{$raid}:$status{$raid} "; |
|
|
|
|
} |
|
|
|
|
print "\n"; |
|
|
|
|
close FILE; |
|
|
|
|
exit $retval; |
|
|
|
|
exit 0; |
|
|
|
|
|
|
|
|
|
# ===== |
|
|
|
|
sub usage() |
|
|
|
|
{ |
|
|
|
|
sub usage(){ |
|
|
|
|
printf(" |
|
|
|
|
Check status of Linux SW RAID |
|
|
|
|
|
|
|
|
|