diff --git a/cmd/zed/agents/zfs_diagnosis.c b/cmd/zed/agents/zfs_diagnosis.c index 4fe9ee2bc5b2..813916d2e82c 100644 --- a/cmd/zed/agents/zfs_diagnosis.c +++ b/cmd/zed/agents/zfs_diagnosis.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "zfs_agents.h" #include "fmd_api.h" @@ -770,6 +771,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) { char *failmode = NULL; boolean_t checkremove = B_FALSE; + uint32_t pri = 0; + int32_t flags = 0; /* * If this is a checksum or I/O error, then toss it into the @@ -792,6 +795,23 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) checkremove = B_TRUE; } else if (fmd_nvl_class_match(hdl, nvl, ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_CHECKSUM))) { + /* + * We ignore ereports for checksum errors generated by + * scrub/resilver I/O to avoid potentially further + * degrading the pool while it's being repaired. + */ + if (((nvlist_lookup_uint32(nvl, + FM_EREPORT_PAYLOAD_ZFS_ZIO_PRIORITY, &pri) == 0) && + (pri == ZIO_PRIORITY_SCRUB || + pri == ZIO_PRIORITY_REBUILD)) || + ((nvlist_lookup_int32(nvl, + FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, &flags) == 0) && + (flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)))) { + fmd_hdl_debug(hdl, "ignoring '%s' for " + "scrub/resilver I/O", class); + return; + } + if (zcp->zc_data.zc_serd_checksum[0] == '\0') { zfs_serd_name(zcp->zc_data.zc_serd_checksum, pool_guid, vdev_guid, "checksum");