mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
zinject: "no-op" error injection
When injected, this causes the matching IO to appear to succeed, but the actual work is never submitted to the physical device. This can be used to simulate a write-back cache servicing a write, but the backing device has failed and the cache cannot complete the operation in the background. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #16085
This commit is contained in:
parent
f22b110f60
commit
4725e543be
@ -221,6 +221,7 @@ static const struct errstr errstrtable[] = {
|
|||||||
{ ENXIO, "nxio" },
|
{ ENXIO, "nxio" },
|
||||||
{ ECHILD, "dtl" },
|
{ ECHILD, "dtl" },
|
||||||
{ EILSEQ, "corrupt" },
|
{ EILSEQ, "corrupt" },
|
||||||
|
{ ENOSYS, "noop" },
|
||||||
{ 0, NULL },
|
{ 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -269,8 +270,8 @@ usage(void)
|
|||||||
"\t\tInject a fault into a particular device or the device's\n"
|
"\t\tInject a fault into a particular device or the device's\n"
|
||||||
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
"\t\tlabel. Label injection can either be 'nvlist', 'uber',\n "
|
||||||
"\t\t'pad1', or 'pad2'.\n"
|
"\t\t'pad1', or 'pad2'.\n"
|
||||||
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl', or\n"
|
"\t\t'errno' can be 'nxio' (the default), 'io', 'dtl',\n"
|
||||||
"\t\t'corrupt' (bit flip).\n"
|
"\t\t'corrupt' (bit flip), or 'noop' (successfully do nothing).\n"
|
||||||
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
|
"\t\t'frequency' is a value between 0.0001 and 100.0 that limits\n"
|
||||||
"\t\tdevice error injection to a percentage of the IOs.\n"
|
"\t\tdevice error injection to a percentage of the IOs.\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -889,7 +890,7 @@ main(int argc, char **argv)
|
|||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
(void) fprintf(stderr, "invalid error type "
|
(void) fprintf(stderr, "invalid error type "
|
||||||
"'%s': must be one of: io decompress "
|
"'%s': must be one of: io decompress "
|
||||||
"decrypt nxio dtl corrupt\n",
|
"decrypt nxio dtl corrupt noop\n",
|
||||||
optarg);
|
optarg);
|
||||||
usage();
|
usage();
|
||||||
libzfs_fini(g_zfs);
|
libzfs_fini(g_zfs);
|
||||||
|
@ -211,9 +211,11 @@ to flip a bit in the data after a read,
|
|||||||
.It Sy dtl
|
.It Sy dtl
|
||||||
for an ECHILD error,
|
for an ECHILD error,
|
||||||
.It Sy io
|
.It Sy io
|
||||||
for an EIO error where reopening the device will succeed, or
|
for an EIO error where reopening the device will succeed,
|
||||||
.It Sy nxio
|
.It Sy nxio
|
||||||
for an ENXIO error where reopening the device will fail.
|
for an ENXIO error where reopening the device will fail, or
|
||||||
|
.It Sy noop
|
||||||
|
to drop the IO without executing it, and return success.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
For EIO and ENXIO, the "failed" reads or writes still occur.
|
For EIO and ENXIO, the "failed" reads or writes still occur.
|
||||||
|
@ -4058,6 +4058,16 @@ zio_vdev_io_start(zio_t *zio)
|
|||||||
zio->io_type == ZIO_TYPE_WRITE ||
|
zio->io_type == ZIO_TYPE_WRITE ||
|
||||||
zio->io_type == ZIO_TYPE_TRIM)) {
|
zio->io_type == ZIO_TYPE_TRIM)) {
|
||||||
|
|
||||||
|
if (zio_handle_device_injection(vd, zio, ENOSYS) != 0) {
|
||||||
|
/*
|
||||||
|
* "no-op" injections return success, but do no actual
|
||||||
|
* work. Just skip the remaining vdev stages.
|
||||||
|
*/
|
||||||
|
zio_vdev_io_bypass(zio);
|
||||||
|
zio_interrupt(zio);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if ((zio = vdev_queue_io(zio)) == NULL)
|
if ((zio = vdev_queue_io(zio)) == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ function cleanup
|
|||||||
|
|
||||||
function test_device_fault
|
function test_device_fault
|
||||||
{
|
{
|
||||||
typeset -a errno=("io" "decompress" "decrypt" "nxio" "dtl" "corrupt")
|
typeset -a errno=("io" "decompress" "decrypt" "nxio" "dtl" "corrupt" "noop")
|
||||||
for e in ${errno[@]}; do
|
for e in ${errno[@]}; do
|
||||||
log_must eval \
|
log_must eval \
|
||||||
"zinject -d $DISK1 -e $e -T read -f 0.001 $TESTPOOL"
|
"zinject -d $DISK1 -e $e -T read -f 0.001 $TESTPOOL"
|
||||||
|
Loading…
Reference in New Issue
Block a user