X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzfs_fm.c;h=af2030ae7f3670a57c8289c924ed21a974880867;hb=refs%2Fheads%2Frertzinger%2Ffeature-zpool-get--p;hp=0b4812666442de49edd3bc310ce124285b877387;hpb=428870ff734fdaccc342b33fc53cf94724409a46;p=zfs.git diff --git a/module/zfs/zfs_fm.c b/module/zfs/zfs_fm.c index 0b48126..af2030a 100644 --- a/module/zfs/zfs_fm.c +++ b/module/zfs/zfs_fm.c @@ -23,6 +23,10 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2012 by Delphix. All rights reserved. + */ + #include #include #include @@ -99,6 +103,16 @@ */ #ifdef _KERNEL static void +zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector) +{ + if (nvl) + fm_nvlist_destroy(nvl, FM_NVA_FREE); + + if (detector) + fm_nvlist_destroy(detector, FM_NVA_FREE); +} + +static void zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, uint64_t stateoroffset, uint64_t size) @@ -134,22 +148,6 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, zio->io_type != ZIO_TYPE_WRITE) return; - /* - * Ignore any errors from speculative I/Os, as failure is an - * expected result. - */ - if (zio->io_flags & ZIO_FLAG_SPECULATIVE) - return; - - /* - * If this I/O is not a retry I/O, don't post an ereport. - * Otherwise, we risk making bad diagnoses based on B_FAILFAST - * I/Os. - */ - if (zio->io_error == EIO && - !(zio->io_flags & ZIO_FLAG_IO_RETRY)) - return; - if (vd != NULL) { /* * If the vdev has already been marked as failing due @@ -252,6 +250,7 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, if (vd != NULL) { vdev_t *pvd = vd->vdev_parent; + vdev_queue_t *vq = &vd->vdev_queue; fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, DATA_TYPE_UINT64, vd->vdev_guid, @@ -269,6 +268,19 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_VDEV_FRU, DATA_TYPE_STRING, vd->vdev_fru, NULL); + if (vd->vdev_ashift) + fm_payload_set(ereport, + FM_EREPORT_PAYLOAD_ZFS_VDEV_ASHIFT, + DATA_TYPE_UINT64, vd->vdev_ashift, NULL); + + if (vq != NULL) { + fm_payload_set(ereport, + FM_EREPORT_PAYLOAD_ZFS_VDEV_COMP_TS, + DATA_TYPE_UINT64, vq->vq_io_complete_ts, NULL); + fm_payload_set(ereport, + FM_EREPORT_PAYLOAD_ZFS_VDEV_DELTA_TS, + DATA_TYPE_UINT64, vq->vq_io_delta_ts, NULL); + } if (pvd != NULL) { fm_payload_set(ereport, @@ -294,6 +306,20 @@ zfs_ereport_start(nvlist_t **ereport_out, nvlist_t **detector_out, */ fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_ERR, DATA_TYPE_INT32, zio->io_error, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_FLAGS, + DATA_TYPE_INT32, zio->io_flags, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_STAGE, + DATA_TYPE_UINT32, zio->io_stage, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_PIPELINE, + DATA_TYPE_UINT32, zio->io_pipeline, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DELAY, + DATA_TYPE_UINT64, zio->io_delay, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_TIMESTAMP, + DATA_TYPE_UINT64, zio->io_timestamp, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DEADLINE, + DATA_TYPE_UINT64, zio->io_deadline, NULL); + fm_payload_set(ereport, FM_EREPORT_PAYLOAD_ZFS_ZIO_DELTA, + DATA_TYPE_UINT64, zio->io_delta, NULL); /* * If the 'size' parameter is non-zero, it indicates this is a @@ -410,7 +436,7 @@ update_histogram(uint64_t value_arg, uint16_t *hist, uint32_t *count) * to the new smallest gap, to prepare for our next invocation. */ static void -shrink_ranges(zfs_ecksum_info_t *eip) +zei_shrink_ranges(zfs_ecksum_info_t *eip) { uint32_t mingap = UINT32_MAX; uint32_t new_allowed_gap = eip->zei_mingap + 1; @@ -429,12 +455,13 @@ shrink_ranges(zfs_ecksum_info_t *eip) uint32_t end = r[idx].zr_end; while (idx < max - 1) { - idx++; + uint32_t nstart, nend, gap; - uint32_t nstart = r[idx].zr_start; - uint32_t nend = r[idx].zr_end; + idx++; + nstart = r[idx].zr_start; + nend = r[idx].zr_end; - uint32_t gap = nstart - end; + gap = nstart - end; if (gap < new_allowed_gap) { end = nend; continue; @@ -454,13 +481,13 @@ shrink_ranges(zfs_ecksum_info_t *eip) } static void -add_range(zfs_ecksum_info_t *eip, int start, int end) +zei_add_range(zfs_ecksum_info_t *eip, int start, int end) { struct zei_ranges *r = eip->zei_ranges; size_t count = eip->zei_range_count; if (count >= MAX_RANGES) { - shrink_ranges(eip); + zei_shrink_ranges(eip); count = eip->zei_range_count; } if (count == 0) { @@ -482,7 +509,7 @@ add_range(zfs_ecksum_info_t *eip, int start, int end) } static size_t -range_total_size(zfs_ecksum_info_t *eip) +zei_range_total_size(zfs_ecksum_info_t *eip) { struct zei_ranges *r = eip->zei_ranges; size_t count = eip->zei_range_count; @@ -516,7 +543,7 @@ annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info, size_t offset = 0; ssize_t start = -1; - zfs_ecksum_info_t *eip = kmem_zalloc(sizeof (*eip), KM_SLEEP); + zfs_ecksum_info_t *eip = kmem_zalloc(sizeof (*eip), KM_PUSHPAGE); /* don't do any annotation for injected checksum errors */ if (info != NULL && info->zbc_injected) @@ -559,7 +586,7 @@ annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info, if (start == -1) continue; - add_range(eip, start, idx); + zei_add_range(eip, start, idx); start = -1; } else { if (start != -1) @@ -569,10 +596,10 @@ annotate_ecksum(nvlist_t *ereport, zio_bad_cksum_t *info, } } if (start != -1) - add_range(eip, start, idx); + zei_add_range(eip, start, idx); /* See if it will fit in our inline buffers */ - inline_size = range_total_size(eip); + inline_size = zei_range_total_size(eip); if (inline_size > ZFM_MAX_INLINE) no_inline = 1; @@ -675,10 +702,8 @@ zfs_ereport_post(const char *subclass, spa_t *spa, vdev_t *vd, zio_t *zio, if (ereport == NULL) return; - fm_ereport_post(ereport, EVCH_SLEEP); - - fm_nvlist_destroy(ereport, FM_NVA_FREE); - fm_nvlist_destroy(detector, FM_NVA_FREE); + /* Cleanup is handled by the callback function */ + zfs_zevent_post(ereport, detector, zfs_zevent_post_cb); #endif } @@ -687,7 +712,7 @@ zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, struct zio *zio, uint64_t offset, uint64_t length, void *arg, zio_bad_cksum_t *info) { - zio_cksum_report_t *report = kmem_zalloc(sizeof (*report), KM_SLEEP); + zio_cksum_report_t *report = kmem_zalloc(sizeof (*report), KM_PUSHPAGE); if (zio->io_vsd != NULL) zio->io_vsd_ops->vsd_cksum_report(zio, report, arg); @@ -696,7 +721,7 @@ zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, /* copy the checksum failure information if it was provided */ if (info != NULL) { - report->zcr_ckinfo = kmem_zalloc(sizeof (*info), KM_SLEEP); + report->zcr_ckinfo = kmem_zalloc(sizeof (*info), KM_PUSHPAGE); bcopy(info, report->zcr_ckinfo, sizeof (*info)); } @@ -709,6 +734,10 @@ zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, if (report->zcr_ereport == NULL) { report->zcr_free(report->zcr_cbdata, report->zcr_cbinfo); + if (report->zcr_ckinfo != NULL) { + kmem_free(report->zcr_ckinfo, + sizeof (*report->zcr_ckinfo)); + } kmem_free(report, sizeof (*report)); return; } @@ -730,12 +759,10 @@ zfs_ereport_finish_checksum(zio_cksum_report_t *report, good_data, bad_data, report->zcr_length, drop_if_identical); if (info != NULL) - fm_ereport_post(report->zcr_ereport, EVCH_SLEEP); + zfs_zevent_post(report->zcr_ereport, + report->zcr_detector, zfs_zevent_post_cb); - fm_nvlist_destroy(report->zcr_ereport, FM_NVA_FREE); - fm_nvlist_destroy(report->zcr_detector, FM_NVA_FREE); report->zcr_ereport = report->zcr_detector = NULL; - if (info != NULL) kmem_free(info, sizeof (*info)); #endif @@ -764,7 +791,7 @@ void zfs_ereport_send_interim_checksum(zio_cksum_report_t *report) { #ifdef _KERNEL - fm_ereport_post(report->zcr_ereport, EVCH_SLEEP); + zfs_zevent_post(report->zcr_ereport, report->zcr_detector, NULL); #endif } @@ -787,14 +814,10 @@ zfs_ereport_post_checksum(spa_t *spa, vdev_t *vd, info = annotate_ecksum(ereport, zbc, good_data, bad_data, length, B_FALSE); - if (info != NULL) - fm_ereport_post(ereport, EVCH_SLEEP); - - fm_nvlist_destroy(ereport, FM_NVA_FREE); - fm_nvlist_destroy(detector, FM_NVA_FREE); - - if (info != NULL) + if (info != NULL) { + zfs_zevent_post(ereport, detector, zfs_zevent_post_cb); kmem_free(info, sizeof (*info)); + } #endif } @@ -817,13 +840,14 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name) VERIFY(nvlist_add_string(resource, FM_CLASS, class) == 0); VERIFY(nvlist_add_uint64(resource, FM_EREPORT_PAYLOAD_ZFS_POOL_GUID, spa_guid(spa)) == 0); - if (vd) + if (vd) { VERIFY(nvlist_add_uint64(resource, FM_EREPORT_PAYLOAD_ZFS_VDEV_GUID, vd->vdev_guid) == 0); + VERIFY(nvlist_add_uint64(resource, + FM_EREPORT_PAYLOAD_ZFS_VDEV_STATE, vd->vdev_state) == 0); + } - fm_ereport_post(resource, EVCH_SLEEP); - - fm_nvlist_destroy(resource, FM_NVA_FREE); + zfs_zevent_post(resource, NULL, zfs_zevent_post_cb); #endif } @@ -836,7 +860,7 @@ zfs_post_common(spa_t *spa, vdev_t *vd, const char *name) void zfs_post_remove(spa_t *spa, vdev_t *vd) { - zfs_post_common(spa, vd, FM_RESOURCE_REMOVED); + zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_REMOVED); } /* @@ -847,7 +871,7 @@ zfs_post_remove(spa_t *spa, vdev_t *vd) void zfs_post_autoreplace(spa_t *spa, vdev_t *vd) { - zfs_post_common(spa, vd, FM_RESOURCE_AUTOREPLACE); + zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_AUTOREPLACE); } /* @@ -859,5 +883,13 @@ zfs_post_autoreplace(spa_t *spa, vdev_t *vd) void zfs_post_state_change(spa_t *spa, vdev_t *vd) { - zfs_post_common(spa, vd, FM_RESOURCE_STATECHANGE); + zfs_post_common(spa, vd, FM_EREPORT_RESOURCE_STATECHANGE); } + +#if defined(_KERNEL) && defined(HAVE_SPL) +EXPORT_SYMBOL(zfs_ereport_post); +EXPORT_SYMBOL(zfs_ereport_post_checksum); +EXPORT_SYMBOL(zfs_post_remove); +EXPORT_SYMBOL(zfs_post_autoreplace); +EXPORT_SYMBOL(zfs_post_state_change); +#endif /* _KERNEL */