#!/usr/bin/perl -w # # Veritas Volume Manager check plugin for nagios. # Version 1.0, 2007-08-21 # # Copyright (C) Dirk Porezag (, ) # and matrix technology AG (http://www.matrix.ag). # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # # History # ======= # 2007-08-21 Version 1.0, initial release # # Overview of checks, return codes and prerequisites # ================================================== # check_vxvm will perform the following checks: # - check if vxprint can be executed without errors: # if vxprint returns with exit_code > 0, status CRITICAL is returned # - check for any dm records with NODEVICE, FAILING or LOCAL_FAILING flags: # if any record of this category is found, status CRITICAL is returned # - check for any plex record with status NODEVICE or IOFAIL: # if any record of this category is found, status CRITICAL is returned # - check for any subdisks with status NDEV, DIS, dS or FAIL: # if any record of this category is found, status CRITICAL is returned # - check for disks with disabled paths that belong to imported disk groups # if any record of this category is found, status WARNING is returned # # The check script must run with root privileges since the vxdmpadm command # requires root permissions. # use strict; # print critical or warning message and exit # sub errmesg($$) { my $err_code= $_[0]; my $severity= ($err_code == 1) ? "WARNING:" : "CRITICAL:"; print "$severity $_[1]\n"; exit($err_code); } # ------------------------------------------------------ # Disk group status checks # ------------------------------------------------------ # run vxprint, return error in case of problems # transform output to array for more straight-forward parsing # my $vxprint_out= `/usr/sbin/vxprint -ht 2>/dev/null`; errmesg(2, "error running vxprint") if ($? != 0); my @vxprint_arr= split(/\n/, $vxprint_out); # check for disk media problems # build list of imported disks in %imp_disks (needed for DMP path checks) # my %imp_disks= (); my $dgroup= ''; my $line; my @larr; foreach $line (@vxprint_arr) { if ($line =~ m/^dg\s+/) { chomp($line); $line =~ s/^dg\s+(\S+)\s+.*$/$1/; $dgroup= $line; } next if not ($line =~ m/^dm\s+/); @larr= split(/\s+/, $line); $imp_disks{$larr[2]}= $larr[1]; if ($larr[6] eq 'NODEVICE' or $larr[6] eq 'FAILING' or $larr[6] eq 'LOCAL_FAILING') { errmesg(2, "disk $larr[1] ($larr[2]) in DG $dgroup has status $larr[6]"); } } # check for plex problems # foreach $line (@vxprint_arr) { if ($line =~ m/^dg\s+/) { chomp($line); $line =~ s/^dg\s+(\S+)\s+.*$/$1/; $dgroup= $line; } next if not ($line =~ m/^pl\s+/); @larr= split(/\s+/, $line); if ($larr[4] eq 'NODEVICE' or $larr[4] eq 'IOFAIL') { errmesg(2, "plex $larr[1] in DG $dgroup has status $larr[4]/$larr[3]"); } } # check for subdisk problems # see "man vxprint" for a description of possible subdisk states # foreach $line (@vxprint_arr) { if ($line =~ m/^dg\s+/) { chomp($line); $line =~ s/^dg\s+(\S+)\s+.*$/$1/; $dgroup= $line; } next if not ($line =~ m/^sd\s+/); @larr= split(/\s+/, $line); if ($larr[8] eq 'NDEV' or $larr[8] eq 'DIS' or $larr[8] eq 'FAIL' or $larr[8] eq 'dS') { errmesg(2, "subdisk $larr[1] in DG $dgroup has status $larr[8]"); } } # ------------------------------------------------------ # Dynamic multipathing (DMP) path checks # check only disks that are part of imported disk groups # ------------------------------------------------------ # build list of valid controllers # my $vxdmp_out= `/sbin/vxdmpadm listctlr all 2>/dev/null`; errmesg(1, "error running vxdmpadm listctlr all") if ($? != 0); my @vxdmp_arr= split(/\n/, $vxdmp_out); # my %ctlrs= (); my $ctlr; foreach $line (@vxdmp_arr) { next if ($line =~ '^CTLR-NAME\s+' or $line =~ '^=+'); @larr= split(/\s+/, $line); $ctlrs{$larr[0]}= 1; } # check paths for each controller # foreach $ctlr (sort keys(%ctlrs)) { $vxdmp_out= `/sbin/vxdmpadm getsubpaths ctlr=$ctlr 2>/dev/null`; errmesg(1, "error running vxdmpadm getsubpaths ctlr=$ctlr") if ($? != 0); @vxdmp_arr= split(/\n/, $vxdmp_out); # foreach $line (@vxdmp_arr) { next if ($line =~ '^NAME\s+' or $line =~ '^=+'); @larr= split(/\s+/, $line); if (exists($imp_disks{$larr[3]}) and $larr[1] =~ m/^DISABLED/) { errmesg(1, "path $larr[0] of disk $imp_disks{$larr[3]} is disabled"); } } } # all is well # print "OK: all disk groups and DMP paths are OK\n"; exit(0);