Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions lib/App/Monitoring/Plugin/CheckRaid/Plugins/mdstat.pm
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ sub check {
my (@status);
my @md = $this->parse;

my @spare_options = ();

@spare_options = split(/\,/, $this->{options}{mdstat_spare_count})
if (exists $this->{options}{mdstat_spare_count});

foreach (@md) {
my %md = %$_;

Expand All @@ -171,6 +176,26 @@ sub check {

# failed disks
my @fd = map { $_->{dev} } grep { $_->{flags} =~ /F/ } @{$md{disks}};
# spare disks
my @sd = map { $_->{dev} } grep { $_->{flags} =~ /S/ } @{$md{disks}};

my $spare_count = 0;
OPTION_LOOP:
{
foreach my $i (0 .. $#spare_options)
{
my ($disk, $value) = split(/:/, $spare_options[$i]);
for(@md)
{
if ($md{dev} eq $disk)
{
$spare_count = $value;
splice(@spare_options, $i, 1);
last OPTION_LOOP;
}
}
}
}

# raid0 is just there or its not. raid0 can't degrade.
# same for linear, no $md_status available
Expand All @@ -194,12 +219,27 @@ sub check {
# FIXME: this is same as above?
$this->warning;
$s .= "hot-spare failure:". join(",", @fd) .":$md{status}";
} elsif (@sd < $spare_count)
{
$this->warning;
$s .= "Array ".$md{dev}." should have ".$spare_count." spares, but has only ".(0+@sd)." spares";
} else {
$s .= "$md{status}";
}
push(@status, $s);
}

if (scalar @spare_options > 0)
{
$this->critical;
foreach (@spare_options)
{
my ($disk, $value) = split(/:/, $_);
my $s = "$disk is defined in spare_count option but could not be found!";
push(@status, $s);
}
}

return unless @status;

# denote this plugin as ran ok
Expand Down
42 changes: 41 additions & 1 deletion t/check_mdstat.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ BEGIN {
use strict;
use warnings;
use constant INACTIVE_TESTS => 2;
use constant ACTIVE_TESTS => 19;
use constant ACTIVE_TESTS => 26;
use Test::More tests => 1 + ACTIVE_TESTS * 6 + INACTIVE_TESTS * 2;
use test;

Expand Down Expand Up @@ -95,6 +95,42 @@ my @tests = (
active => 1,
message => 'md1(1.82 TiB raid1):hot-spare failure:sdh1:UUUUU, md0(119.18 GiB raid1):UU',
},
{ input => 'pr185_0', status => OK,
mdstat_spare_count => 'md1:1',
active => 1,
message => 'md1(3.49 TiB raid5):UUUUU',
},
{ input => 'pr185_0', status => WARNING,
mdstat_spare_count => 'md1:2',
active => 1,
message => 'md1(3.49 TiB raid5):Array md1 should have 2 spares, but has only 1 spares',
},
{ input => 'pr185_0', status => CRITICAL,
mdstat_spare_count => 'md2:2',
active => 1,
message => 'md1(3.49 TiB raid5):UUUUU, md2 is defined in spare_count option but could not be found!',
},
{ input => 'pr185_1', status => OK,
mdstat_spare_count => 'md1:1,md2:2',
active => 1,
message => 'md1(3.49 TiB raid5):UUUUU, md2(3.49 TiB raid5):UUUUU',
},
{ input => 'pr185_1', status => WARNING,
mdstat_spare_count => 'md1:1,md2:3',
active => 1,
message => 'md1(3.49 TiB raid5):UUUUU, md2(3.49 TiB raid5):Array md2 should have 3 spares, but has only 2 spares',
},
{ input => 'pr185_1', status => WARNING,
mdstat_spare_count => 'md1:2,md2:3',
active => 1,
message => 'md1(3.49 TiB raid5):Array md1 should have 2 spares, but has only 1 spares, md2(3.49 TiB raid5):Array md2 should have 3 spares, but has only 2 spares',
},
{ input => 'pr185_1', status => CRITICAL,
mdstat_spare_count => 'md1:1,md2:2,md3:1',
active => 1,
message => 'md1(3.49 TiB raid5):UUUUU, md2(3.49 TiB raid5):UUUUU, md3 is defined in spare_count option but could not be found!',
},

);

# test that plugin can be created
Expand All @@ -108,6 +144,10 @@ foreach my $test (@tests) {
if (defined $test->{check_status}) {
$options{check_status} = $test->{check_status};
}
if (defined $test->{mdstat_spare_count}) {
$options{mdstat_spare_count} = $test->{mdstat_spare_count};
}

my $plugin = mdstat->new(
commands => {
'mdstat' => ['<', TESTDIR . '/data/mdstat/' . $test->{input}],
Expand Down
6 changes: 6 additions & 0 deletions t/data/mdstat/pr185_0
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid5 sdh[3] sdg[2] sdj[6] sde[1] sdk[5](S) sdd[0]
3750244352 blocks super 1.2 level 5, 512k chunk, algorithm 2 [5/5] [UUUUU]
bitmap: 4/7 pages [16KB], 65536KB chunk

unused devices: <none>
10 changes: 10 additions & 0 deletions t/data/mdstat/pr185_1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
md1 : active raid5 sdh[3] sdg[2] sdj[6] sde[1] sdk[5](S) sdd[0]
3750244352 blocks super 1.2 level 5, 512k chunk, algorithm 2 [5/5] [UUUUU]
bitmap: 4/7 pages [16KB], 65536KB chunk

md2 : active raid5 sda[3] sdb[2] sdc[6] sdf[1] sdi[5](S) sdl[0](S) sdm[7]
3750244352 blocks super 1.2 level 5, 512k chunk, algorithm 2 [5/5] [UUUUU]
bitmap: 4/7 pages [16KB], 65536KB chunk

unused devices: <none>