/etc/zfs/zfs_pool_alert is in zfs-fuse 0.7.0-16.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57  | #!/usr/bin/perl
# example zfs_pool_alert script
# ###########################################################################
# To be copied into /etc/zfs/zfs_pool_alert (and made executable) if you plan
# on using automatic recovery on vdev failure.
# ###########################################################################
# zfs_pool_alert : this command is executed everytime a pool passes from the
# state HEALTHY to DEGRADED, or the other way around.
# It receives only the pool name as argument.
# Here this script tries to :
#  - if the new state is degraded
#    - if there are some spares available, try to use 1
#    - otherwise send a mail to tell a vdev is failing for this pool
#  - if the new state is healthy
#    - if there are still some spares in use, execute zpool clear, spares are
#    usually removed quite some time after that without sending any command.
use strict;
my $zpool = "zpool";
my $pool = shift @ARGV;
my $status = `$zpool status $pool`;
my ($state) = $status =~ /state: (.+)/;
if ($state eq "DEGRADED") {
	# get the 1st avail spare
	my ($spare) = $status =~ /[ \t]+(.+)[ \t]+AVAIL/; 
	my ($dev, $cur, $comment) = $status =~ /[ \t]+(.+)[ \t]+(UNAVAIL|FAULTED)[ \t\d]+(.+)/;
	if ($spare) {
		$spare = "/dev/$spare" if ($spare !~ /\//);
		if ($dev) {
			print "dev :$dev:\n";
			if ($comment =~ /was (.+)/) {
				$dev = $1;
			}
			$dev = "/dev/$dev" if ($dev !~ /\//);
			system("$zpool replace $pool $dev $spare");
		} else {
			print "no dev $dev,$cur,$comment\n";
		}
	} else {
# a vdev is failing and there is no spare -> send a mail ?
		system("echo automatic mail generated by zfs_pool_alert | ".
		"mail -s 'vdev $dev is failing for pool $pool' root");
	}
} else {
	my ($spare) = $status =~ /[ \t]+(.+)[ \t]+INUSE/; 
	if ($spare) {
# There is a spare in use, but the pool is already healthy, be sure to clear
# the errors then. Notice : the spare is not removed immediately then, and it
# can be quite long. Don't know why !
		sleep 3;
		system("$zpool clear $pool");
	}
}
 |