diff --git a/cmd/zed/zed.d/io-spare.sh b/cmd/zed/zed.d/io-spare.sh index b64b2a9f1160..f9f3c19a5ba9 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 @@ -62,6 +62,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}` @@ -70,6 +81,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} @@ -78,12 +90,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 @@ -111,10 +123,18 @@ 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 "${ZEVENT_POOL}:${ZEVENT_VDEV_GUID} = '$orig_size'" >> /tmp/zed.out + echo "${ZEVENT_POOL}:${SPARE} = '$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..5b44a396b8e5 100644 --- a/include/sys/fm/fs/zfs.h +++ b/include/sys/fm/fs/zfs.h @@ -73,6 +73,10 @@ 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_ASIZE "vdev_asize" +#define FM_EREPORT_PAYLOAD_ZFS_VDEV_PSIZE "vdev_psize" +#define FM_EREPORT_PAYLOAD_ZFS_VDEV_MIN_ASIZE "vdev_min_asize" +#define FM_EREPORT_PAYLOAD_ZFS_VDEV_MAX_ASIZE "vdev_max_asize" #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..b77092fdc6d6 100644 --- a/man/man5/zfs-events.5 +++ b/man/man5/zfs-events.5 @@ -383,6 +383,43 @@ The GUID of the vdev in question (the vdev failing or operated upon with \fBzpool clear\fR etc). .RE +.sp +.ne 2 +.na +\fBvdev_asize\fR +.ad +.RS 12n +Allocatable device capacity +.RE + +.sp +.ne 2 +.na +\fBvdev_min_asize\fR +.ad +.RS 12n +Min acceptable asize +.RE + +.sp +.ne 2 +.na +\fBvdev_max_asize\fR +.ad +.RS 12n +Max acceptable asize +.RE + +.sp +.ne 2 +.na +\fBvdev_psize\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 7e9c473d3ea4..802c330fa0cc 100644 --- a/module/zfs/zfs_fm.c +++ b/module/zfs/zfs_fm.c @@ -309,6 +309,16 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, FM_EREPORT_PAYLOAD_ZFS_PARENT_TYPE, DATA_TYPE_STRING, pvd->vdev_ops->vdev_op_type, NULL); + fm_payload_set(ereport, + FM_EREPORT_PAYLOAD_ZFS_VDEV_ASIZE, + DATA_TYPE_UINT64, pvd->vdev_asize, + FM_EREPORT_PAYLOAD_ZFS_VDEV_PSIZE, + DATA_TYPE_UINT64, pvd->vdev_psize, + FM_EREPORT_PAYLOAD_ZFS_VDEV_MIN_ASIZE, + DATA_TYPE_UINT64, pvd->vdev_min_asize, + FM_EREPORT_PAYLOAD_ZFS_VDEV_MAX_ASIZE, + DATA_TYPE_UINT64, pvd->vdev_max_asize, + NULL); if (pvd->vdev_path) fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_PARENT_PATH,