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:

  1. It lists all the pools available on the machine and puts them into a variable.
  2. It loops through the pools stored in the variable and looks for certain words in order to see if it is OK or degraded.
  3. Depending on the status it will send an email or not.
  4. 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!

Mastodon