Skip to content

Instantly share code, notes, and snippets.

@w3ttr3y
Created July 23, 2015 02:07
Show Gist options
  • Save w3ttr3y/a64cf5f09da2545124dd to your computer and use it in GitHub Desktop.
Save w3ttr3y/a64cf5f09da2545124dd to your computer and use it in GitHub Desktop.
#!/bin/bash --restricted
##########################
## check_mounts
###########################
# A script to use as a Nagios plugin to check that a mount is actually mounted based on device, mount point and/or filesystem type
#
# The original intent of this script was to check that /data on our indexers was indeed mounted
# When they were first built the raid array wasn't always built, so some times they would come up without
# anything mounted on /data. When they would start Splunk, it would write to
# /data which placed a large amount of data on a small / filesystem.
# Luckily, the low disk space warning alerted us to the problem and no crisis ensued.
# The hope was with this check the problem could be found earlier and
# the actual root issue could be identified (e.g. that the device wasn't mounted)
#
#
#############################
# Change log
# ###########################
# 2015-07-22 - WET - initial version
#
#############################
#Fail if any command fails -- otherwise things are just too unpredictable
set -e
#############
## Constants
################
# Plugin Return Code
# 0 OK
# 1 WARNING
# 2 CRITICAL
# 3 UNKNOWN
RET_OK=0
RET_WARN=1
RET_CRIT=2
RET_UNKNOWN=3
usage='
A script to check that a mount is actually mounted.
Usage:
${0} [options]
Options:
-c, --cmd the command to run to get a list of mounts (defaults to cat - if STDIN; else mount)
-d, --device the device to be mounted
-p, --mount-point the mount points on the file system
-t, --type the filesystem type
Requirements:
This script requires that mount (or the specified command) outputs data about
the mounted filesystems in the format device on mountpoint type filesystem (options)
/dev/mapper/centos-root on / type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)
/dev/sdb on /data type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=64k,sunit=128,swidth=1280,noquota)
/dev/mapper/centos-opt on /opt type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)
/dev/sda1 on /boot type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)
/dev/sda3 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,shortname=winnt,errors=remount-ro)
/dev/mapper/centos-home on /home type xfs (rw,nodev,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)
/dev/mapper/centos-var_log on /var/log type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,swidth=512,noquota)
If you have a different format, it may be possible to write a regex to easily parse the output of mount.
Future Potential:
If you replaced the comma in options, you could fairly easily iterate over options.
Being able to require options could be helpful (e.g. require a partition is mounted readonly)
Examples:
Ensure /dev/sdb is mounted
./${0} -d /dev/sdb
Ensure /home is mounted
./${0} -p /home
Ensure a filesystem of type tmpfs is mounted
./${0} -t tmpfs
Ensure /dev/sdb1 is mounted on /home and is of type ext4
./${0} -d /dev/sdb1 -p /home -t ext4
If you want to use fake data for testing, the -c option can be used
./${0} -c "cat ~/mounts" -d /dev/sdb1
You can then grep out then grep out the data to ensure it will correctly flag as critical
./${0} -c "cat ~/mounts | grep -v /dev/sdb1" -d /dev/sdb1
./${0} -c "mount | grep -v /dev/sdb1" -d /dev/sdb1
Finally, if you pipe data to ${0} it will attempt to read the data from STDIN by default (-c will override)
mount | ${0} -d /dev/sdb1
mount | grep -v /dev/sdb1 | ${0}
'
###########################
## Defaults
###########################
# If we're being piped data on STDIN use it; otherwise use the mount command
# This can be overridden with command line arguments -- this just sets the default
if [ -t 0 ] ; then
cmd="mount"
else
cmd="cat -"
fi
###########################
## Build a return message
###########################
function build_message {
RET_MSG=$1
if [ "${DEVICE}" != "" ] ; then
RET_MSG="${RET_MSG} ${DEVICE}"
fi
if [ "${POINT}" != "" ]; then
RET_MSG="${RET_MSG} on ${POINT}"
fi
if [ "${TYPE}" != "" ] ; then
RET_MSG="${RET_MSG} as ${TYPE}"
fi
}
##########################
## Argument Parsing
##########################
if [ $# -eq 0 ] ; then
echo "At least one device, mountpoint, or filesystem must be specified." >&2
echo "${usage}"
exit $RET_UNKNOWN
fi
while getopts "hc:d:p:t:" opt; do
case $opt in
c ) cmd=$OPTARG;;
d ) DEVICE=$OPTARG;;
h ) echo "${usage}" ; exit $RET_UNKNOWN;;
p ) POINT=$OPTARG;;
t ) TYPE=$OPTARG ;;
\?)
echo "Invalid option: -$OPTARG" >&2
echo "${usage}"
exit $RET_UNKNOWN;;
:)
echo "Option -$OPTARG requires an argument" >&2
echo "${usage}"
exit $RET_UNKNOWN;;
esac
done
##########################
## Main
###########################
build_message
while IFS= read -r LINE; do
[[ $LINE =~ ^([^[:space:]]+)[[:space:]]+on[[:space:]]+([^[:space:]]+)[[:space:]]+type[[:space:]]+([^[:space:]]+)[[:space:]]([^[:space:]]+) ]]
# 1. device
# 2. mountpoint
# 3. filesystem
# 4. options
if [ "${DEVICE}" == '' ] || [ "${DEVICE}" == "${BASH_REMATCH[1]}" ] ; then
if [ "${POINT}" == '' ] || [ "${POINT}" == "${BASH_REMATCH[2]}" ] ; then
if [ "${TYPE}" == '' ] || [ "${TYPE}" == "${BASH_REMATCH[3]}" ] ; then
echo "MOUNT OK ${RET_MSG}"
exit $RET_OK
fi
fi
fi
done < <(eval $cmd)
echo "MOUNT CRITICAL ${RET_MSG}"
exit $RET_CRIT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment