How to run a command once a ZFS scrub *completes*?

Solution 1:

On ZFS On Linux, starting with version 0.6.3 this can be handled quite elegantly by using the ZFS Event Daemon (zed). The event daemon, by virtue of monitoring the kernel events directly, can react almost immediately to any events that take place and does not depend on continuous polling and parsing of some other command's output.

Create a shell script with any file name that begins with /etc/zfs/zed.d/scrub.finish (for example, That script can take any appropriate action, such as sending an email, writing a log entry somewhere, or making the system sing and dance (OK, maybe not that). Examples are provided that can provide a starting point.

If all you want is to receive an email when the scrub completes, the provided script will do that nicely. Simply edit /etc/zfs/zed.d/zed.rc to indicate to where the email should be sent and whether an email should be sent also if the pool is not experiencing any problems, make sure something named scrub.finish followed by anything in /etc/zfs/zed.d leads to it, and make sure zed is started on boot.

Solution 2:

I use this simple script for scrubbing status reporting by email.

  • zpadmin

If you need to detect transition from scrub running to scrub finished I would check the state field of zpool status output. Something like this:

# start scrubbing 
zpool scrub ZPOOL

# wait till scrub is finished
while zpool status ZPOOL | grep 'scan:  *scrub in progress' > /dev/null; do
   echo -n '.'
   sleep 10

# send a report
zpool status | mail -s "zpool status: ZPOOL" RECIPIENT

Solution 3:

Although this question is specific to linux, it is the first google result when searching for "wait until scrub is finished", therefore I'd like to add some useful information for people running OpenSolaris (tested it on OmniOS, but SmartOS, illumos etc. should be similar) instead of Linux (normal Solaris should also work, but I did not test it there).

You can use syseventadm to register kernel events. The complete list can be found in /usr/include/sys/sysevent/eventdefs.h (just search for "ZFS" in this file). After adding events, the service has to be restarted, for example:

syseventadm add -c EC_zfs -s ESC_ZFS_scrub_finish /path/to/ \$pool_name
syseventadm restart

This way, the script will be started when any scrubbing of any pool finishes - you have to check inside the script if $1 equals your desired pool name. Still, it is much less overhead than polling.

Solution 4:

I have had much success with zfswatcher