1 |
#!/usr/bin/perl -w |
2 |
|
3 |
# Nagios probe to verify that a file system is writable |
4 |
# This is verified by first inspecting the information from /proc/mounts |
5 |
# If the file system is mounted rw, then it is attempted to create a file on it |
6 |
|
7 |
use strict; |
8 |
use Getopt::Long; |
9 |
|
10 |
my $verbose=0; |
11 |
my $help; |
12 |
my $hostname; |
13 |
my $debug; |
14 |
|
15 |
my $TIMEOUT = 10; |
16 |
|
17 |
GetOptions("help" => \$help, |
18 |
"host:s" => \$hostname, |
19 |
"debug" => \$debug, |
20 |
"verbose+" => \$verbose ); |
21 |
|
22 |
|
23 |
my %ERRORS=(OK=>0, |
24 |
WARNING=>1, |
25 |
CRITICAL=>2, |
26 |
UNKNOWN=>3, |
27 |
DEPENDENT=>4); |
28 |
my $result = $ERRORS{"UNKNOWN"}; |
29 |
|
30 |
if ( scalar @ARGV < 1 ) { |
31 |
print( "UNKNOWN: missing mandatory argument for file system\n" ); |
32 |
exit $ERRORS{"UNKNOWN"}; |
33 |
} |
34 |
my $filesystem = $ARGV[0]; |
35 |
|
36 |
# remove trailing slashes or the match against /proc/mounts will fail |
37 |
$filesystem =~ s!\/*$!!; |
38 |
|
39 |
# Just in case of problems, let's not hang Nagios |
40 |
$SIG{'ALRM'} = sub { |
41 |
print ("ERROR: No response from $hostname (alarm timeout)\n"); |
42 |
exit $ERRORS{"UNKNOWN"}; |
43 |
}; |
44 |
|
45 |
alarm($TIMEOUT); |
46 |
|
47 |
my $msg; |
48 |
($result, $msg) = &check_writable_filesystem( $filesystem ); |
49 |
|
50 |
alarm(0); |
51 |
|
52 |
print "$msg\n"; |
53 |
exit($result); |
54 |
|
55 |
|
56 |
|
57 |
|
58 |
# |
59 |
# check_writable_filesystem |
60 |
# |
61 |
# Checks that a specific file system is mounted RW and that a file can be written to it |
62 |
# |
63 |
sub check_writable_filesystem { |
64 |
my $filesystem = $_[0]; |
65 |
my $res = $ERRORS{OK}; |
66 |
my $msg = ''; |
67 |
|
68 |
if ( ! open MNT, "/proc/mounts" ) { |
69 |
$msg = "Failed to open /proc/mounts"; |
70 |
$res = $ERRORS{CRITICAL}; |
71 |
} |
72 |
|
73 |
# check that the file system is mounted |
74 |
if ( $res == $ERRORS{OK} ) { |
75 |
my $found = 0; |
76 |
while ( <MNT> ) { |
77 |
my ($mnt, $fs, $options) = (split /\s+/)[1,2,3]; |
78 |
$debug and print STDERR "$mnt $fs $options\n"; |
79 |
if ( $mnt eq $filesystem ) { |
80 |
$verbose and print STDERR "Found file system $filesystem\n"; |
81 |
foreach my $opt ( split(',', $options) ) { |
82 |
if ( $opt eq "ro" ) { |
83 |
$msg = "file system $fs is mounted read-only"; |
84 |
$res = $ERRORS{CRITICAL}; |
85 |
last; # no need to process other options |
86 |
} |
87 |
elsif ( $opt eq "rw" ) { |
88 |
$verbose and print STDERR "mount: $mnt $fs $opt\n"; |
89 |
last; # no need to process other options |
90 |
} |
91 |
} |
92 |
$found = 1; |
93 |
last; |
94 |
} |
95 |
} |
96 |
close MNT; |
97 |
if ( ! $found ) { |
98 |
$msg = "file system $filesystem is not mounted"; |
99 |
$res = $ERRORS{CRITICAL}; |
100 |
} |
101 |
} |
102 |
|
103 |
# write to file |
104 |
my $now = time; |
105 |
my $file = "$filesystem/nagios-check-writable-fs.$now"; |
106 |
|
107 |
if ( $res == $ERRORS{OK} ) { |
108 |
if ( ! open WRT, "> $file" ) { |
109 |
$msg = "Cannot write to $file: $!"; |
110 |
$res = $ERRORS{CRITICAL}; |
111 |
} |
112 |
# Do not write anything because that may fail if the disk is full! |
113 |
close WRT; |
114 |
} |
115 |
|
116 |
if ( $res == $ERRORS{CRITICAL} ) { |
117 |
$msg = "ERROR: $msg"; |
118 |
} |
119 |
else { |
120 |
$msg = "OK"; |
121 |
} |
122 |
|
123 |
return ($res, $msg); |
124 |
} |
125 |
|