diff options
author | Don Brady <[email protected]> | 2017-06-16 18:21:11 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2017-06-16 17:21:11 -0700 |
commit | 0241e491a08ffa471a08ceaa0b0943999d775cbe (patch) | |
tree | 17f07ce2cf37c4f19155dba12851c8eab519c8a1 /module/zfs/zio_inject.c | |
parent | 05a5357a6c63b8c83062c1b295ee98d14f8e85aa (diff) |
Inject zinject(8) a percentage amount of dev errs
In the original form of device error injection, it was an all or nothing
situation. To help simulate intermittent error conditions, you can now
specify a real number percentage value. This is also very useful for our
ZFS fault diagnosis testing and for injecting intermittent errors during
load testing.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Don Brady <[email protected]>
Closes #6227
Diffstat (limited to 'module/zfs/zio_inject.c')
-rw-r--r-- | module/zfs/zio_inject.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/module/zfs/zio_inject.c b/module/zfs/zio_inject.c index 0e8e9d932..4a4d431e3 100644 --- a/module/zfs/zio_inject.c +++ b/module/zfs/zio_inject.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. + * Copyright (c) 2017, Intel Corporation. */ /* @@ -99,6 +100,26 @@ static kmutex_t inject_delay_mtx; static int inject_next_id = 1; /* + * Test if the requested frequency was triggered + */ +static boolean_t +freq_triggered(uint32_t frequency) +{ + /* + * zero implies always (100%) + */ + if (frequency == 0) + return (B_TRUE); + + /* + * Note: we still handle legacy (unscaled) frequecy values + */ + uint32_t maximum = (frequency <= 100) ? 100 : ZI_PERCENTAGE_MAX; + + return (spa_get_random(maximum) < frequency); +} + +/* * Returns true if the given record matches the I/O in progress. */ static boolean_t @@ -113,8 +134,7 @@ zio_match_handler(zbookmark_phys_t *zb, uint64_t type, record->zi_object == DMU_META_DNODE_OBJECT) { if (record->zi_type == DMU_OT_NONE || type == record->zi_type) - return (record->zi_freq == 0 || - spa_get_random(100) < record->zi_freq); + return (freq_triggered(record->zi_freq)); else return (B_FALSE); } @@ -128,8 +148,7 @@ zio_match_handler(zbookmark_phys_t *zb, uint64_t type, zb->zb_blkid >= record->zi_start && zb->zb_blkid <= record->zi_end && error == record->zi_error) - return (record->zi_freq == 0 || - spa_get_random(100) < record->zi_freq); + return (freq_triggered(record->zi_freq)); return (B_FALSE); } @@ -294,6 +313,12 @@ zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error) if (handler->zi_record.zi_error == error) { /* + * limit error injection if requested + */ + if (!freq_triggered(handler->zi_record.zi_freq)) + continue; + + /* * For a failed open, pretend like the device * has gone away. */ @@ -466,10 +491,8 @@ zio_handle_io_delay(zio_t *zio) if (handler->zi_record.zi_cmd != ZINJECT_DELAY_IO) continue; - if (handler->zi_record.zi_freq != 0 && - spa_get_random(100) >= handler->zi_record.zi_freq) { + if (!freq_triggered(handler->zi_record.zi_freq)) continue; - } if (vd->vdev_guid != handler->zi_record.zi_guid) continue; |