diff --git a/cmd/zed/zed.d/io-spare.sh b/cmd/zed/zed.d/io-spare.sh index dd5bf4e0f226..7ff91cae3934 100755 --- a/cmd/zed/zed.d/io-spare.sh +++ b/cmd/zed/zed.d/io-spare.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Replace a device with a hot spare in response to IO or checksum errors. # The following actions will be performed automatically when the number @@ -38,9 +38,11 @@ test -n "${ZEVENT_VDEV_GUID}" || exit 5 # Defaults to disabled, enable in the zed.rc file. ZED_SPARE_ON_IO_ERRORS=${ZED_SPARE_ON_IO_ERRORS:-0} ZED_SPARE_ON_CHECKSUM_ERRORS=${ZED_SPARE_ON_CHECKSUM_ERRORS:-0} +ZED_SPARE_ON_UNAVAIL=${ZED_SPARE_ON_UNAVAIL:-0} if [ ${ZED_SPARE_ON_IO_ERRORS} -eq 0 -a \ - ${ZED_SPARE_ON_CHECKSUM_ERRORS} -eq 0 ]; then + ${ZED_SPARE_ON_CHECKSUM_ERRORS} -eq 0 -a \ + ${ZED_SPARE_ON_UNAVAIL} -eq 0 ]; then exit 2 fi @@ -61,6 +63,17 @@ vdev_status() { return 0 } +# Given a , return the size +vdev_size() { + local VDEV=`basename $1` + + for dir in /dev /dev/disk/by-*; do + if [[ -L $dir/$VDEV ]]; then + blockdev --getsize64 $dir/$VDEV + fi + done +} + # Fault devices after N I/O errors. if [ "${ZEVENT_CLASS}" = "ereport.fs.zfs.io" ]; then ERRORS=`expr ${ZEVENT_VDEV_READ_ERRORS} + ${ZEVENT_VDEV_WRITE_ERRORS}` @@ -69,6 +82,7 @@ if [ "${ZEVENT_CLASS}" = "ereport.fs.zfs.io" ]; then ${ERRORS} -ge ${ZED_SPARE_ON_IO_ERRORS} ]; then ACTION="fault" fi + # Degrade devices after N checksum errors. elif [ "${ZEVENT_CLASS}" = "ereport.fs.zfs.checksum" ]; then ERRORS=${ZEVENT_VDEV_CKSUM_ERRORS} @@ -77,12 +91,12 @@ elif [ "${ZEVENT_CLASS}" = "ereport.fs.zfs.checksum" ]; then ${ERRORS} -ge ${ZED_SPARE_ON_CHECKSUM_ERRORS} ]; then ACTION="degrade" fi + else ACTION= fi if [ -n "${ACTION}" ]; then - # Device is already FAULTED or DEGRADED set -- `vdev_status ${ZEVENT_POOL} ${ZEVENT_VDEV_PATH}` ZEVENT_VDEV_PATH_FOUND=$1 @@ -110,10 +124,17 @@ if [ -n "${ACTION}" ]; then # Round robin through the spares selecting those which are available. # for SPARE in ${ZEVENT_VDEV_SPARE_PATHS}; do + orig_size=${ZEVENT_VDEV_SIZE} + spare_size=$(vdev_size ${SPARE}) + echo "${SPARE}: orig_size='$orig_size', spare_size='$spare_size'" >> /tmp/zed.out + set -- `vdev_status ${ZEVENT_POOL} ${SPARE}` SPARE_VDEV_FOUND=$1 STATUS=$2 + echo "SPARE_VDEV_FOUND='$SPARE_VDEV_FOUND', STATUS='$STATUS'" >> /tmp/zed.out + if [ "${STATUS}" = "AVAIL" ]; then + echo "${ZPOOL} replace ${ZEVENT_POOL} ${ZEVENT_VDEV_GUID} ${SPARE_VDEV_FOUND}" >> /tmp/zed.out ${ZPOOL} replace ${ZEVENT_POOL} \ ${ZEVENT_VDEV_GUID} ${SPARE_VDEV_FOUND} && exit 0 fi diff --git a/include/sys/fm/fs/zfs.h b/include/sys/fm/fs/zfs.h index d541b07a3729..cb039dd1042a 100644 --- a/include/sys/fm/fs/zfs.h +++ b/include/sys/fm/fs/zfs.h @@ -73,6 +73,7 @@ extern "C" { #define FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU "vdev_fru" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE "vdev_state" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_ASHIFT "vdev_ashift" +#define FM_EREPORT_PAYLOAD_ZFS_VDEV_SIZE "vdev_size" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_COMP_TS "vdev_complete_ts" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_DELTA_TS "vdev_delta_ts" #define FM_EREPORT_PAYLOAD_ZFS_VDEV_SPARE_PATHS "vdev_spare_paths" diff --git a/man/man5/zfs-events.5 b/man/man5/zfs-events.5 index 4b72484d4f1c..a25f2419bb0d 100644 --- a/man/man5/zfs-events.5 +++ b/man/man5/zfs-events.5 @@ -383,6 +383,16 @@ The GUID of the vdev in question (the vdev failing or operated upon with \fBzpool clear\fR etc). .RE +.sp +.ne 2 +.na +\fBvdev_size\fR +.ad +.RS 12n +Size of the vdev in question (the vdev failing or operated upon with +\fBzpool clear\fR etc). +.RE + .sp .ne 2 .na diff --git a/module/zfs/zfs_fm.c b/module/zfs/zfs_fm.c index fb65ec6a6525..fd8233d8f020 100644 --- a/module/zfs/zfs_fm.c +++ b/module/zfs/zfs_fm.c @@ -312,7 +312,9 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, if (pvd->vdev_path) fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH, - DATA_TYPE_STRING, pvd->vdev_path, NULL); + DATA_TYPE_STRING, pvd->vdev_path, + FM_EREPORT_PAYLOAD_ZFS_VDEV_SIZE, + DATA_TYPE_UINT64, pvd->vdev_psize, NULL); if (pvd->vdev_devid) fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_PARENT_DEVID,