File check_fs_frag of Package monitoring-plugins-fs_frag
#!/bin/bash
#
# Copyright (c) 2015-2019, Lars Vogdt <lars@linux-schulserver.de>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
VERSION='1.1'
MTAB='/etc/mtab'
UTILS='/usr/lib/nagios/plugins/utils.sh'
BC='/usr/bin/bc'
HEAD='/usr/bin/head'
SED='/usr/bin/sed'
E2FSCK='/usr/sbin/e2fsck'
XFS_DB='/usr/sbin/xfs_db'
SUDO='/usr/bin/sudo'
USE_SUDO='yes'
WARNING=50
CRITICAL=70
TIMEOUT=30
if [ -r "$UTILS" ]; then
# shellcheck source=/usr/lib/nagios/plugins/utils.sh
. "$UTILS"
else
echo "UNKNOWN: can not read $UTILS"
exit 3
fi
RES="$STATE_OK"
print_help(){
echo "Usage: $(basename "$0") -w <level> -c <level> [OPTIONS]"
echo " checks fragementation of local file systems (xfs, ext2, ext3, ext4)"
echo
echo " -w <level> : warning level (default: $WARNING) in percent"
echo " -c <level> : critical level (default: $CRITICAL) in percent"
echo " -t <seconds> : seconds for each file system analysis to wait (default: $TIMEOUT)"
echo
echo " -m <file> : use <file> as mtab file (default: $MTAB)"
echo " -b <file> : path to bc (default: $BC)"
echo " -h : this help"
echo " -s : do not use sudo (default: $USE_SUDO)"
echo " -v : version number"
echo
print_revision "$(basename "$0")" "$VERSION"
echo
support
exit "$STATE_OK"
}
compare(){
value="$1"
level="$2"
res=$(echo "$value > $level" | "$BC");
return "$res"
}
check_fs_values(){
local fs="$1"
local value="$2"
local type="$3"
if ! compare "$value" "$WARNING"; then
OUTPUT="Warn: filesystem $fs ($type) is $value% defragmented; $OUTPUT"
if [ "$RES" -lt "$STATE_WARNING" ]; then
RES="$STATE_WARNING"
fi
elif ! compare "$value" "$CRITICAL"; then
OUTPUT="Crit: filesystem $fs ($type) is $value% defragmented; $OUTPUT"
RES="$STATE_CRITICAL"
else
OUTPUT="Ok: filesystem $fs ($type) is $value% defragmented; $OUTPUT"
if [ "$RES" -lt "$STATE_OK" ]; then
RES="$STATE_OK"
fi
fi
}
while getopts "hvm:b:w:c:t:s" OPTION; do
case "$OPTION" in
h) print_help
exit "$STATE_OK"
;;
v) print_revision "$(basename "$0")" "$VERSION"
exit "$STATE_OK"
;;
w) WARNING="$OPTARG"
;;
c) CRITICAL="$OPTARG"
;;
m) MTAB="$OPTARG"
;;
b) BC="$OPTARG"
;;
t) TIMEOUT="$OPTARG"
;;
s) USE_SUDO='no'
;;
*) echo "Unkown commandline option: $OPTION"
print_help
exit "$STATE_UNKNOWN"
;;
esac
done
if [ ! -x "$BC" ]; then
echo "UNKNOWN: can not execute $BC"
print_help
exit "$STATE_UNKNOWN"
fi
if [ ! -x "$SED" ]; then
echo "UNKNOWN: can not execute $SED"
exit "$STATE_UNKNOWN"
fi
if [ ! -r "$MTAB" ]; then
echo "UNKNOWN: can not read $MTAB"
print_help
exit "$STATE_UNKNOWN"
fi
if [[ ! "$WARNING" =~ ^-?[0-9]+$ ]]; then
echo "UNKNOWN: $WARNING for warning must be an integer"
print_help
exit "$STATE_UNKNOWN"
fi
if [[ ! "$CRITICAL" =~ ^-?[0-9]+$ ]]; then
echo "UNKNOWN: $CRITICAL for critical must be an integer"
print_help
exit "$STATE_UNKNOWN"
fi
if [[ ! "$TIMEOUT" =~ ^-?[0-9]+$ ]]; then
echo "UNKNOWN: $TIMEOUT must be an integer"
print_help
exit "$STATE_UNKNOWN"
fi
if [ "$WARNING" -ge "$CRITICAL" ]; then
echo "UNKNOWN: critical value $CRITICAL must be greater than warning value $WARNING"
print_help
exit "$STATE_UNKNOWN"
fi
if [ "$USE_SUDO" != 'yes' ]; then
SUDO=''
elif [ ! -x "$SUDO" ]; then
echo "UNKNOWN: can not execute $SUDO"
print_help
exit "$STATE_UNKNOWN"
fi
unset LANG;
while read -r LINE ; do
# shellcheck disable=SC2206
ARRY=($LINE);
FIELDNAME=$(echo "${ARRY[0]}" | sed 's/^[^A-Za-z_]/_/; s/[^A-Za-z0-9_]/_/g');
FS="${ARRY[1]}"
case $FS in
xfs)
if [ ! -x "$XFS_DB" ]; then
echo "UNKNOWN: found xfs filesystem but can not execute $XFS_DB";
exit "$STATE_UNKNOWN"
fi
FRAGVALUE=$(timeout "$TIMEOUT" "$SUDO" "$XFS_DB" -f -c frag -r "${ARRY[0]}")
if [ $? -eq 124 ]; then
OUTPUT="UNKNOWN: timeout ($TIMEOUT) reached while checking ${ARRY[0]}; $OUTPUT"
if [ "$RES" -lt "$STATE_UNKNOWN" ]; then
RES="$STATE_UNKNOWN"
fi
continue
fi
FRAG=$(echo "$FRAGVALUE" | $HEAD -n1 | $SED 's/.*fragmentation factor \(.*\)%.*/\1/');
check_fs_values "$FIELDNAME" "$FRAG" "$FS"
PERFDATA="$PERFDATA '$FIELDNAME.frag'=$FRAG%;$WARNING;$CRITICAL;;"
;;
ext*)
if [ ! -x "$E2FSCK" ]; then
echo "UNKNOWN: found ${ARRY[1]} filesystem but can not execute $E2FSCK";
exit "$STATE_UNKNOWN"
fi
FRAGVALUE=$(timeout "$TIMEOUT" "$SUDO" "$E2FSCK" -fn "${ARRY[0]}" 2>/dev/null)
if [ $? -eq 124 ]; then
OUTPUT="UNKNOWN: timeout ($TIMEOUT) reached while checking ${ARRY[0]}; $OUTPUT"
if [ "$RES" -lt "$STATE_UNKNOWN" ]; then
RES="$STATE_UNKNOWN";
fi
continue
fi
FRAG=$(echo "$FRAGVALUE" | tail -n 1 | "$SED" 's/.*(\(.*\)% non-contiguous.*/\1/');
check_fs_values "$FIELDNAME" "$FRAG" "$FS"
PERFDATA="$PERFDATA '$FIELDNAME.frag'=$FRAG%;$WARNING;$CRITICAL;;"
;;
sysfs|proc|devtmpfs|securityfs|tmpfs|devpts|cgroup|cgroup2|pstore|mqueue|debugfs|hugetlbfs|tracefs|autofs|nfs|fuse*)
# ignore filesystems where we can not gather fragmentation information
;;
*)
OUTPUT="Info: filesystem ${ARRY[0]} ($FS) is not checked; $OUTPUT"
;;
esac
done < <(awk '{print $1 " " $3}' "$MTAB")
case "$RES" in
$STATE_CRITICAL)
echo -n "CRITICAL: $OUTPUT"
;;
$STATE_WARNING)
echo -n "WARNING: $OUTPUT"
;;
$STATE_OK)
echo -n "All OK: $OUTPUT"
;;
*)
echo -n "UNKNOWN: $OUTPUT"
;;
esac
echo "|$PERFDATA"
exit "$RES"