2016-10-19 19:55:59 +00:00
|
|
|
#!/bin/bash
|
|
|
|
#
|
|
|
|
# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes.
|
|
|
|
#
|
2016-10-24 17:45:59 +00:00
|
|
|
# Turn LED on if the VDEV becomes faulted or degraded, and turn it back off
|
|
|
|
# when it's online again. It will also turn on the LED (or keep it on) if
|
|
|
|
# the drive becomes unavailable, unless the drive was in was a previously
|
|
|
|
# online state (online->unavail is a normal state transition during an
|
|
|
|
# autoreplace).
|
|
|
|
#
|
|
|
|
# This script requires that your enclosure be supported by the
|
2016-10-19 19:55:59 +00:00
|
|
|
# Linux SCSI enclosure services (ses) driver. The script will do nothing
|
|
|
|
# if you have no enclosure, or if your enclosure isn't supported.
|
|
|
|
#
|
|
|
|
# This script also requires ZFS to be built with libdevmapper support.
|
|
|
|
#
|
|
|
|
# Exit codes:
|
|
|
|
# 0: enclosure led successfully set
|
|
|
|
# 1: enclosure leds not not available
|
|
|
|
# 2: enclosure leds administratively disabled
|
2016-10-24 17:45:59 +00:00
|
|
|
# 3: ZED didn't pass enclosure sysfs path
|
|
|
|
# 4: Enclosure sysfs path doesn't exist
|
2016-10-19 19:55:59 +00:00
|
|
|
|
|
|
|
[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
|
|
|
|
. "${ZED_ZEDLET_DIR}/zed-functions.sh"
|
|
|
|
|
2016-10-24 17:45:59 +00:00
|
|
|
if [ ! -d /sys/class/enclosure ] ; then
|
|
|
|
exit 1
|
|
|
|
fi
|
2016-10-19 19:55:59 +00:00
|
|
|
|
|
|
|
if [ "${ZED_USE_ENCLOSURE_LEDS}" != "1" ] ; then
|
|
|
|
exit 2
|
|
|
|
fi
|
|
|
|
|
2016-10-24 17:45:59 +00:00
|
|
|
[ -n "${ZEVENT_VDEV_ENC_SYSFS_PATH}" ] || exit 3
|
|
|
|
|
|
|
|
[ -e "${ZEVENT_VDEV_ENC_SYSFS_PATH}/fault" ] || exit 4
|
2016-10-19 19:55:59 +00:00
|
|
|
|
|
|
|
# Turn on/off enclosure LEDs
|
|
|
|
function led
|
|
|
|
{
|
2016-10-24 17:45:59 +00:00
|
|
|
file="$1/fault"
|
2016-10-19 19:55:59 +00:00
|
|
|
val=$2
|
|
|
|
|
|
|
|
# We want to check the current state first, since writing to the
|
|
|
|
# 'fault' entry always always causes a SES command, even if the
|
|
|
|
# current state is already what you want.
|
2016-10-24 17:45:59 +00:00
|
|
|
current=$(cat "${file}")
|
2016-10-19 19:55:59 +00:00
|
|
|
|
2016-10-24 17:45:59 +00:00
|
|
|
# On some enclosures if you write 1 to fault, and read it back,
|
|
|
|
# it will return 2. Treat all non-zero values as 1 for
|
|
|
|
# simplicity.
|
|
|
|
if [ "$current" != "0" ] ; then
|
|
|
|
current=1
|
|
|
|
fi
|
2016-10-19 19:55:59 +00:00
|
|
|
|
2016-10-24 17:45:59 +00:00
|
|
|
if [ "$current" != "$val" ] ; then
|
|
|
|
# Set the value twice. I've seen enclosures that were
|
|
|
|
# flakey about setting it the first time.
|
|
|
|
echo "$val" > "$file"
|
|
|
|
echo "$val" > "$file"
|
2016-10-19 19:55:59 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Decide whether to turn on/off an LED based on the state
|
|
|
|
# Pass in path name and fault string ("ONLINE"/"FAULTED"/"DEGRADED"...etc)
|
2016-10-24 17:45:59 +00:00
|
|
|
#
|
|
|
|
# We only turn on LEDs when a drive becomes FAULTED, DEGRADED, or UNAVAIL and
|
|
|
|
# only turn it on when it comes back ONLINE. All other states are ignored, and
|
|
|
|
# keep the previous LED state.
|
2016-10-19 19:55:59 +00:00
|
|
|
function process {
|
2016-10-24 17:45:59 +00:00
|
|
|
path="$1"
|
2016-10-19 19:55:59 +00:00
|
|
|
fault=$2
|
2016-10-25 18:05:30 +00:00
|
|
|
if [ "$fault" == "FAULTED" ] || [ "$fault" == "DEGRADED" ] || \
|
|
|
|
[ "$fault" == "UNAVAIL" ] ; then
|
2016-10-24 17:45:59 +00:00
|
|
|
led "$path" 1
|
|
|
|
elif [ "$fault" == "ONLINE" ] ; then
|
|
|
|
led "$path" 0
|
2016-10-19 19:55:59 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2016-10-25 18:05:30 +00:00
|
|
|
process "$ZEVENT_VDEV_ENC_SYSFS_PATH" "$ZEVENT_VDEV_STATE_STR"
|