summaryrefslogtreecommitdiffstats
path: root/cmd/zed/zed.d/statechange-led.sh
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/zed/zed.d/statechange-led.sh')
-rwxr-xr-xcmd/zed/zed.d/statechange-led.sh88
1 files changed, 88 insertions, 0 deletions
diff --git a/cmd/zed/zed.d/statechange-led.sh b/cmd/zed/zed.d/statechange-led.sh
new file mode 100755
index 000000000..ca911d2b9
--- /dev/null
+++ b/cmd/zed/zed.d/statechange-led.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+#
+# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes.
+#
+# Turn LED on if the VDEV becomes faulted/degraded, and turn it back off when
+# it's healthy again. This requires that your enclosure be supported by the
+# 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
+# 3: ZED built without libdevmapper
+
+[ -f "${ZED_ZEDLET_DIR}/zed.rc" ] && . "${ZED_ZEDLET_DIR}/zed.rc"
+. "${ZED_ZEDLET_DIR}/zed-functions.sh"
+
+# ZEVENT_VDEV_UPATH will not be present if ZFS is not built with libdevmapper
+[ -n "${ZEVENT_VDEV_UPATH}" ] || exit 3
+
+if [ "${ZED_USE_ENCLOSURE_LEDS}" != "1" ] ; then
+ exit 2
+fi
+
+if [ ! -d /sys/class/enclosure ] ; then
+ exit 1
+fi
+
+# Turn on/off enclosure LEDs
+function led
+{
+ name=$1
+ 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.
+ if [ -e /sys/block/$name/device/enclosure_device*/fault ] ; then
+ # We have to do some monkey business to deal with spaces in
+ # enclosure_device names. I've seen horrible things like this:
+ #
+ # '/sys/block/sdfw/device/enclosure_device:SLOT 43 41 /fault'
+ #
+ # ...so escape all spaces.
+ file=`ls /sys/block/$name/device/enclosure_device*/fault | sed 's/\s/\\ /g'`
+
+ current=`cat "$file"`
+
+ # 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
+
+ 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"
+ fi
+ fi
+}
+
+# Decide whether to turn on/off an LED based on the state
+# Pass in path name and fault string ("ONLINE"/"FAULTED"/"DEGRADED"...etc)
+function process {
+ # path=/dev/sda, fault=
+
+ path=$1
+ fault=$2
+ name=`basename $path`
+
+ if [ -z "$name" ] ; then
+ return
+ fi
+
+ if [ "$fault" == "FAULTED" ] || [ "$fault" == "DEGRADED" ] ; then
+ led $name 1
+ else
+ led $name 0
+ fi
+}
+
+process "$ZEVENT_VDEV_UPATH" "$ZEVENT_VDEV_STATE_STR"