Check status of your ZFS pools under Linux
Are you using ZFS pools under Linux? And would you like to get a daily/weekly email with their status, or get notified when one of them gets degraded?
This script is based on the use of debian-zfs package.
The script below assumes that some sort of MTA (Mail Transfer Agent) is configured to handle the outgoing email. Ex exim4 – to re-configure it in debian; run
dpkg-reconfigure exim4-config
The script do a few things before it proceeds with a status check:
- It lists all the pools available on the machine and puts them into a variable.
- It loops through the pools stored in the variable and looks for certain words in order to see if it is OK or degraded.
- Depending on the status it will send an email or not.
- It also does a weekly (or daily if you wish) check and sends an email with the status of the pools. See crontab entry below.
The script:
#!/bin/bash
#Script to check the status of ZFS pools and send an email when they fault, or weekly status.
#Tossed together by Drakfot
#Changelog
#20131203 – Initial scripting started.
# Variables!
EMAIL=YOUR@EMAIL.DOMAIN
LOGFILE=/var/log/zpool_status.log
#The script
#Consisting of functions that are being called at the end of the script.
function zpool_info() {
#Gather all the pools into an array
ZFS_POOLS=$(/sbin/zpool list | grep -v NAME | awk ‘{ print $1 }’)
#Cycle through the pools and check the(ir) status
for pool in "${ZFS_POOLS[*]}"
do
#Go through the array with ZFS pools and check if any disk have become faulty etc. If so then send an email to $EMAIL
condition=$(/sbin/zpool status $pool | egrep -i ‘(DEGRADED|FAULTED|OFFLINE|UNAVAIL|REMOVED|FAIL|DESTROYED|corrupt|cannot|unrecover)’)
#If a test of the script was called, it will set $condition to anything, triggering an email
if [ "$test_script" = 1 ]; then
condition=1
echo "NOTE: This is a test of the script!" >> $LOGFILE
fi
if [ "$condition" ]; then
echo "There is something wrong with ZFS Pool $pool!"
emailSubject="`hostname` – ZFS pool ERROR $pool"
emailContent="`/sbin/zpool list` nnn `/sbin/zpool status $pool`"
else
echo "ZFS Pool $pool is OK!" >> $LOGFILE
fi
done
}
function send_email () {
#Send Email if $emailSubject is not empty
if [ "${emailSubject}" ]; then
echo -e "$emailContent" | /usr/bin/mailx -s "$emailSubject" $EMAIL — -r "`hostname`"
else
echo "No email sent" >> $LOGFILE
fi
}
function pool_info () {
emailContent=`/sbin/zpool list`
emailSubject="`hostname` ZFS Pool Status @ `date`"
}
function update_logfile () {
echo "" >> $LOGFILE
echo "Checking the status of the ZFS pool(s) on `hostname` @ `date`" >> $LOGFILE
echo "" >> $LOGFILE
}
#Calling the functions
case $1 in
–status)
pool_info
send_email
exit 0
;;
–test)
test_script=1
zpool_info
send_email
exit 0
;;
–help)
echo "Usage: $0 –status to display current status of the ZFS pools."
echo "Usage: $0 –test to send a (fake) email to the address specified in the script."
echo "Usage: $0 –help displays this help text."
exit 0
;;
*)
update_logfile
zpool_info
send_email
;;
esac
Here is an excerpt from my crontab calling the script every 15 minutes to check on the disks. And once a week to send a status update of the pools.
# m h dom mon dow command
*/15 * * * * /root/scripts/check_ZFS.sh
0 12 * * 1 /root/scripts/check_ZFS.sh –status
Of course the script can be adapted and fine tuned, but it’s a start at least. Enjoy
Cheers!