mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
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 <behlendorf1@llnl.gov> Signed-off-by: Don Brady <don.brady@intel.com> Closes #6227
This commit is contained in:
committed by
Brian Behlendorf
parent
05a5357a6c
commit
0241e491a0
+30
-7
@@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -98,6 +99,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.
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -293,6 +312,12 @@ zio_handle_device_injection(vdev_t *vd, zio_t *zio, int error)
|
||||
continue;
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user