[Pkg-nagios-changes] [pkg-nagios-plugins-contrib] 01/01: check_multipath: Update to latest version 0.4.7
Jan Wagner
waja at moszumanska.debian.org
Sat Sep 10 16:42:32 UTC 2016
This is an automated email from the git hooks/post-receive script.
waja pushed a commit to branch master
in repository pkg-nagios-plugins-contrib.
commit fa1684b0e6ac70656f7a2656d8ffacca9111212e
Author: Jan Wagner <waja at cyconet.org>
Date: Sat Sep 10 18:36:46 2016 +0200
check_multipath: Update to latest version 0.4.7
---
check_multipath/check-multipath.pl | 559 +++++++++++++++++++++++++++++--------
check_multipath/control | 2 +-
2 files changed, 449 insertions(+), 112 deletions(-)
diff --git a/check_multipath/check-multipath.pl b/check_multipath/check-multipath.pl
index bd1440c..7ae3c0c 100644
--- a/check_multipath/check-multipath.pl
+++ b/check_multipath/check-multipath.pl
@@ -21,7 +21,7 @@
#-------------------------------------------------------------
#
#
-# Copyright (C) 2011-2015
+# Copyright (C) 2011-2016
# Hinnerk Rümenapf, Trond H. Amundsen, Gunther Schlegel, Matija Nalis,
# Bernd Zeimetz, Sven Anders, Ben Evans
#
@@ -53,7 +53,7 @@
# 0.1.5 add debian testcases and patch by Bernd Zeimetz
# 0.1.6 Added checklunline test for "-" character, thanks to Sven Anders <s.anders at digitec.de> also for test data (testcase 22)
# 0.1.7 Added test option
-# 0.1.8 Added Support for LUN names without HEX-ID (e.g. iSCSI LUNs)
+# 0.1.8 Added Support for LUN names without WWID (e.g. iSCSI LUNs)
# 0.1.9 Added extraconfig option
#
# 0.2.0 Improved flexibility, more testcases. Thanks to Benjamin von Mossner and Ben Evans
@@ -64,17 +64,22 @@
#
# 0.3.0 Added Option --ll, added handling of checker messages. Thanks to Andreas Steinel <Andreas.Steinel at exirius.de>
#
-# 0.4.0 Added check if multipathd is running (suggested by Dmitry Sakoun) 11. Dec. 2015
+# 0.4.0 Added check if multipathd is running (suggested by Dmitry Sakoun) 11. Dec. 2015
# Added --group option (based on comments by Robert Towster and Tom Schier)
-# 0.4.1 minor changes 14. Dec 2015
+# 0.4.1 minor changes 14. Dec. 2015
#
+# 0.4.5 distinguish between different attributes identifying a LUN (OPTIONAL) (based on suggestions by Séverin Launiau)
+# for output and extraconfig LUN-selector (see usage message)
+# Added ability to check counts of policies per LUN (suggested by Jim Clark)
+# Added ability to check counts of scsi-hosts and scsi-ids per LUN 3. Aug. 2016
+# 0.4.6 Bugfix (output)
+# 0.4.7 Compatibility with CentOS/RHEL 5-7: no "switch", check second directory for multipath binary (thanks to Christian Zettel) 25. Aug. 2016
#
-
use strict;
use warnings;
-use Switch;
+#use Switch; ## causes compatibility issues (perl version)
use POSIX qw(isatty);
use Getopt::Long qw(:config no_ignore_case);
@@ -93,7 +98,7 @@ use vars qw( $NAME $VERSION $AUTHOR $CONTACT $E_OK $E_WARNING $E_CRITICAL
# === Version and similar info ===
$NAME = 'check-multipath.pl';
-$VERSION = '0.4.1 14. DEC 2015';
+$VERSION = '0.4.7 25. AUG 2016';
$AUTHOR = 'Hinnerk Rümenapf';
$CONTACT = 'hinnerk [DOT] ruemenapf [AT] uni-hamburg [DOT] de (hinnerk [DOT] ruemenapf [AT] gmx [DOT] de)';
@@ -381,14 +386,14 @@ $SIG{__WARN__} = sub { push @perl_warnings, [@_]; };
." \\_ 2:0:1:3 sds 65:32 [active][undef]\n"
." \\_ 7:0:1:3 sdr 65:16 [active][undef]\n",
-#23. LUN without HEX-ID (iSCSI) thanks to Ernest Beinrohr <Ernest.Beinrohr at axonpro.sk>
+#23. LUN without WWID (iSCSI) thanks to Ernest Beinrohr <Ernest.Beinrohr at axonpro.sk>
"1STORAGE_server_target2 dm-2 IET,VIRTUAL-DISK\n"
."size=1.0T features='0' hwhandler='0' wp=rw\n"
."`-+- policy='round-robin 0' prio=0 status=active\n"
." |- 9:0:0:1 sdc 8:32 active undef running\n"
." `- 10:0:0:1 sdd 8:48 active undef running\n",
-#24. LUN without HEX-ID (iSCSI) thanks to Ernest Beinrohr <Ernest.Beinrohr at axonpro.sk>
+#24. LUN without WWID (iSCSI) thanks to Ernest Beinrohr <Ernest.Beinrohr at axonpro.sk>
"1STORAGE_server_target2 dm-2 IET,VIRTUAL-DISK\n"
."size=1.0T features='0' hwhandler='0' wp=rw\n"
."`-+- policy='round-robin 0' prio=1 status=active\n"
@@ -473,14 +478,49 @@ $SIG{__WARN__} = sub { push @perl_warnings, [@_]; };
."| `- 1:0:2:11 sdau 66:224 active ready running\n"
."`-+- policy='round-robin 0' prio=10 status=enabled\n"
." |- 0:0:3:11 sdz 65:144 active ready running\n"
-." `- 1:0:3:11 sdba 67:64 active ready running\n"
+." `- 1:0:3:11 sdba 67:64 active ready running\n",
+
+#32. thanks to Séverin Launiau
+"3600a098038303039492b473242384661 dm-19 NETAPP ,LUN C-Mode\n"
+."size=5.0T features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='1 alua' wp=rw\n"
+."|-+- policy='service-time 0' prio=50 status=active\n"
+."| `- 7:0:0:0 sdb 8:16 active ready running\n"
+."`-+- policy='service-time 0' prio=10 status=enabled\n"
+." `- 11:0:0:0 sdg 8:96 active ready running\n"
+."360a98000375432714a3f336733636843 dm-3 NETAPP ,LUN\n"
+."size=10T features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='0' wp=rw\n"
+."`-+- policy='service-time 0' prio=2 status=active\n"
+." |- 8:0:0:0 sdd 8:48 active ready running\n"
+." |- 9:0:0:0 sde 8:64 active ready running\n"
+." |- 10:0:0:0 sdf 8:80 active ready running\n"
+." `- 12:0:0:0 sdi 8:128 active ready running\n"
+."3600a098038303039365d4671616a756e dm-2 NETAPP ,LUN C-Mode\n"
+."size=150G features='4 queue_if_no_path pg_init_retries 50 retain_attached_hw_handle' hwhandler='1 alua' wp=rw\n"
+."|-+- policy='service-time 0' prio=50 status=active\n"
+."| `- 11:0:0:1 sdh 8:112 active ready running\n"
+."`-+- policy='service-time 0' prio=10 status=enabled\n"
+." `- 7:0:0:1 sdc 8:32 active ready running\n"
);
+
# Commands with full path
$SUDO = '/usr/bin/sudo';
-$MULTIPATH_LIST_LONG = '/sbin/multipath -ll';
-$MULTIPATH_LIST = '/sbin/multipath -l';
-$MULTIPATH_RELOAD = '/sbin/multipath -r';
+
+
+# check path for multipath command
+my $multipathCmd = '/usr/sbin/multipath';
+if (! -e $multipathCmd ) {
+ $multipathCmd = '/sbin/multipath';
+ if ( ! -e $multipathCmd ) {
+ $multipathCmd = '';
+ } # if
+} # if
+
+# commands with options
+$MULTIPATH_LIST_LONG = $multipathCmd.' -ll';
+$MULTIPATH_LIST = $multipathCmd.' -l';
+$MULTIPATH_RELOAD = $multipathCmd.' -r';
+
# Exit codes
$E_OK = 0;
@@ -521,6 +561,9 @@ see:
http://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check-2Dmultipath-2Epl/details
http://www.nagios.org/documentation
+The number of parameters and options has increased over the time, as a result of feature requests by users.
+You might not need most of them.
+
A configuration for a specific LUN name via --extraconfig has highest priority and overrides group and global config.
If a regex defined in --group matches a LUN line the specified group values are used. (First regex in List, checked from left to right)
Otherwise the global defaults are used (--min-paths, --ok-paths).
@@ -531,6 +574,17 @@ OPTIONS:
-n, --no-multipath Exitcode for no LUNs, no multipath driver and multipathd not running [warning]
-M, --mdskip Skip extra check if multipathd is running (check uses '--no-multipath' returncode)
+ -a, --addchecks define low/high marks for additional checks
+ number of policies per LUN p,<LOW>,<HIGH> DEFAULT: p,0,0
+ number of scsi-hosts per LUN sh,<LOW>,<HIGH> DEFAULT: sh,0,0
+ number of scsi-ids, per LUN si,<LOW>,<HIGH> DEFAULT: si,0,0
+ e.g. 'p,1,2,sh,1,2'; 'si,1,2,p,1,2,sh,2,4'; 'p,1,2'
+ See documentation of multipath output. If the HIGH value is 0, the check is skipped.
+ A typical standard-configuration uses 2 scsi-hosts and 2 scsi-ids, resulting in four paths
+ representing all possible combinations: h0-i0, h0-i1, h1-i0, h1-i1.
+
+ --scsi-all Count all scsi-hosts and scsi-ids, even from paths that report an error state.
+
-r, --reload force devmap reload if status is WARNING or CRITICAL
(multipath -r)
Can help to pick up LUNs coming back to life.
@@ -548,19 +602,42 @@ OPTIONS:
-g, --group Specify perl-regex to identify groups of LUNs with other default-thresholds.
Overrides global config for LUNs with LUN lines that math a group regex.
In most cases a simple String should be sufficient. NOTE: special regex characters must be escaped!
- "<LUN_LINE_REGEX>,<LOW>,<HIGH>:" for each group with deviant thresholds
- e.g. "IBM,ServeRAID,1,1:HAL,ChpRAID,1,2:"
+ "<LUN_LINE_REGEX>,<LOW>,<HIGH>[@#,<ADDCHECKS>]:" for each group with deviant thresholds (see explanation of --addchecks)
+ e.g. "IBM,ServeRAID,1,1:HAL,ChpRAID,1,2:" or "IBM,ServeRAID,1,1@#,p,1,2:HAL,ChpRAID,1,2@#,sh,1,2,si,1,2:"
Use command multipath -l to see the LUN lines and to identify groups.
-e, --extraconfig Specify different low/high thresholds for LUNs.
Overrides group and global config for the specified LUNs.
- optional: specify return code if no data for LUN name was found
+ optional: specify return code if no data for LUN selector was found
(ok, warning, critical), default is warning
- "<LUN>,<LOW>,<HIGH>[,<RETURNCODE>]:" for each LUN with deviant thresholds
+ the return code MAY be followed by definitions of additional check, see explanation of --addchecks above
+ "<LUN-selector>,<LOW>,<HIGH>[,<RETURNCODE>[,<ADDCHECKS>]]:" for each LUN with deviant thresholds
e.g. "iscsi_lun_01,2,2:dummyLun,1,1,ok:paranoid_lun,8,16,critical:"
- "oddLun,3,5,critical:"
- "default,2,4,warning:DonalLunny,6,8:"
- Use option -v to see LUN names used by this plugin.
+ "oddLun,3,5:"
+ "paranoidOddLun,5,11,critical,p,3,5,sh,5,9,si,3,7:"
+ "default,2,4,warning:DonalLunny,6,8,warning,sh,1,4,si,1,4:"
+
+ <LUN-selector> is by default checked against the "generic Name", as used in older plugin versions.
+ You can specify a prefix to select a LUN attribute as identifier.
+ Not all attributes may be available, depending on the specific multipath configuration.
+ Use command multipath -l to see the complete LUN lines.
+ "G!" generic name, as used in older versions. Exists always. Content depends on the specific configuration. DEFAULT
+ "W!" WWID as reported by the multipath command
+ "D!" dm Identifier (dm-3 or similar)
+ "N!" user-firendly name
+ e.g. 'W!36000d774000045f655ea91cb4ea41d6f,4,8,critical:DonalLunny,6,8:D!dm-3,1,2,warning,sh,1,2,si,1,2:'
+ NOTE: enclose parameter value in SINGLE-quotes for this notation!
+
+ -p, --print List to determine which attribute of the LUN should be printed as identifier in the output
+ The letters in the list are checked from left to right, the first coresponding attribute that exists is printed.
+ The letter G is always appended to the list.
+ Avalible are:
+ G: generic name, as used in older versions. Exists always. Content depends on the specific configuration.
+ W: WWID as reported by the multipath command
+ D: dm Identifier (dm-3 or similar)
+ N: user-firendly name
+ e.g. "DN": print dm-identifier (if present), else user friendly name (if present) else generic name (as G is always appended to the list)
+ "WDN": print WWID (if present), else print dm-identifier (if present), else user friendly name (if present) else generic name (as G ist always appended to the list)
-s, --state Prefix alerts with alert state
-S, --short-state Prefix alerts with alert state abbreviated
@@ -586,7 +663,7 @@ $LICENSE = <<"END_LICENSE";
$NAME $VERSION
-Copyright (C) 2011-2014 $AUTHOR
+Copyright (C) 2011-2016 $AUTHOR
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
@@ -623,8 +700,30 @@ END_LICENSE
'll' => 0,
'mdskip' => 0,
'group' => '',
+ 'print' => '',
+ 'scsi-all' => 0,
+ 'addchecks' => '',
+ );
+
+
+# the hash keys define the valid check identifiers. only \w characters for IDs!
+# Initialize the hash with defaults (no checks)
+my %addChecks
+ = (
+ 'sh' => [0,0], # scsi-hosts
+ 'si' => [0,0], # scsi-ids
+ 'p' => [0,0], # policies
);
+# short human readable description
+my %addCheckNames
+ = (
+ 'sh' => 'scsi-hosts',
+ 'si' => 'scsi-ids',
+ 'p' => 'policies',
+ );
+
+
# Get options
GetOptions(#'t|timeout=i' => \$opt{timeout},
'h|help' => \$opt{'help'},
@@ -643,6 +742,9 @@ GetOptions(#'t|timeout=i' => \$opt{timeout},
'L|ll' => \$opt{'ll'},
'M|mdskip' => \$opt{'mdskip'},
'g|group=s' => \$opt{'group'},
+ 'p|print=s' => \$opt{'print'},
+ 'scsi-all' => \$opt{'scsi-all'},
+ 'a|addchecks=s' => \$opt{'addchecks'},
) or do { print $USAGE; exit $E_UNKNOWN };
# If user requested help
@@ -671,6 +773,66 @@ if ($opt{'version'}) {
#alarm $opt{timeout};
+
+#---------------------------------------
+#
+# Initialise a hash with current addcheck defaults
+# copy the arrays, not just the references!
+#
+sub getNewAddCheckHash {
+ my %h;
+
+ foreach my $k (keys %addChecks) {
+ #print "getNewAddCheckHash : '$k'\n";
+ my @arr = @{$addChecks{$k}};
+ $h{$k}= \@arr;
+ } # foreach
+
+ return \%h;
+} # sub
+
+
+#---------------------------------------
+#
+# analyse definition of additional checks, write check-values to referenced hash
+#
+sub getAddChecks {
+ my ($inString, $rOuthash, $errPrefix) = @_;
+
+ if ( !defined($inString) ) { # undefined or empty means no change
+ return;
+ } elsif ($inString eq '') {
+ return;
+ } # if
+
+ if ( !defined($errPrefix) ) { # errorPrefix should give information about the call context
+ $errPrefix = '';
+ } # if
+
+ if ($inString !~ m!^\w+,\d+,\d+(,\w+,\d+,\d+)*$! ) {
+ unknown_error($errPrefix."invalid addcheck definition: '$inString', syntax error. See help information.");
+ } # if
+
+ while ($inString =~ m!(\w+),(\d+),(\d+)!g) {
+ my ( $id, $low, $high ) = ($1, $2, $3);
+ #print "AddCheck: id='$id', low='$low', high='$high', errprefix='$errPrefix'\n";
+
+ if ( defined($$rOuthash{$id}) ) { # hash keys define valid ids
+ if ( $low <= $high ) { # make sure low and high value are in the right order
+ @{$$rOuthash{$id}} = ($low, $high); # only set values found in input string, leave the others untouched
+ } else {
+ unknown_error($errPrefix."invalid addcheck definition for id '$id', low value bigger than high value. See help information.");
+ } # if
+ } else {
+ unknown_error($errPrefix."invalid addcheck identifier '$id' in '$inString', syntax error. See help information.");
+ } # if
+ } # while
+} # sub
+
+#---------------------------------------
+
+
+
# Default line break
$linebreak = isatty(*STDOUT) ? "\n" : '<br/>';
@@ -688,23 +850,31 @@ if (defined $opt{linebreak}) {
}
} # if
+# Analyse additional check definitions. Parameter sets defaults
+# exit on Error
+getAddChecks( $opt{'addchecks'}, \%addChecks, "Parameter '--addchecks'; " );
+
# group option
my @group = ();
-#print "--group='".$opt{'group'}.$opt{'group'}."'\n";
+#print "--group='".$opt{'group'}."'\n";
if ($opt{'group'} ne '') {
- if ( $opt{'group'} !~ m!^(.+?,\d+,\d+:)+$! ) {
+ if ( $opt{'group'} !~ m!^(.+?,\d+,\d+(?:@#(,\w+,\d+,\d+)*)?:)+$! ) {
unknown_error("Wrong usage of '--group' option: '"
. $opt{'group'}
. "' syntax error. See help information.");
} # if
- while ( $opt{'group'} =~ m!(.+?),(\d+),(\d+):!g ) {
- my $regex =$1;
- my $crit =$2;
- my $warn =$3;
- #print "GROUP: Regex='$regex', c=$crit, w=$warn\n";
+ while ( $opt{'group'} =~ m/(.+?),(\d+),(\d+)(?:@#,([\w\d,]+))?:/g ) {
+ my $regex = $1;
+ my $crit = $2;
+ my $warn = $3;
+ my $addchecks = $4;
+ if ( !defined($addchecks) ) {
+ $addchecks = '';
+ } # if
+ #print "GROUP: Regex='$regex', c=$crit, w=$warn, addchecks='$addchecks'\n";
if ($crit > $warn) {
unknown_error("Error in '--group' option '"
@@ -712,40 +882,63 @@ if ($opt{'group'} ne '') {
. "' for group rule '$regex': critical threshold ($crit) must not be higher than warning threshold ($warn).");
} # if
- push ( @group, { 'regex' => $regex, 'warn' => $warn, 'crit' => $crit } );
+ my $rHash = getNewAddCheckHash(); # initialise with default
+ getAddChecks( $addchecks, $rHash, "Parameter '--group'; " );
+ push ( @group, { 'regex' => $regex, 'warn' => $warn, 'crit' => $crit, 'addchecks' => $rHash } );
} # while
} # if
+# print option
+$opt{'print'} .= 'G'; # last resort: "generic name" (always present) als default
+if ($opt{'print'} !~ m!^[GWND]+$!) {
+ unknown_error("Error in '--print' option: invalid character in value '". $opt{'print'} ."'. Please check usage.");
+} # if
+
+
# extraconfig option
-my %extraconfig = ();
+my @extraconfig = ();
if ($opt{extraconfig} ne '') {
- if ( $opt{extraconfig} !~ m!^([\w\-]+,\d+,\d+(?:,(?:ok|warning|critical))?:)+$! ) {
+ if ( $opt{extraconfig} !~ m/^([GWDN]!)?([\w\-]+,\d+,\d+(?:,(?:ok|warning|critical)(?:,\w+,\d+,\d+)*)?:)+$/ ) {
unknown_error("Wrong usage of '--extraconfig' option: '"
. $opt{extraconfig}
. "' syntax error. See help information.");
} # if
- while ( $opt{extraconfig} =~ m!([\w\-]+),(\d+),(\d+)(?:,(ok|warning|critical))?:+!g ) {
- my $name =$1;
- my $crit =$2;
- my $warn =$3;
- my $ret = $4;
- my $missingRet=$E_WARNING;
+ #print "EXTRA-Param '$opt{extraconfig}'\n";
+ while ( $opt{extraconfig} =~ m/(?:([GWDN])!)?([\w\-]+),(\d+),(\d+)(?:,(ok|warning|critical)(?:,([\w\d,]+))?)?:+/g ) {
+ my $attribute = $1;
+ my $attribValue = $2;
+ my $crit = $3;
+ my $warn = $4;
+ my $ret = $5;
+ my $addchecks = $6;
+ my $missingRet = $E_WARNING; # set default
- if ( defined($ret) ) {
+ if ( defined($ret) ) { # if retcode is given: convert and store
$missingRet=$text2exit{$ret};
- }
- #print "EXTRA: $name, c=$crit, w=$warn, m=$missingRet, '$ret'\n";
+ } else {
+ $ret = '#UNDEF#';
+ } # if
+ if ( !defined($addchecks) ) {
+ $addchecks = '';
+ } # if
+ if ( !defined($attribute) ) {
+ $attribute = 'G'; # DEFAULT: generic Name
+ } # if
+
+ #print "EXTRA: attrib='$attribute', val='$attribValue', c=$crit, w=$warn, m=$missingRet, '$ret', addchecks='$addchecks'\n";
if ($crit > $warn) {
unknown_error("Error in '--extraconfig' option '"
. $opt{extraconfig}
- . "' for LUN '$name': critical threshold ($crit) must not be higher than warning threshold ($warn).");
+ . "' for LUN selector '".$attribute.'!'.$attribValue."': critical threshold ($crit) must not be higher than warning threshold ($warn).");
} # if
- $extraconfig{$name} = {'warn' => $warn, 'crit' => $crit, 'missingRet' => $missingRet, 'found' => 0 };
+ my $rHash = getNewAddCheckHash (); # initialise with default
+ getAddChecks( $addchecks, $rHash, "Parameter '--extraconfig'; " );
+ push ( @extraconfig, {'attrib' => $attribute, 'val' =>$attribValue, 'warn' => $warn, 'crit' => $crit, 'missingRet' => $missingRet, 'addchecks' => $rHash, 'found' => 0 });
} # while
} # if
@@ -804,11 +997,11 @@ sub report {
sub unknown_error {
my $msg = shift;
- my $hostname = qx('hostname'); # add hostname to error message
- chomp $hostname;
if ($opt{"test"}) {
print "ERROR: $msg |TESTCASE|\n";
} else {
+ my $hostname = qx('hostname'); # add hostname to error message
+ chomp $hostname;
print "ERROR: $msg |Host: $hostname|\n";
}
exit $E_UNKNOWN;
@@ -816,6 +1009,29 @@ sub unknown_error {
#---------------------------------------
#
+# get attribute to print from LUN data
+#
+sub getLunPrintName {
+ my ( $rLunDef ) = @_;
+
+ my $lunPrintName = 'UNDEF';
+ my $displayPrio = $opt{'print'};
+ for(my $i = 0; $i < length($displayPrio); $i++) { # all characters in prio-string
+ my $c = substr ($displayPrio, $i, 1);
+ #print "i=$i, c='$c'\n";
+ if ($$rLunDef{$c}) { # first non-empty attribute wins
+ $lunPrintName = $$rLunDef{$c};
+ #print "FOUND: $lunPrintName i=$i, c='$c'\n";
+ last;
+ } # if
+ } # for
+
+ return $lunPrintName;
+} # sub
+
+
+#---------------------------------------
+#
# get output of multipath -l
# or debug input (testcase)
#
@@ -885,38 +1101,70 @@ sub checkLunLine {
my ($textLine, $rCurrentLun, $rLunData) = @_;
#print "checkLunLine: '$textLine'\n";
+ my $idGeneric = '';
+ my $idWWID = '';
+ my $idDm = '';
+ my $idName = '';
+
# mpathb (36000d774000045f655ea91cb4ea41d6f) dm-1 FALCON,IPSTOR DISK
# mpathb (36000d774000045f655ea91cb4ea41d6f) dm-1
# MYVOLUME (36005076801810523100000000000006f)
# tex-lun4 (3600000e00d0000000002161200120000) dm-7 FUJITSU ,ETERNUS_DXL
# fc-p6-vicepb (1Proware_FF010000333001EC) dm-1 Proware,R_laila thanks to Michal Svamberg
- if ($textLine =~ m/^([\w\-]+) \s+ \([\w\-]+\)/x) {
+ #if ($textLine =~ m/^([\w\-]+) \s+ \([\w\-]+\)/x) {
+ if ($textLine =~ m/^([\w\-]+) \s+ \(([\w\-]+)\) (?: \s+ ([\w\-]+))?/x) {
$$rCurrentLun = $1;
- #report("named LUN $$rCurrentLun found", $E_OK);
+ $idGeneric = $1;
+ $idName = $1;
+ $idWWID = $2;
+ $idDm = $3;
+
+ if ( !defined($idDm) ) {
+ $idDm ='';
+ }
+ #report("named LUN $$rCurrentLun found, G='$idGeneric', W='$idWWID', D='$idDm', N='$idName'", $E_OK);
}
# 36006016019e02a00d009495ddbf3e011 dm-2 DGC,VRAID
- elsif ($textLine =~ m/^[0-9a-fA-F]+ \s+ ([\w\-\_]+)/x) {
- $$rCurrentLun = $1;
- #report("simple (1) LUN $$rCurrentLun found", $E_OK);
+ # 360a98000503361754b5a58724f6f7a59 dm-2 NETAPP ,LUN
+ # 360a98000503361754b5a58724f6f7a59 dm-2 NETAPP ,LUN C-Mode
+ #elsif ($textLine =~ m/^[0-9a-fA-F]+ \s+ ([\w\-\_]+)/x) {
+ elsif ($textLine =~ m/^([0-9a-fA-F]+) \s+ ([\w\-\_]+)/x) {
+ $$rCurrentLun = $2;
+ $idGeneric = $2;
+ $idWWID = $1;
+ $idDm = $2;
+ #report("simple (1) LUN $$rCurrentLun found, G='$idGeneric', W='$idWWID', D='$idDm', N='$idName'", $E_OK);
}
# 360a98000503361754b5a58724f6f7a59dm-2 NETAPP ,LUN
- elsif ($textLine =~ m/^[0-9a-fA-F]{3,33} \s* ([\w\-\_]+) \s+/x) {
- $$rCurrentLun = $1;
- #report("simple (2) LUN $$rCurrentLun found", $E_OK);
+ #elsif ($textLine =~ m/^[0-9a-fA-F]{3,33} \s* ([\w\-\_]+) \s+/x) {
+ elsif ($textLine =~ m/^([0-9a-fA-F]{33}) ([\w\-]+) \s+ ([\w\-\_]+)/x) {
+ $$rCurrentLun = $2;
+ $idGeneric = $2;
+ $idWWID = $1;
+ $idDm = $2;
+ #report("simple (2) LUN $$rCurrentLun found, G='$idGeneric', W='$idWWID', D='$idDm', N='$idName'", $E_OK);
}
# iscsi-LUN example
# 1STORAGE_server_target2 dm-2 IET,VIRTUAL-DISK
- #elsif ($textLine =~ m/^([\w\-]+) \s+ [a-z]+\-\d+/x) {
- elsif ($textLine =~ m/^([\w\-]+) \s+ [a-z]+\-\d+ \s+ [\w\-\,]+/x) {
+ #elsif ($textLine =~ m/^([\w\-]+) \s+ [a-z]+\-\d+ \s+ [\w\-\,]+/x) {
+ elsif ($textLine =~ m/^([\w\-_]+) \s+ ([\w\-]+) \s+ [\w\-\_]+/x) {
$$rCurrentLun = $1;
- #report("LUN without HEX-ID $$rCurrentLun found", $E_OK);
+ $idGeneric = $1;
+ $idName = $1;
+ $idDm = $2;
+
+ #report("LUN without WWID $$rCurrentLun found, G='$idGeneric', W='$idWWID', D='$idDm', N='$idName'", $E_OK);
}
else {
return 0; ## Not a LUN line, stop here and return zero
} # if
# initialise data of found LUN
- ${$rLunData}{$$rCurrentLun} = { 'paths' => 0, 'lunline' => $textLine };
+ ${$rLunData}{$$rCurrentLun} = { 'paths' => 0, 'policies' => 0,
+ 'lunline' => $textLine,
+ 'G' => $idGeneric, 'W' => $idWWID, 'D' => $idDm, 'N' => $idName,
+ 'sh-hash' => {}, 'si-hash' => {}
+ };
return 1;
} # sub
@@ -926,7 +1174,7 @@ sub checkLunLine {
# check if text is a policy description line
#
sub checkPolicyLine {
- my ($textLine) = @_;
+ my ($textLine, $currentLun, $rLunData) = @_;
#print "checkPolicyLine: '$textLine'\n";
# `-+- policy='round-robin 0' prio=-1 status=active
@@ -937,6 +1185,8 @@ sub checkPolicyLine {
# _ round-robin 0 active
#if ( $textLine =~ m/^[|\`\-\+_\s]+ \s+ (?:policy=\')?[\w\.\-\_]+ \s \d(?:\')? \s+ prio=/x ) {
if ( $textLine =~ m/^[|\`\-\+_\s]+ \s+ (?:policy=\')?[\w\.\-\_]+ \s \d(?:\')? \s+ \w+/x ) {
+ ${$$rLunData{$currentLun}}{'policies'}++;
+ #print "checkPolicyLine: found policy no. ".${$$rLunData{$currentLun}}{'policies'}."\n";
return 1;
} else {
return 0;
@@ -960,10 +1210,8 @@ sub checkMultipathText {
foreach my $textLine (@$rTextArray) {
$i++;
#print "$i:\n";
- switch($state) {
- # initial state: look for path state, new LUN Name, policy
- case "pathDesc"
- { # check for path status line
+ if ($state eq 'pathDesc') { # initial state: look for path state, new LUN Name, policy
+ # check for path status line
# |- 3:0:0:1 sdf 8:80 active undef running
## \_ 3:0:1:1 sde 8:64 [active][undef]
## _ 3:0:1:1 sde 8:64 active undef
@@ -976,47 +1224,65 @@ sub checkMultipathText {
# (thanks to Ben Evans)
# `- #:#:#:# - #:# active undef running
- #if ( $textLine =~ m/^[\s_\|\-\`\\\+]+ [\d\:]+ \s+ (\w+) \s+ [\d\:]+ \s+ \w+ \s+ \w+/xi ) {
- if ( $textLine =~ m/^[\s_\|\-\`\\\+]+ [#\d\:]+ \s+ ([\w\-]+) \s+ [#\d\:]+ \s+ \w+/xi ) {
- my $pathName = $1;
- #print "'$textLine', ";
- #print "LUN '$currentLun', path '$pathName'\n";
+ #if ( $textLine =~ m/^[\s_\|\-\`\\\+]+ [#\d\:]+ \s+ ([\w\-]+) \s+ [#\d\:]+ \s+ \w+/xi ) {
+ if ( $textLine =~ m/^[\s_\|\-\`\\\+]+ ([#\d]+):[#\d]+:([#\d]+):[#\d]+ \s+ ([\w\-]+) \s+ [#\d\:]+ \s+ \w+/xi ) {
+ my $sh = $1;
+ my $si = $2;
+ my $pathName = $3;
+ my $ok = 0;
+
+ my $rLunData = $lunData{$currentLun};
+
+ #print "pathDesc: [$textLine], ";
+ #print "LUN '$currentLun', path '$pathName', sh='$sh', si='$si'\n";
if ($textLine =~ m/fail|fault|offline|shaky/) { # fail or fault, offline or shaky?
#print "ERROR: $textLine\n";
- report("LUN $currentLun, path $pathName: ERROR.", $E_WARNING);
+ report("LUN ".getLunPrintName ($rLunData).", path $pathName: ERROR.", $E_WARNING);
}
elsif ($textLine !~ m/\sactive\s/) { # path is active?
#print "NOT active: $textLine\n";
- report("LUN $currentLun, path $pathName: NOT active.", $E_WARNING);
+ report("LUN ".getLunPrintName ($rLunData).", path $pathName: NOT active.", $E_WARNING);
}
elsif ($pathName eq "-") { # empty path name => path is missing (thanks to Ben Evans)
- report("LUN $currentLun: missing path (empty path name)", $E_WARNING);
+ report("LUN ".getLunPrintName ($rLunData).": missing path (empty path name)", $E_WARNING);
}
else {
if ( $currentLun eq "") { # YES => check logic, increase path count for LUN
unknown_error ("Path info before LUN name. Line $i:\n'$textLine'")
}
- ${$lunData{$currentLun}}{'paths'}++;
+ $$rLunData{'paths'}++;
+ $ok =1;
} # if
- } # check for new LUN name
+
+
+ if ( $ok || $opt{'scsi-all'}) { # if path is OK or ALL paths are to be counted
+ if ($sh =~ m!^\d+$! ) {
+ ${$$rLunData{'sh-hash'}}{$sh}=1; # store scsi-host as hash key
+ } # if
+
+ if ($si =~ m!^\d+$! ) {
+ ${$$rLunData{'si-hash'}}{$si}=1; # store scsi-id as hash key
+ } # if
+ } # if
+ } # check for new LUN name
elsif ( checkLunLine ($textLine, \$currentLun, \%lunData) ) {
$state="lunInfo";
- } # check for new LUN name
- elsif ( ($currentLun ne "") && checkPolicyLine ($textLine) ) {
+ } # check for new LUN name
+ elsif ( ($currentLun ne "") && checkPolicyLine ($textLine, $currentLun, \%lunData) ) {
; # SKIP NESTED POLICY
}
elsif ( $textLine =~ m/checker msg is /) {
; # SKIP tur message stuff
}
- else { # error: unknown line format
+ else { # error: unknown line format
unknown_error ("Line $i not recognised. Expected path info, new LUN or nested policy:\n'$textLine'")
}
} # case
# after new LUN was found skip the INFO-Line (nothing else...)
- case "lunInfo" {
- if ( $currentLun eq "" ) { # check logic
+ elsif ($state eq 'lunInfo') {
+ if ( $currentLun eq "" ) { # check logic
unknown_error ("No current LUN while looking for LUN info. Line $i:\n'$textLine'")
}
# size=2.0T features='1 queue_if_no_path' hwhandler='0' wp=rw
@@ -1028,19 +1294,19 @@ sub checkMultipathText {
#if ($textLine =~ m/^\s*size=[\w\.]+\s+features=/x) {
if ($textLine =~ m/^\s*size=[\w\.]+\s+ ([a-zA-Z]+\s+)? features=/x) {
$state = "pathPolicy";
- } else { # error: unknown line format
+ } else { # error: unknown line format
unknown_error ("Line $i not recognised. Expected LUN info:\n'$textLine'")
}
} # case
# after LUN info was found skip the path policy (nothing else...)
# or handle new LUN if no paths available
- case "pathPolicy" {
+ elsif ($state eq 'pathPolicy') {
if ( $currentLun eq "") { # check logic
unknown_error ("No current LUN while looking for path policy. Line $i:\'$textLine'")
}
- if ( checkPolicyLine ($textLine) ) {
+ if ( checkPolicyLine ($textLine, $currentLun, \%lunData)) {
$state = "pathDesc";
} # new LUN found
elsif ( checkLunLine ($textLine, \$currentLun, \%lunData) ) {
@@ -1048,13 +1314,59 @@ sub checkMultipathText {
} else { # error: unknown line format
unknown_error ("Line $i not recognised. Expected path policy or new LUN:\n'$textLine'")
}
- } # case
- } # switch
+ }
+ else {
+ unknown_error ("Internal error: unknown state '$state' of parser")
+ } # if
} # foreach
return \%lunData
} # sub
+
+
+#---------------------------------------
+#
+# test value
+#
+sub testValue {
+ my ($val, $low, $high, $lunPrintName, $txtErr, $txtOk) = @_;
+
+ if ( !defined($txtOk) ) {
+ $txtOk = '';
+ } elsif ($txtOk ne '') {
+ $txtOk .= ' ';
+ } #if
+
+ #print "TEST val='$val', low='$low', high='$high', LUN='$lunPrintName', txtErr='$txtErr', txtOk='$txtOk'\n";
+
+ if ($val < $low){
+ report("LUN $lunPrintName: less than $low $txtErr ($val/$high)!", $E_CRITICAL);
+ } elsif ($val < $high){
+ report("LUN $lunPrintName: less than $high $txtErr ($val/$high).", $E_WARNING);
+ } else {
+ report("LUN $lunPrintName: $txtOk$val/$high.", $E_OK);
+ } # if
+} # sub
+
+#---------------------------------------
+#
+# test additional checks
+#
+sub testAddChecks {
+ my ($rDefHash, $rValueHash, $lunPrintName) = @_;
+
+ foreach my $id (sort keys %{$rDefHash} ) {
+ my $rDefArr = $$rDefHash{$id};
+
+ if ($$rDefArr[1] > 0 ) { # high mark 0 => NO check
+ testValue ($$rValueHash{$id}, $$rDefArr[0], $$rDefArr[1], $lunPrintName, $addCheckNames{$id}, $addCheckNames{$id});
+ } else {
+ #print "SKIP $$rValueHash{$id}, $$rDefArr[0], $$rDefArr[1], $lunPrintName, $addCheckNames{$id}, $addCheckNames{$id} \n"
+ }# if
+ } # foreach
+} # sub
+
#=====================================================================
# Main program
#=====================================================================
@@ -1079,6 +1391,12 @@ if ( !$opt{'mdskip'} ) { # check is not
} # if
+if ( ($opt{'di'} == 0) && ($multipathCmd eq '') ) {
+ # No testcase called and no multipath binary found
+ unknown_error ("No multipath binary found. Unable to perform check.");
+} # if
+
+
my $mpListCmd = $MULTIPATH_LIST;
if ($opt{'ll'}) {
$mpListCmd = $MULTIPATH_LIST_LONG;
@@ -1099,48 +1417,67 @@ if (scalar keys %lunData == 0) {
# Check path count for each LUN
#
foreach my $lunName ( sort {$a cmp $b} keys %lunData) {
- my $rLunDef = $lunData{$lunName};
- my $pathCount = $$rLunDef{'paths'};
- my $lunLine = $$rLunDef{'lunline'};
-
- my $warn = $opt{'ok-paths'};
- my $crit = $opt{'min-paths'};
-
- # $extraconfig{$name} = {'warn' => $warn, 'crit' => $crit};
- if (defined ($extraconfig{$lunName}) ) { # deviant thresholds for THIS LUN from options?
- $warn = ${$extraconfig{$lunName}}{'warn'};
- $crit = ${$extraconfig{$lunName}}{'crit'};
- #print "$lunName: $pathCount EXTRA: crit=$crit, warn=$warn\n";
- ${$extraconfig{$lunName}}{'found'} = 1;
- } else { # LUN-Line matches a group definition?
- foreach my $rGroupDef ( @group ) {
+ my $rLunDef = $lunData{$lunName};
+ my $pathCount = $$rLunDef{'paths'};
+ my $policiesCount = $$rLunDef{'policies'};
+ my $lunLine = $$rLunDef{'lunline'};
+
+ my $warn = $opt{'ok-paths'};
+ my $crit = $opt{'min-paths'};
+
+ my $rAddChecks = \%addChecks; # initialise with default
+
+ # Get the LUN-ID to be displayed, a 'G' in appended to the option-string at parameter check
+ my $lunPrintName = getLunPrintName ($rLunDef);
+
+ # check if an extraconfig entry matches
+ my $extraconfigMatched = 0;
+ foreach my $rExtraConf( @extraconfig ) {
+ if ( $$rExtraConf{'val'} eq $$rLunDef{$$rExtraConf{'attrib'}}) {
+ $warn = $$rExtraConf{'warn'};
+ $crit = $$rExtraConf{'crit'};
+
+ $rAddChecks = $$rExtraConf{'addchecks'};
+ $$rExtraConf{'found'} = 1;
+ $extraconfigMatched = 1;
+ #print "EXTRA: ".$$rExtraConf{'attrib'}."!".$$rExtraConf{'val'}." c=$crit w=$warn \n";
+ last;
+ } # if
+ } # foreach
+
+ if ( !$extraconfigMatched ) { # NO extaconfig entry matched
+ foreach my $rGroupDef ( @group ) { # LUN-Line matches a group definition?
my $regex = ${$rGroupDef}{'regex'};
#print "GRP: '$regex'\n";
if ($lunLine =~ m!$regex! ) {
- $warn = ${$rGroupDef}{'warn'};
- $crit = ${$rGroupDef}{'crit'};
- #print "GRP: '$regex' MATCH: c=$crit w=$warn \n";
+ $warn = ${$rGroupDef}{'warn'};
+ $crit = ${$rGroupDef}{'crit'};
+ $rAddChecks = ${$rGroupDef}{'addchecks'};
+ #print "GRP: '$regex' MATCH: c=$crit w=$warn\n";
last;
- }
+ } # if
} # foreach
}# if
+
+ #print "LUN '$lunPrintName'\n";
- if ($pathCount < $crit){
- report("LUN $lunName: less than $crit paths ($pathCount/$warn)!", $E_CRITICAL);
- } elsif ($pathCount < $warn){
- report("LUN $lunName: less than $warn paths ($pathCount/$warn).", $E_WARNING);
- } else {
- report("LUN $lunName: $pathCount/$warn.", $E_OK);
- }
+ testValue ($pathCount, $crit, $warn, $lunPrintName, 'paths', '' );
+
+ my %addCheckValues = (
+ 'sh' => scalar( keys %{$$rLunDef{'sh-hash'}}),
+ 'si' => scalar( keys %{$$rLunDef{'si-hash'}}),
+ 'p' => $policiesCount
+ );
+ testAddChecks ( $rAddChecks, \%addCheckValues, $lunPrintName);
} # foreach
#
# Check if all LUNs in extraconfig were found
#
-foreach my $lunName ( keys %extraconfig ) {
- if (! ${$extraconfig{$lunName}}{'found'} ) {
- report("LUN '$lunName' in extraconfig, but NO DATA found.",${$extraconfig{$lunName}}{'missingRet'} );
+foreach my $rExtraConf ( @extraconfig ) {
+ if (! $$rExtraConf{'found'} ) {
+ report("NO DATA found for extra-config LUN selector '". $$rExtraConf{'attrib'}.'!'.$$rExtraConf{'val'}."'", $$rExtraConf{'missingRet'} );
}
} # foreach
@@ -1216,4 +1553,4 @@ if ( ($exit_code != $E_OK) && $opt{'reload'} ){
print $linebreak;
#print "$exit_code\n";
# Exit with proper exit code
-exit $exit_code;
+exit $exit_code;
diff --git a/check_multipath/control b/check_multipath/control
index 1986c04..264d554 100644
--- a/check_multipath/control
+++ b/check_multipath/control
@@ -1,5 +1,5 @@
Watch: http://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check-2Dmultipath-2Epl/details Current Version</div><div class="data">([0-9.]+)</div>
-Version: 0.4.1
+Version: 0.4.7
Homepage: http://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check-2Dmultipath-2Epl/details
Uploaders: Bernd Zeimetz <bzed at debian.org>
Description: plugin to monitor the number of available and
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-nagios/pkg-nagios-plugins-contrib.git
More information about the Pkg-nagios-changes
mailing list