check_fsck.pl
changeset 0 31c5debb897d
child 1 52edcba85acf
equal deleted inserted replaced
-1:000000000000 0:31c5debb897d
       
     1 #! /usr/bin/perl -w
       
     2 
       
     3 #    Copyright (C) 2011  Christian Arnold
       
     4 #
       
     5 #    This program is free software: you can redistribute it and/or modify
       
     6 #    it under the terms of the GNU General Public License as published by
       
     7 #    the Free Software Foundation, either version 3 of the License, or
       
     8 #    (at your option) any later version.
       
     9 #
       
    10 #    This program is distributed in the hope that it will be useful,
       
    11 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13 #    GNU General Public License for more details.
       
    14 #
       
    15 #    You should have received a copy of the GNU General Public License
       
    16 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
    17 #
       
    18 #    Christian Arnold <arnold@schlittermann.de>
       
    19 
       
    20 use 5.010;
       
    21 use strict;
       
    22 use warnings;
       
    23 use File::Basename;
       
    24 use Pod::Usage;
       
    25 use Getopt::Long;
       
    26 use Date::Manip;
       
    27 
       
    28 $ENV{LANG} = "POSIX";
       
    29 my %ERRORS = (
       
    30     OK        => 0,
       
    31     WARNING   => 1,
       
    32     CRITICAL  => 2,
       
    33     UNKNOWN   => 3,
       
    34     DEPENDENT => 4
       
    35 );
       
    36 
       
    37 my $ME      = basename $0;
       
    38 my $VERSION = "0.1";
       
    39 
       
    40 sub get_status($);
       
    41 sub report($);
       
    42 
       
    43 my $opt = {
       
    44     fs        => undef,
       
    45     warning   => 5,
       
    46     critical  => 1,
       
    47     twarning  => "5days",
       
    48     tcritical => "1day",
       
    49     binary    => "/sbin/tune2fs"
       
    50 };
       
    51 
       
    52 MAIN: {
       
    53     Getopt::Long::Configure('bundling');
       
    54     GetOptions(
       
    55         "f|fs=s"        => \$opt->{fs},
       
    56         "w|warning=i"   => \$opt->{warning},
       
    57         "c|critical=i"  => \$opt->{critical},
       
    58         "W|twarning=s"  => \$opt->{twarning},
       
    59         "C|tcritical=s" => \$opt->{tcritical},
       
    60         "b|binary=s"    => \$opt->{binary},
       
    61         "h|help" => sub { pod2usage( -verbose => 1, -exitval => $ERRORS{OK} ) },
       
    62         "m|man" => sub { pod2usage( -verbose => 2, -exitval => $ERRORS{OK} ) },
       
    63         "V|version" => sub { version( $ME, $VERSION ); exit $ERRORS{OK}; }
       
    64     ) or pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} );
       
    65 
       
    66     $opt->{fs} // pod2usage( -verbose => 1, -exitval => $ERRORS{CRITICAL} );
       
    67 
       
    68     report( get_status( $opt->{fs} ) );
       
    69 }
       
    70 
       
    71 sub report($) {
       
    72     my $status   = shift;
       
    73     my @output   = ();
       
    74     my $rc       = undef;
       
    75     my %rcconter = (
       
    76         CRITICAL => 0,
       
    77         WARNING  => 0
       
    78     );
       
    79 
       
    80     foreach my $fs ( keys %$status ) {
       
    81         if (   $status->{$fs}{mstatus}[0] eq "CRITICAL"
       
    82             || $status->{$fs}{tstatus}[0] eq "CRITICAL" )
       
    83         {
       
    84             $rc = "CRITICAL";
       
    85             $rcconter{$rc}++;
       
    86         }
       
    87         elsif ($status->{$fs}{mstatus}[0] eq "WARNING"
       
    88             || $status->{$fs}{tstatus}[0] eq "WARNING" )
       
    89         {
       
    90             $rc = "WARNING";
       
    91             $rcconter{$rc}++;
       
    92         }
       
    93         else {
       
    94             $rc = "OK";
       
    95         }
       
    96         push @output,
       
    97             "$rc - $fs: Mount count: "
       
    98           . "[$status->{$fs}{'Mount count'}/$status->{$fs}{'Maximum mount count'}] "
       
    99           . "Next check after: [$status->{$fs}{'Next check after'}]\n";
       
   100     }
       
   101 
       
   102     print @output;
       
   103 
       
   104     foreach ( keys %rcconter ) {
       
   105         if ( $_ eq "CRITICAL" && $rcconter{$_} > 0 ) {
       
   106             exit $ERRORS{CRITICAL};
       
   107         }
       
   108         elsif ( $_ eq "WARNING" && $rcconter{$_} > 0 ) {
       
   109             exit $ERRORS{WARNING};
       
   110         }
       
   111     }
       
   112     exit $ERRORS{OK};
       
   113 }
       
   114 
       
   115 sub get_status($) {
       
   116     my $fs = shift;
       
   117     my @fs = split( /,/, $fs );
       
   118 
       
   119     my %values = ();
       
   120 
       
   121     foreach $fs (@fs) {
       
   122         unless ( -b $fs && -r $fs ) {
       
   123             print
       
   124 "FSCK CRITICAL $fs - not exists or not read permission is granted";
       
   125             exit $ERRORS{CRITICAL};
       
   126         }
       
   127         foreach (
       
   128             grep
       
   129 /^Mount count:\s+\d+|Maximum mount count:\s+\d+|Next check after:\s+/i
       
   130             => `$opt->{binary} -l $fs` )
       
   131         {
       
   132             chomp;
       
   133             my ( $index, $value ) = split( /:/, $_, 2 );
       
   134             ( $value = $value ) =~ s/^\s+//;
       
   135             $values{$fs}{$index} = $value;
       
   136         }
       
   137     }
       
   138 
       
   139     my $w_time = DateCalc( "today", "+ $opt->{twarning}" );
       
   140     my $c_time = DateCalc( "today", "+ $opt->{tcritical}" );
       
   141 
       
   142     foreach $fs ( keys %values ) {
       
   143         my $mounts =
       
   144           $values{$fs}{'Maximum mount count'} - $values{$fs}{'Mount count'};
       
   145         my $next_check_after = ParseDate( $values{$fs}{'Next check after'} );
       
   146 
       
   147         push( @{ $values{$fs}{mounts} }, $mounts );
       
   148 
       
   149         if ( $mounts <= $opt->{critical} ) {
       
   150             push( @{ $values{$fs}{mstatus} }, "CRITICAL" );
       
   151         }
       
   152         elsif ( $mounts <= $opt->{warning} ) {
       
   153             push( @{ $values{$fs}{mstatus} }, "WARNING" );
       
   154         }
       
   155         else {
       
   156             push( @{ $values{$fs}{mstatus} }, "OK" );
       
   157         }
       
   158 
       
   159         Date_Cmp( $next_check_after, $w_time ) > 0
       
   160           and push( @{ $values{$fs}{tstatus} }, "OK" ), next;
       
   161         Date_Cmp( $next_check_after, $c_time ) > 0
       
   162           and push( @{ $values{$fs}{tstatus} }, "WARNING" ), next;
       
   163         push( @{ $values{$fs}{tstatus} }, "CRITICAL" );
       
   164     }
       
   165 
       
   166     return \%values;
       
   167 }
       
   168 
       
   169 __END__
       
   170 
       
   171 =head1 NAME
       
   172 
       
   173 check_fsck - nagios plugin to report next filesystem check time
       
   174 
       
   175 =head1 SYNOPSIS
       
   176 
       
   177 check_fsck -f|--fs path
       
   178           [-w|--warning int]
       
   179           [-c|--critical int]
       
   180           [-W|--twarning string]
       
   181           [-C|--tcritical string]
       
   182           [-b|--binary path]
       
   183 
       
   184           check_fsck [-h|--help]
       
   185           check_fsck [-m|--man]
       
   186           check_fsck [-v|--version]
       
   187 
       
   188 =head1 OPTIONS
       
   189 
       
   190 =over
       
   191 
       
   192 =item B<-f>|B<--fs> I<path>
       
   193 
       
   194 ext2/ext3 filesystem to check. Multiple filesystems are possible separated by commas.
       
   195 
       
   196 =item B<-w>|B<--warning> I<int>
       
   197 
       
   198 Possible mount counts before status change to warning. (default: I<5>)
       
   199 
       
   200 =item B<-c>|B<--critical> I<int>
       
   201 
       
   202 Possible mount counts before status change to critical. (default: I<1>)
       
   203 
       
   204 =item B<-W>|B<--twarning> I<string>
       
   205 
       
   206 Time before change to warning status. (default: I<5days>)
       
   207 
       
   208 =item B<-C>|B<--tcritical> I<string>
       
   209 
       
   210 Time before change to critical status. (default: I<1day>)
       
   211 
       
   212 =item B<-b>|B<--binary> I<path>
       
   213 
       
   214 Path to I<tune2fs> binary program (default: I</sbin/tune2fs>)
       
   215 
       
   216 =item B<-h>|B<--help>
       
   217 
       
   218 Print detailed help screen.
       
   219 
       
   220 =item B<-m>|B<--man>
       
   221 
       
   222 Print manual page.
       
   223 
       
   224 =item B<-V>|B<--version>
       
   225 
       
   226 Print version information.
       
   227 
       
   228 =back
       
   229 
       
   230 =head1 DESCRIPTION
       
   231 
       
   232 This plugin check current mount counts and next filesystem check time for
       
   233 ext2/ext3 filesystems.  This plugin must be run as root.
       
   234 
       
   235 =head1 VERSION
       
   236 
       
   237 This man page is current for version 0.1 of check_fsck.
       
   238 
       
   239 =head1 AUTHOR
       
   240 
       
   241 Written by Christian Arnold L<arnold@schlittermann.de>
       
   242 
       
   243 =head1 COPYRIGHT
       
   244 
       
   245 Copyright (C) 2011 by Christian Arnold and Schlittermann internet & unix support.
       
   246 This is free software, and you are welcome to redistribute it under certain conditions.
       
   247 See the GNU General Public Licence for details.
       
   248 
       
   249 =cut