From 8d396e32a82e5cc3a0d123ff52145e3298103ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Thu, 29 Apr 2021 10:40:39 +0200 Subject: [PATCH 1/5] libzutil: fix dm_get_underlying_path() return if not a DM device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example, this would happily return "/dev/(null)" for /dev/sda1 Signed-off-by: Ahelenia Ziemiańska --- lib/libzutil/os/linux/zutil_device_path_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libzutil/os/linux/zutil_device_path_os.c b/lib/libzutil/os/linux/zutil_device_path_os.c index 1775a45c6092..da7ffba764a8 100644 --- a/lib/libzutil/os/linux/zutil_device_path_os.c +++ b/lib/libzutil/os/linux/zutil_device_path_os.c @@ -346,7 +346,7 @@ dm_get_underlying_path(const char *dm_name) free(tmp); free(realp); - if (!path) { + if (!path && first_path) { /* * None of the underlying paths had a link back to their * enclosure devices. Throw up out hands and return the first From 46b243ab5c081e6fe257097a291bd63bcafc82cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Fri, 23 Apr 2021 22:27:50 +0200 Subject: [PATCH 2/5] zed.d/pool_import-led.sh: fix for current zpool scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also minor clean-up with folding state_to_val() into a case, unrolling the lesser-available seq into numbers, ignoring vdev states we don't care about, and documentation comments Signed-off-by: Tony Hutter Signed-off-by: Ahelenia Ziemiańska Closes #11934 --- cmd/zed/zed.d/statechange-led.sh | 90 ++++++++++++++++---------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/cmd/zed/zed.d/statechange-led.sh b/cmd/zed/zed.d/statechange-led.sh index e656e125d378..0f9da3204317 100755 --- a/cmd/zed/zed.d/statechange-led.sh +++ b/cmd/zed/zed.d/statechange-led.sh @@ -1,21 +1,21 @@ #!/bin/sh # -# Turn off/on the VDEV's enclosure fault LEDs when the pool's state changes. +# Turn off/on vdevs' enclosure fault LEDs when their pool's state changes. # -# Turn the VDEV's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL. -# Turn the LED off when it's back ONLINE again. +# Turn a vdev's fault LED on if it becomes FAULTED, DEGRADED or UNAVAIL. +# Turn its LED off when it's back ONLINE again. # # This script run in two basic modes: # # 1. If $ZEVENT_VDEV_ENC_SYSFS_PATH and $ZEVENT_VDEV_STATE_STR are set, then -# only set the LED for that particular VDEV. This is the case for statechange +# only set the LED for that particular vdev. This is the case for statechange # events and some vdev_* events. # -# 2. If those vars are not set, then check the state of all VDEVs in the pool +# 2. If those vars are not set, then check the state of all vdevs in the pool # and set the LEDs accordingly. This is the case for pool_import events. # # Note that this script requires that your enclosure be supported by the -# Linux SCSI enclosure services (ses) driver. The script will do nothing +# Linux SCSI Enclosure services (SES) driver. The script will do nothing # if you have no enclosure, or if your enclosure isn't supported. # # Exit codes: @@ -59,6 +59,10 @@ check_and_set_led() file="$1" val="$2" + if [ -z "$val" ]; then + return 0 + fi + if [ ! -e "$file" ] ; then return 3 fi @@ -66,11 +70,11 @@ check_and_set_led() # If another process is accessing the LED when we attempt to update it, # the update will be lost so retry until the LED actually changes or we # timeout. - for _ in $(seq 1 5); do + for _ in 1 2 3 4 5; do # We want to check the current state first, since writing to the # 'fault' entry always causes a SES command, even if the # current state is already what you want. - current=$(cat "${file}") + read -r current < "${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 @@ -85,27 +89,29 @@ check_and_set_led() else break fi - done + done } state_to_val() { state="$1" - if [ "$state" = "FAULTED" ] || [ "$state" = "DEGRADED" ] || \ - [ "$state" = "UNAVAIL" ] ; then - echo 1 - elif [ "$state" = "ONLINE" ] ; then - echo 0 - fi + case "$state" in + FAULTED|DEGRADED|UNAVAIL) + echo 1 + ;; + ONLINE) + echo 0 + ;; + esac } -# process_pool ([pool]) +# process_pool (pool) # -# Iterate through a pool (or pools) and set the VDEV's enclosure slot LEDs to -# the VDEV's state. +# Iterate through a pool and set the vdevs' enclosure slot LEDs to +# those vdevs' state. # # Arguments -# pool: Optional pool name. If not specified, iterate though all pools. +# pool: Pool name. # # Return # 0 on success, 3 on missing sysfs path @@ -113,19 +119,22 @@ state_to_val() process_pool() { pool="$1" - rc=0 - # Lookup all the current LED values and paths in parallel - #shellcheck disable=SC2016 - cmd='echo led_token=$(cat "$VDEV_ENC_SYSFS_PATH/fault"),"$VDEV_ENC_SYSFS_PATH",' - out=$($ZPOOL status -vc "$cmd" "$pool" | grep 'led_token=') - - #shellcheck disable=SC2034 - echo "$out" | while read -r vdev state read write chksum therest; do + # The output will be the vdevs only (from "grep '/dev/'"): + # + # U45 ONLINE 0 0 0 /dev/sdk 0 + # U46 ONLINE 0 0 0 /dev/sdm 0 + # U47 ONLINE 0 0 0 /dev/sdn 0 + # U50 ONLINE 0 0 0 /dev/sdbn 0 + # + ZPOOL_SCRIPTS_AS_ROOT=1 $ZPOOL status -c upath,fault_led "$pool" | grep '/dev/' | ( + rc=0 + while read -r vdev state _ _ _ therest; do # Read out current LED value and path - tmp=$(echo "$therest" | sed 's/^.*led_token=//g') - vdev_enc_sysfs_path=$(echo "$tmp" | awk -F ',' '{print $2}') - current_val=$(echo "$tmp" | awk -F ',' '{print $1}') + # Get dev name (like 'sda') + dev=$(basename "$(echo "$therest" | awk '{print $(NF-1)}')") + vdev_enc_sysfs_path=$(realpath "/sys/class/block/$dev/device/enclosure_device"*) + current_val=$(echo "$therest" | awk '{print $NF}') if [ "$current_val" != "0" ] ; then current_val=1 @@ -137,36 +146,27 @@ process_pool() fi if [ ! -e "$vdev_enc_sysfs_path/fault" ] ; then - #shellcheck disable=SC2030 - rc=1 + rc=3 zed_log_msg "vdev $vdev '$file/fault' doesn't exist" - continue; + continue fi val=$(state_to_val "$state") if [ "$current_val" = "$val" ] ; then # LED is already set correctly - continue; + continue fi if ! check_and_set_led "$vdev_enc_sysfs_path/fault" "$val"; then - rc=1 + rc=3 fi - done - - #shellcheck disable=SC2031 - if [ "$rc" = "0" ] ; then - return 0 - else - # We didn't see a sysfs entry that we wanted to set - return 3 - fi + exit "$rc"; ) } if [ -n "$ZEVENT_VDEV_ENC_SYSFS_PATH" ] && [ -n "$ZEVENT_VDEV_STATE_STR" ] ; then - # Got a statechange for an individual VDEV + # Got a statechange for an individual vdev val=$(state_to_val "$ZEVENT_VDEV_STATE_STR") vdev=$(basename "$ZEVENT_VDEV_PATH") check_and_set_led "$ZEVENT_VDEV_ENC_SYSFS_PATH/fault" "$val" From 7e1ebbc6d7e04e8e34942ba2fa6bc58cefe57160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Fri, 23 Apr 2021 22:41:19 +0200 Subject: [PATCH 3/5] zed.d/*-notify.sh: use mktemp instead of generating temp path manually MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ahelenia Ziemiańska --- cmd/zed/zed.d/data-notify.sh | 2 +- cmd/zed/zed.d/generic-notify.sh | 2 +- cmd/zed/zed.d/scrub_finish-notify.sh | 2 +- cmd/zed/zed.d/statechange-notify.sh | 2 +- cmd/zed/zed.d/trim_finish-notify.sh | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/zed/zed.d/data-notify.sh b/cmd/zed/zed.d/data-notify.sh index 639b459bdd3b..792d30a66d23 100755 --- a/cmd/zed/zed.d/data-notify.sh +++ b/cmd/zed/zed.d/data-notify.sh @@ -25,7 +25,7 @@ zed_rate_limit "${rate_limit_tag}" || exit 3 umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} error for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has detected a data error:" echo diff --git a/cmd/zed/zed.d/generic-notify.sh b/cmd/zed/zed.d/generic-notify.sh index e438031a088a..1db26980c1a0 100755 --- a/cmd/zed/zed.d/generic-notify.sh +++ b/cmd/zed/zed.d/generic-notify.sh @@ -31,7 +31,7 @@ umask 077 pool_str="${ZEVENT_POOL:+" for ${ZEVENT_POOL}"}" host_str=" on $(hostname)" note_subject="ZFS ${ZEVENT_SUBCLASS} event${pool_str}${host_str}" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has posted the following event:" echo diff --git a/cmd/zed/zed.d/scrub_finish-notify.sh b/cmd/zed/zed.d/scrub_finish-notify.sh index 2145a100a3fa..5c0124b8d7e7 100755 --- a/cmd/zed/zed.d/scrub_finish-notify.sh +++ b/cmd/zed/zed.d/scrub_finish-notify.sh @@ -41,7 +41,7 @@ fi umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} event for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has finished a ${action}:" echo diff --git a/cmd/zed/zed.d/statechange-notify.sh b/cmd/zed/zed.d/statechange-notify.sh index f46080a03239..76f09061c5b5 100755 --- a/cmd/zed/zed.d/statechange-notify.sh +++ b/cmd/zed/zed.d/statechange-notify.sh @@ -37,7 +37,7 @@ fi umask 077 note_subject="ZFS device fault for pool ${ZEVENT_POOL_GUID} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { if [ "${ZEVENT_VDEV_STATE_STR}" = "FAULTED" ] ; then echo "The number of I/O errors associated with a ZFS device exceeded" diff --git a/cmd/zed/zed.d/trim_finish-notify.sh b/cmd/zed/zed.d/trim_finish-notify.sh index 5075302997e3..8fdb64531d0a 100755 --- a/cmd/zed/zed.d/trim_finish-notify.sh +++ b/cmd/zed/zed.d/trim_finish-notify.sh @@ -19,7 +19,7 @@ zed_check_cmd "${ZPOOL}" || exit 9 umask 077 note_subject="ZFS ${ZEVENT_SUBCLASS} event for ${ZEVENT_POOL} on $(hostname)" -note_pathname="${TMPDIR:="/tmp"}/$(basename -- "$0").${ZEVENT_EID}.$$" +note_pathname="$(mktemp)" { echo "ZFS has finished a trim:" echo From 5fba73264c6c577713217c9ee8484d2dbe85daf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Fri, 23 Apr 2021 22:41:47 +0200 Subject: [PATCH 4/5] zed.d/history_event-zfs-list-cacher.sh: no grep for snapshot detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ahelenia Ziemiańska --- cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in b/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in index bf5a121f6a79..15f0a8ed6189 100755 --- a/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in +++ b/cmd/zed/zed.d/history_event-zfs-list-cacher.sh.in @@ -14,10 +14,10 @@ FSLIST="${FSLIST_DIR}/${ZEVENT_POOL}" . "${ZED_ZEDLET_DIR}/zed-functions.sh" [ "$ZEVENT_SUBCLASS" != "history_event" ] && exit 0 -zed_check_cmd "${ZFS}" sort diff grep +zed_check_cmd "${ZFS}" sort diff # If we are acting on a snapshot, we have nothing to do -printf '%s' "${ZEVENT_HISTORY_DSNAME}" | grep '@' && exit 0 +[ "${ZEVENT_HISTORY_DSNAME%@*}" = "${ZEVENT_HISTORY_DSNAME}" ] || exit 0 # We obtain a lock on zfs-list to avoid any simultaneous writes. # If we run into trouble, log and drop the lock From 66c0a07bca2e7c2dd4f8cbb98357b63cba5ac2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Tue, 27 Apr 2021 17:27:33 +0200 Subject: [PATCH 5/5] zed.d/zed-functions.sh: fix zed_guid_to_pool() on dash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ahelenia Ziemiańska Closes #11954 --- cmd/zed/zed.d/zed-functions.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/zed/zed.d/zed-functions.sh b/cmd/zed/zed.d/zed-functions.sh index 44a9b8d23303..1fd3888625b2 100644 --- a/cmd/zed/zed.d/zed-functions.sh +++ b/cmd/zed/zed.d/zed-functions.sh @@ -367,7 +367,7 @@ zed_notify_pushbullet() # # Notification via Slack Webhook . # The Webhook URL (ZED_SLACK_WEBHOOK_URL) identifies this client to the -# Slack channel. +# Slack channel. # # Requires awk, curl, and sed executables to be installed in the standard PATH. # @@ -511,10 +511,8 @@ zed_guid_to_pool() return fi - guid=$(printf "%llu" "$1") - if [ -n "$guid" ] ; then - $ZPOOL get -H -ovalue,name guid | awk '$1=='"$guid"' {print $2}' - fi + guid="$(printf "%u" "$1")" + $ZPOOL get -H -ovalue,name guid | awk '$1 == '"$guid"' {print $2; exit}' } # zed_exit_if_ignoring_this_event