You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
5.6 KiB
Perl
280 lines
5.6 KiB
Perl
#!/usr/bin/perl
|
|
|
|
use Getopt::Std;
|
|
|
|
$CFG_FILE = "/usr/local/nagios/etc/check_disk.cfg";
|
|
$CFG_FILE_LOCAL = "/usr/local/nagios/etc/check_disk_local.cfg";
|
|
$DFLT_WARN = 90;
|
|
$DFLT_CRIT = 95;
|
|
$DFLT_CLASS = "system";
|
|
|
|
$CURR_WARN = $DFLT_WARN;
|
|
$CURR_CRIT = $DFLT_CRIT;
|
|
$CURR_CLASS = $DFLT_CLASS;
|
|
|
|
$sys_type = `uname`;
|
|
chomp($sys_type);
|
|
|
|
%FSTypes = (
|
|
ext2 => 1,
|
|
ext3 => 1,
|
|
ext4 => 1,
|
|
ufs => 1,
|
|
vxfs => 1,
|
|
zfs => 1,
|
|
xfs => 1
|
|
);
|
|
|
|
# -p enable perf stats
|
|
# -d enable debugging output
|
|
# -c <crit> set default critical threshold
|
|
# -w <warn> set default warning threshold
|
|
# -f <config-file>
|
|
# -C <class>
|
|
# -t <type[,type...]> add additional file system types
|
|
|
|
getopts("pdc:w:f:C:t:");
|
|
$CURR_WARN = $opt_w if $opt_w ne '';
|
|
$CURR_CRIT = $opt_c if $opt_c ne '';
|
|
$opt_C = $CURR_CLASS if $opt_C eq '';
|
|
|
|
# get the types
|
|
|
|
if ($opt_t ne '') {
|
|
@types = split(/,/, $opt_t);
|
|
for $t (@types) {
|
|
print "add type $t\n" if $opt_d;
|
|
$FSTypes{$t} = 1;
|
|
}
|
|
}
|
|
|
|
# get the list of file systems
|
|
|
|
&read_mounts;
|
|
|
|
# read the config file; if it's not there we take the defaults, except
|
|
# that if we specify a config file on the command line, we return UNKNOWN
|
|
# if the file isn't there
|
|
|
|
if ($opt_f ne '') {
|
|
open (CFG_FILE, $opt_f) or unknown("Can't open config file: $opt_f");
|
|
&read_config;
|
|
}
|
|
|
|
else {
|
|
(open(CFG_FILE, $CFG_FILE_LOCAL) or open(CFG_FILE, $CFG_FILE)) and &read_config;
|
|
}
|
|
|
|
|
|
if ($opt_d) {
|
|
for $fs (sort keys %Class) {
|
|
print "fs $fs class $Class{$fs} warn $Warn{$fs} crit $Crit{$fs}\n";
|
|
}
|
|
}
|
|
|
|
|
|
# if there are any file systems that are mounted but not mentioned in the config file,
|
|
# give them default class and thresholds
|
|
|
|
for $fs (keys %Type) {
|
|
print "testing $fs: ", defined($Interesting{$fs}) ? "" : "not ", "interested\n" if $opt_d;
|
|
if (! defined($Interesting{$fs})) {
|
|
$Class{$fs} = $DFLT_CLASS;
|
|
$Warn{$fs} = $DFLT_WARN;
|
|
$Crit{$fs} = $DFLT_CRIT;
|
|
}
|
|
}
|
|
|
|
if ($sys_type eq "Linux") {
|
|
$cmd = "/bin/df -kP";
|
|
}
|
|
|
|
elsif ($sys_type eq "SunOS") {
|
|
$cmd = "/usr/bin/df -k";
|
|
}
|
|
|
|
else {
|
|
unknown("I don't grok system type $sys_type");
|
|
}
|
|
|
|
$fscount = 0;
|
|
for $fs (sort keys %Class) {
|
|
## unknown("Non-existant FS ($fs) in config file, line $Line{$fs}") if $Type{$fs} eq '';
|
|
push(@FSList, $fs);
|
|
}
|
|
|
|
|
|
for $fs (@FSList) {
|
|
next if $Ignore{$fs};
|
|
next if $Class{$fs} ne $opt_C;
|
|
|
|
$cmd = $cmd . " " . $fs;
|
|
$fscount++;
|
|
}
|
|
|
|
if ($fscount == 0) {
|
|
unknown("no file systems in class \'$opt_C\'");
|
|
}
|
|
|
|
print "$cmd\n" if $opt_d;
|
|
$code = 0;
|
|
open(DF, "$cmd|") or unknown("Unable to exec df command");
|
|
$junk = <DF>; # column headers
|
|
while (<DF>) {
|
|
chop;
|
|
($dev, $tot, $used, $free, $cap, $fs) = split;
|
|
$p = int(($tot - $free) * 100 / $tot);
|
|
print "$fs: $used/$tot $p\n" if $opt_d;
|
|
$perf .= " $fs=$p\%";
|
|
if ($p > $Crit{$fs}) {
|
|
$crit_result .= " $fs: $p\% (C)";
|
|
$code = 2;
|
|
}
|
|
|
|
elsif ($p > $Warn{$fs}) {
|
|
$warn_result .= " $fs: $p\% (W)";
|
|
$code = 1 if $code != 2;
|
|
}
|
|
|
|
else {
|
|
$result .= " $fs: $p\% (OK)";
|
|
}
|
|
}
|
|
|
|
print "perf $perf\n" if $opt_d;
|
|
@CODE = ("OK", "WARNING", "CRITICAL", "UNKNOWN");
|
|
print "DISK $CODE[$code]: class '$opt_C':$crit_result$warn_result$result";
|
|
|
|
print "|$perf" if $opt_p;
|
|
print "\n";
|
|
exit $code;
|
|
|
|
|
|
sub read_mounts
|
|
{
|
|
open(MNTTAB, "/etc/mtab") or open(MNTTAB, "/etc/mnttab") or unknown("Can't open file system mount table");
|
|
while (<MNTTAB>) {
|
|
chop;
|
|
@mnt = split;
|
|
|
|
next if $FSTypes{$mnt[2]} != 1;
|
|
$fs = $mnt[1];
|
|
print "read from mtab: $_\n" if $opt_d;
|
|
# push(@FSList, $fs);
|
|
|
|
$Type{$fs} = $mnt[2];
|
|
# $Class{$fs} = $DFLT_CLASS;
|
|
# $Warn{$fs} = $DFLT_WARN;
|
|
# $Crit{$fs} = $DFLT_CRIT;
|
|
}
|
|
}
|
|
|
|
|
|
sub read_config
|
|
{
|
|
my ($tmp_class, $tmp_warn, $tmp_crit);
|
|
$line_num = 0;
|
|
while (<CFG_FILE>) {
|
|
$line_num++;
|
|
chop;
|
|
|
|
s/^[ ]*//;
|
|
next if /^#/;
|
|
next if $_ eq '';
|
|
|
|
if (/^ignore\s/) {
|
|
($junk, $fs) = split;
|
|
$Ignore{$fs} = 1;
|
|
}
|
|
|
|
elsif (/^crit\s/) {
|
|
($junk, $crit) = split;
|
|
$CURR_CRIT = $crit;
|
|
}
|
|
|
|
elsif (/^warn\s/) {
|
|
($junk, $warn) = split;
|
|
$CURR_WARN = $warn;
|
|
}
|
|
|
|
elsif (/^class\s/) {
|
|
($junk, $class) = split;
|
|
$CURR_CLASS = $class;
|
|
}
|
|
|
|
elsif (/^fs\s/) {
|
|
($junk, @a) = split;
|
|
$fs = $a[0];
|
|
|
|
@fslist = &match($fs);
|
|
foreach $fs (@fslist) {
|
|
$tmp_class = $CURR_CLASS;
|
|
$tmp_warn = $CURR_WARN;
|
|
$tmp_crit = $CURR_CRIT;
|
|
|
|
@aa = @a;
|
|
shift @aa;
|
|
foreach $arg (@aa) {
|
|
if ($arg =~ /^class=/) { $tmp_class = substr($arg, 6); }
|
|
elsif ($arg =~ /^warn=/) { $tmp_warn = substr($arg, 5); }
|
|
elsif ($arg =~ /^crit=/) { $tmp_crit = substr($arg, 5); }
|
|
|
|
else { unknown("Syntax error in config file, line $line_num"); }
|
|
}
|
|
|
|
# mark the file system as being of overall interest
|
|
|
|
$Interesting{$fs} = 1;
|
|
|
|
# Only set these values if the class of the file system is the one that
|
|
# we are looking to check. This allows us to put a file system in
|
|
# multiple classes (in cases where more than on group wants to know
|
|
# about a F.S.) and not have one definition overwritten by another one.
|
|
|
|
print "about to test $fs now $Class{$fs} tmp $tmp_class dflt $CURR_CLASS opt $opt_C\n" if $opt_d;
|
|
next if $tmp_class ne $opt_C;
|
|
|
|
print "setting $fs to class $tmp_class\n" if $opt_d;
|
|
$Class{$fs} = $tmp_class;
|
|
$Warn{$fs} = $tmp_warn;
|
|
$Crit{$fs} = $tmp_crit;
|
|
$Line{$fs} = $line_num;
|
|
}
|
|
}
|
|
|
|
else { # syntax error
|
|
unknown("Syntax error in config file, line $line_num");
|
|
}
|
|
}
|
|
|
|
close(CFG_FILE);
|
|
}
|
|
|
|
|
|
sub match
|
|
{
|
|
my ($fs) = @_;
|
|
my @glist = glob($fs);
|
|
my @rlist = ();
|
|
|
|
print "Match glob list is " . join(' ', @glist) . "\n" if $opt_d;
|
|
|
|
foreach $fs (@glist) {
|
|
push @rlist, $fs if $Type{$fs} ne '';
|
|
}
|
|
|
|
print "Match return list is " . join(' ', @rlist) . "\n" if $opt_d;
|
|
|
|
return @rlist;
|
|
}
|
|
|
|
|
|
sub unknown
|
|
{
|
|
my ($reason) = @_;
|
|
|
|
print "UNKNOWN: $reason\n";
|
|
exit 3;
|
|
}
|
|
|