/etc/zfs/zfs_pool_alert is in zfs-fuse 0.7.0-18build1.
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");
}
}
|