parent
cdbbc17ce6
commit
c0e1aa14ac
3 changed files with 162 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||||
|
# Discover multipath devices |
||||||
|
# $1 not used for now |
||||||
|
UserParameter=vfs.mpath.discovery[*],sudo /var/lib/zabbix/bin/disco_mpath_sudo --$1 |
||||||
|
|
||||||
|
# Check multipath device |
||||||
|
UserParameter=vfs.mpath.info[*],sudo /var/lib/zabbix/bin/check_mpath_sudo --mpath=$1 |
@ -0,0 +1,125 @@ |
|||||||
|
#!/usr/bin/perl |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use JSON; |
||||||
|
use Getopt::Long; |
||||||
|
use File::Which; |
||||||
|
|
||||||
|
my $json = {}; |
||||||
|
my $mpath = undef; |
||||||
|
my $help = 0; |
||||||
|
my $pretty = 0; |
||||||
|
|
||||||
|
GetOptions( |
||||||
|
"mpath=s" => \$mpath, |
||||||
|
"help" => \$help, |
||||||
|
"pretty" => \$pretty |
||||||
|
); |
||||||
|
|
||||||
|
my $multipathd = which('multipathd'); |
||||||
|
|
||||||
|
if (not defined $multipathd){ |
||||||
|
print 'ZBX_NOTSUPPORTED'; |
||||||
|
exit 1; |
||||||
|
} |
||||||
|
|
||||||
|
if ($help or not defined $mpath){ |
||||||
|
print <<_EOF; |
||||||
|
Usage : $0 --mpath=<name of the mpath device> [--pretty] |
||||||
|
|
||||||
|
* --mpath : the name of the device to check |
||||||
|
* --pretty : output pretty JSON, easier to read for humans |
||||||
|
* --help : display this help |
||||||
|
|
||||||
|
_EOF |
||||||
|
exit 2; |
||||||
|
} |
||||||
|
|
||||||
|
$json = { |
||||||
|
mpath => $mpath, |
||||||
|
size => 0, |
||||||
|
dm_st => 'unknown', |
||||||
|
features => '', |
||||||
|
failures => 0, |
||||||
|
path_failures => 0, |
||||||
|
paths_num_total => 0, |
||||||
|
paths_num_ko => 0, |
||||||
|
paths_num_active => 0, |
||||||
|
paths_num_inactive => 0, |
||||||
|
paths_details => [], |
||||||
|
paths_with_issue => [], |
||||||
|
errors => [] |
||||||
|
}; |
||||||
|
my @res = qx($multipathd show maps raw format "%n|%N|%S|%f|%t|%x|%0"); |
||||||
|
if ($? != 0){ |
||||||
|
push @{$json->{errors}}, "Failed to run multipathd show maps raw format"; |
||||||
|
} |
||||||
|
foreach (@res){ |
||||||
|
chomp; |
||||||
|
next if $_ !~ /^$mpath\|/; |
||||||
|
(undef, $json->{paths_num_total}, $json->{size}, $json->{features}, |
||||||
|
$json->{dm_st}, $json->{failures}, $json->{path_failures}) = split(/\s*\|\s*/, $_); |
||||||
|
# Cast to int |
||||||
|
foreach (qw(failures path_failures paths_num_total)){ |
||||||
|
$json->{$_} = 0 + $json->{$_}; |
||||||
|
} |
||||||
|
# Convert size to bytes |
||||||
|
my $unit = chop $json->{size}; |
||||||
|
if ($unit eq 'K'){ |
||||||
|
$json->{size} *= 1024; |
||||||
|
} elsif ($unit eq 'M'){ |
||||||
|
$json->{size} *= 1024 * 1024; |
||||||
|
} elsif ($unit eq 'G'){ |
||||||
|
$json->{size} *= 1024 * 1024 * 1024; |
||||||
|
} elsif ($unit eq 'T'){ |
||||||
|
$json->{size} *= 1024 * 1024 * 1024 * 1024; |
||||||
|
} elsif ($unit eq 'P'){ |
||||||
|
$json->{size} *= 1024 * 1024 * 1024 * 1024 * 1024; |
||||||
|
} |
||||||
|
# No need to process the other mpath here |
||||||
|
last; |
||||||
|
} |
||||||
|
|
||||||
|
# Now check status of every path |
||||||
|
@res = qx($multipathd show paths format "%m|%d|%t|%o|%T|%0|%z"); |
||||||
|
if ($? != 0){ |
||||||
|
push @{$json->{errors}}, "Failed to run multipathd show paths format"; |
||||||
|
} |
||||||
|
# Skip header line |
||||||
|
shift @res; |
||||||
|
foreach (@res){ |
||||||
|
chomp; |
||||||
|
next if $_ !~ /^$mpath\|/; |
||||||
|
my (undef, $dev, $dm_st, $dev_st, $chk_st, $failures, $serial) = split(/\s*\|\s*/, $_); |
||||||
|
push @{$json->{paths_details}}, { |
||||||
|
dev => $dev, |
||||||
|
dm_st => $dm_st, |
||||||
|
dev_st => $dev_st, |
||||||
|
chk_st => $chk_st, |
||||||
|
failures => $failures + 0, |
||||||
|
serial => $serial |
||||||
|
}; |
||||||
|
if ($dm_st eq 'active'){ |
||||||
|
$json->{paths_num_active} += 1; |
||||||
|
if ($dev_st ne 'running'){ |
||||||
|
$json->{paths_num_ko} += 1; |
||||||
|
push @{$json->{paths_with_issue}}, $dev; |
||||||
|
push @{$json->{errors}}, "dev $dev is not running"; |
||||||
|
} elsif ($chk_st ne 'ready' or $failures > 0){ |
||||||
|
$json->{paths_num_ko} += 1; |
||||||
|
push @{$json->{paths_with_issue}}, $dev; |
||||||
|
push @{$json->{errors}}, "dev $dev is not active"; |
||||||
|
} else { |
||||||
|
$json->{paths_num_ok} += 1; |
||||||
|
} |
||||||
|
} else { |
||||||
|
$json->{paths_num_inactive} += 1; |
||||||
|
} |
||||||
|
} |
||||||
|
# We want easy usage from zabbix, so turn thos ones to strings |
||||||
|
$json->{paths_with_issue} = join(',', @{$json->{paths_with_issue}}); |
||||||
|
$json->{errors} = join(',', @{$json->{errors}}); |
||||||
|
|
||||||
|
print to_json($json, { pretty => $pretty }); |
||||||
|
exit 0; |
@ -0,0 +1,31 @@ |
|||||||
|
#!/usr/bin/perl |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings; |
||||||
|
use JSON; |
||||||
|
use Getopt::Long; |
||||||
|
use File::Which; |
||||||
|
|
||||||
|
my $mpath = 1; |
||||||
|
my $pretty = 0; |
||||||
|
my $json = []; |
||||||
|
|
||||||
|
GetOptions( |
||||||
|
"mpath" => \$mpath, |
||||||
|
"pretty" => \$pretty |
||||||
|
); |
||||||
|
|
||||||
|
my $multipath = which('multipath'); |
||||||
|
|
||||||
|
if (not defined $multipath){ |
||||||
|
print to_json($json, { pretty => $pretty }); |
||||||
|
exit 0; |
||||||
|
} |
||||||
|
|
||||||
|
foreach (qx($multipath -l -v1)){ |
||||||
|
chomp; |
||||||
|
push @{$json}, { '{#MPATH_DEV}' => $_ }; |
||||||
|
} |
||||||
|
|
||||||
|
print to_json($json, { pretty => $pretty }); |
||||||
|
exit 0; |
Loading…
Reference in new issue