scripts/xymon/plugins/client/ext/smart

150 lines
4.0 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# NOTE: Must be run as root, so you probably need to setup sudo for this.
# Vars {{{
debug="0"
## Colors {{{
c_redb='\033[1;31m'
c_magentab='\033[1;35m'
c_reset='\033[0m'
## }}}
# }}}
# Functions
## Test if a disk really support SMART {{{
## Smartctl can give an health status even without a full support
## of SMART for some type (eg. scsi or megaraid).
## Exemple: SMART support is: Unavailable - device lacks SMART capability.
is_disk_support_smart() {
_disk="${1}"
_type="${2}"
_smarctl_support_result="/tmp/dsupport.$(basename "${_disk}")"
smart_support_msg=""
[ "${debug}" -eq "0" ] && printf "${c_magentab}%-6b${c_reset}\n" "DEBUG: is_disk_support_smart func check if SMART is supported on: ${_disk}."
if test -f "${_smarctl_support_result}"; then rm -f "${_smarctl_support_result}"; fi
## Grep only "support" lines from disk's informations
smartctl -d "${_type}" -i -- "${_disk}" | grep -E "^SMART support is:" -- > "${_smarctl_support_result}"
## TODO: Test if grep successfully got something
## Parse all "support" lines
while IFS= read -r _LINE; do
if ! printf -- '%s' "${_LINE}" | grep -q -E -- "(Enabled|Available)"
then
smart_support_msg="${_LINE}"
fi
done < "${_smarctl_support_result}"
if [ -z "${smart_support_msg}" ]; then
[ "${debug}" -eq "0" ] && printf "${c_magentab}%-6b${c_reset}\n" "DEBUG: is_disk_support_smart func SMART seems fully supported on: ${_disk}."
else
[ "${debug}" -eq "0" ] && printf "${c_magentab}%-6b${c_reset}\n" "DEBUG: is_disk_support_smart func SMART is not fully supported on: ${_disk}. See smartctl informations:\n${smart_support_msg}"
fi
rm -f -- "${_smarctl_support_result}"
}
## }}}
## Test the type of disk with smartctl {{{
choose_correct_type() {
_disk="${1}"
_scanned_type="${2}"
_default_type="auto"
TYPE=""
SMART_SUPPORT_MSG=""
for test_type in "${_default_type}" "${_scanned_type}"; do
is_disk_support_smart "${_disk}" "${test_type}"
## If no message, the type is correct
if [ -z "${smart_support_msg}" ]; then
TYPE="${test_type}"
SMART_SUPPORT_MSG=""
return
else
SMART_SUPPORT_MSG="${smart_support_msg}"
fi
done
}
## }}}
if test -f /tmp/dres; then rm -f /tmp/dres; fi
if test -f /tmp/dscan; then rm -f /tmp/dscan; fi
# Get the list of all available devices
smartctl --scan > /tmp/dscan
# TODO: Test if the file is not empty
while IFS= read -r LINE; do
## Get device path
DISK=$(echo "${LINE}" | cut -d" " -f1)
## Try to determine the best type
SCANNED_TYPE=$(echo "${LINE}" | cut -d" " -f3)
choose_correct_type "${DISK}" "${SCANNED_TYPE}"
## If no correct type was found for this device
if [ -z "${TYPE}" ]; then
[ "${debug}" -eq "0" ] && printf "${c_magentab}%-6b${c_reset}\n" "DEBUG: SMART is not fully supported."
DRES=$(printf '%s' "${SMART_SUPPORT_MSG}")
DCODE="2"
else
[ "${debug}" -eq "0" ] && printf "${c_magentab}%-6b${c_reset}\n" "DEBUG: SMART seems fully supported, proceed normally."
### Get SMART Health Status and return code
DRES=$(/usr/sbin/smartctl -H -d "${TYPE}" -n standby "${DISK}")
DCODE=$?
fi
DSTBY=$(( DCODE & 2 ))
DFAIL=$(( DCODE & 8 ))
DWARN=$(( DCODE & 32 ))
## Give a weight to each to color to easily get the page status
if test $DSTBY -ne 0
then
COLOR="4&clear"
elif test $DFAIL -ne 0
then
COLOR="1&red"
elif test $DWARN -ne 0
then
COLOR="2&yellow"
else
COLOR="3&green"
fi
echo "${COLOR} $DISK ${TYPE}"
echo "${COLOR} $DISK ${TYPE}" | cut -c2- >>/tmp/dres
echo "" >>/tmp/dres
echo "$DRES" | grep -v -E "^smartctl|^Copyright|^$|^===" >>/tmp/dres
echo "------------------------------------------------------------" >>/tmp/dres
echo "" >>/tmp/dres
echo "" >>/tmp/dres
done < /tmp/dscan >/tmp/dcheck
# Set the global color according to the highest alert
COLOR=$(< /tmp/dcheck awk '{print $1}' | sort | uniq | head -1 | cut -c3-)
$XYMON "${XYMSRV}" "status ${MACHINE}.smart ${COLOR} SMART health check
$(< /tmp/dcheck cut -c2-)
==================== Detailed status ====================
$(cat /tmp/dres)
"
rm -f /tmp/dres /tmp/dcheck /tmp/dscan
exit 0