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.
Princeton/pu/libexec/check_mounted_disks.pl

178 lines
4.9 KiB
Perl

#!/usr/bin/perl -w
use strict;
use warnings;
use Cwd 'abs_path';
sub prtmsg;
# doesn't pick up offline swap partitions
# deal with unexpected problems.
$SIG{__DIE__} = sub { print "@_"; exit 3; };
my $mount;
my $fstab;
my (%mounted_disks, %mounted_disks_options, %fstab_disks, %fstab_disks_options); # store the read details.
my (@ignore, $ign);
my $ignore_file = "/usr/local/nagios/etc/mount_ignore";
my $os = `uname`;
chomp $os;
if ($os eq 'Linux') {
$mount = "/bin/mount";
$fstab = "/etc/fstab";
}
elsif ($os eq 'SunOS')
{
$mount = "/usr/sbin/mount";
$fstab = "/etc/vfstab";
}
else {
die "Unknown OS: $os";
}
## read the list of ignore prefixes if present
if (open( my $ignore_fh, $ignore_file)) {
while (<$ignore_fh>) {
chomp;
push @ignore, $_;
}
close $ignore_fh;
}
########################################################
# get the device and mount point from fstab (what should be mounted)
########################################################
open( my $fstab_fh, $fstab)
|| die "Failed to open $fstab: $!";
while ( <$fstab_fh> ) {
chomp;
s/^\s+//;
s/#.*$//;
s/\s+$//;
next if $_ eq '';
my ($device, $mount_point, $opts);
($device, $mount_point, $opts) = (split(/\s+/, $_))[0, 1, 3] if $os eq 'Linux';
($device, $mount_point, $opts) = (split(/\s+/, $_))[0, 2, 5] if $os eq 'SunOS';
### print "$device $mount_point $opts\n";
$device = abs_path("/dev/disk/by-uuid/" . readlink "/dev/disk/by-uuid/$1") if $device =~ m/UUID=(.*)/;
next unless $device =~ m!/! and $mount_point =~ m!/!; # drop swap, etc. partitions
$mount_point =~ s#/$## unless $mount_point =~ m#^/$#;
next if $device =~ m!(^/dev/cdrom)|(^/dev/fd\d+)!;
next if $os eq 'Linux' and $opts =~ /noauto/;
next if $os eq 'SunOS' and $opts !~ /yes/;
next if grep m#^$mount_point$#, @ignore;
$fstab_disks{$mount_point} = $device;
$fstab_disks_options{$mount_point} = [ split /,/, $opts ];
#print "%%%$device%%%%\n";
#print join "\n", @{$fstab_disks_options{$mount_point}};
#print "\n\n";
}
close $fstab_fh;
### my $i;
### foreach $i (keys %fstab_disks) {print "$i\n";}
$fstab_disks{"/"} = "/" if $os eq 'SunOS'; ## root isn't in vfstab for solaris
########################################################
# get the device and mount point of the mounted disks
########################################################
open( my $mount_fh, "$mount |")
|| die "Failed to open $mount: $!";
while ( <$mount_fh> ) {
my ($device, $mount_point, $mopt);
($device, $mount_point, $mopt) = (split(/\s+/, $_))[0,2,5] if $os eq 'Linux';
($device, $mount_point) = (split(/\s+/, $_))[2,0] if $os eq 'SunOS';
next unless $device =~ m!/!; ## ignore pseudo-fs
next if grep m#^$mount_point$#, @ignore;
### print "$device $mount_point\n";
$mounted_disks{$mount_point} = $device;
$mopt =~ s#[\(\)]##g;
$mounted_disks_options{$mount_point} = [ split /,/, $mopt ];
#print "%%%$device%%%%\n";
#print join "\n", @{$mounted_disks_options{$mount_point}};
#print "\n\n";
}
close $mount_fh;
########################################################
# find inconsistant disks
########################################################
my @not_mounted = sort grep { ! exists $mounted_disks{$_} } keys %fstab_disks;
my @not_persistent = sort grep { ! exists $fstab_disks{$_} } keys %mounted_disks;
my (@ro_mts, @fstab_ro_mts);
foreach (keys %mounted_disks) {
#print "###$_###:\n";
#print "Mount##", join ",,,", @{$mounted_disks_options{$_}}, "##\n";
#print "Fstab##", join ",,,", @{$fstab_disks_options{$_}}, "##\n";
grep (/^ro$/, @{$mounted_disks_options{$_}}) && ! grep (/^ro$/, @{$fstab_disks_options{$_}}) and push @ro_mts, $_;
grep (/^ro$/, @{$fstab_disks_options{$_}}) && (! grep (/^ro$/, @{$mounted_disks_options{$_}}) || grep (/^rw$/, @{$mounted_disks_options{$_}})) and push @fstab_ro_mts, $_;
}
#print join "%%%%", @fstab_ro_mts;
########################################################
# Build output
########################################################
my %out = (
'0' => 'OK: All disks are mounted correctly and persistent',
'1' => 'WARNING: ',
'2' => 'CRITICAL: ',
);
my $message = "";
my $exit_code = 0;
@fstab_ro_mts > 0 and do {
$message = prtmsg \@fstab_ro_mts, " should be mounted read only (and it's not!)<br>\n", " should be mounted read only (and they are not!)<br>\n";
$exit_code = 1;
};
@not_persistent > 0 and do {
$message .= prtmsg \@not_persistent, " is not persistent<br>\n", " are not persistent<br>\n";
$exit_code = 1;
};
@not_mounted > 0 and do {
$message .= prtmsg \@not_mounted, " is not mounted<br>\n", " are not mounted<br>\n";
$exit_code = 2;
};
@ro_mts > 0 and do {
$message .= prtmsg \@ro_mts, " is mounted read only (and it shouldn't be!)", " are all mounted read only (and they shouldn't be!)";
$exit_code = 2;
};
print $out{$exit_code} . "$message\n";
exit $exit_code;
sub prtmsg {
my $arr = shift;
my $msgsingle = shift;
my $msgplural = shift;
if (@$arr == 1) {
return "@$arr" . $msgsingle;
} else {
return join (", ", @$arr) . $msgplural;
}
}