Skip to content

Commit ad8aa42

Browse files
committed
zinject: add "probe" device injection type
Injecting a device probe failure is not possible by matching IO types, because probe IO goes to the label regions, which is explicitly excluded from injection. Even if it were possible, it would be awkward to do, because a probe is sequence of reads and writes. This commit adds a new IO "type" to match for injection, which looks for the ZIO_FLAG_PROBE flag instead. Any probe IO will be match the injection record and recieve the wanted error. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Rob Norris <[email protected]>
1 parent 05f7664 commit ad8aa42

File tree

7 files changed

+88
-15
lines changed

7 files changed

+88
-15
lines changed

cmd/zinject/zinject.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ static const char *const iotypestrtable[ZINJECT_IOTYPES] = {
251251
[ZINJECT_IOTYPE_FLUSH] = "flush",
252252
[ZINJECT_IOTYPE_TRIM] = "trim",
253253
[ZINJECT_IOTYPE_ALL] = "all",
254+
[ZINJECT_IOTYPE_PROBE] = "probe",
254255
};
255256

256257
static zinject_iotype_t

include/sys/zfs_ioctl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,8 @@ typedef enum zinject_iotype {
471471
ZINJECT_IOTYPE_TRIM = ZIO_TYPE_TRIM,
472472
ZINJECT_IOTYPE_ALL = ZIO_TYPES,
473473
/* Room for future expansion for ZIO_TYPE_* */
474-
ZINJECT_IOTYPES = 16,
474+
ZINJECT_IOTYPE_PROBE = 16,
475+
ZINJECT_IOTYPES,
475476
} zinject_iotype_t;
476477

477478
typedef struct zfs_share {

man/man8/zinject.8

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@
1919
.\" CDDL HEADER END
2020
.\"
2121
.\" Copyright 2013 Darik Horn <[email protected]>. All rights reserved.
22-
.\" Copyright (c) 2024, Klara Inc.
22+
.\" Copyright (c) 2024, 2025, Klara, Inc.
2323
.\"
2424
.\" lint-ok: WARNING: sections out of conventional order: Sh SYNOPSIS
2525
.\"
26-
.Dd December 2, 2024
26+
.Dd January 14, 2025
2727
.Dt ZINJECT 8
2828
.Os
2929
.
@@ -265,15 +265,16 @@ will be translated to the appropriate blkid range according to the
265265
object's properties.
266266
.It Fl s Ar seconds
267267
Run for this many seconds before reporting failure.
268-
.It Fl T Ar failure
269-
Set the failure type to one of
270-
.Sy all ,
271-
.Sy flush ,
272-
.Sy claim ,
273-
.Sy free ,
274-
.Sy read ,
275-
or
276-
.Sy write .
268+
.It Fl T Ar type
269+
Inject the error into I/O of this type.
270+
.Bl -tag -compact -width "read, write, flush, claim, free"
271+
.It Sy read , Sy write , Sy flush , Sy claim , Sy free
272+
Fundamental I/O types
273+
.It Sy all
274+
All fundamental I/O types
275+
.It Sy probe
276+
Device probe I/O
277+
.El
277278
.It Fl t Ar mos_type
278279
Set this to
279280
.Bl -tag -compact -width "spacemap"

module/zfs/zio_inject.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@ zio_match_iotype(zio_t *zio, uint32_t iotype)
386386
if (iotype >= ZINJECT_IOTYPES)
387387
return (B_FALSE);
388388

389+
/* Probe IOs only match IOTYPE_PROBE, regardless of their type. */
390+
if (zio->io_flags & ZIO_FLAG_PROBE)
391+
return (iotype == ZINJECT_IOTYPE_PROBE);
392+
389393
/* Standard IO types, match against ZIO type. */
390394
if (iotype < ZINJECT_IOTYPE_ALL)
391395
return (iotype == zio->io_type);
@@ -405,9 +409,11 @@ zio_handle_device_injection_impl(vdev_t *vd, zio_t *zio, int err1, int err2)
405409

406410
/*
407411
* We skip over faults in the labels unless it's during device open
408-
* (i.e. zio == NULL) or a device flush (offset is meaningless)
412+
* (i.e. zio == NULL) or a device flush (offset is meaningless). We let
413+
* probe IOs through so we can match them to probe inject records.
409414
*/
410-
if (zio != NULL && zio->io_type != ZIO_TYPE_FLUSH) {
415+
if (zio != NULL && zio->io_type != ZIO_TYPE_FLUSH &&
416+
!(zio->io_flags & ZIO_FLAG_PROBE)) {
411417
uint64_t offset = zio->io_offset;
412418

413419
if (offset < VDEV_LABEL_START_SIZE ||

tests/runfiles/common.run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ tests = ['json_sanity']
159159
tags = ['functional', 'cli_root', 'json']
160160

161161
[tests/functional/cli_root/zinject]
162-
tests = ['zinject_args', 'zinject_counts']
162+
tests = ['zinject_args', 'zinject_counts', 'zinject_probe']
163163
pre =
164164
post =
165165
tags = ['functional', 'cli_root', 'zinject']

tests/zfs-tests/tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
616616
functional/cli_root/json/json_sanity.ksh \
617617
functional/cli_root/zinject/zinject_args.ksh \
618618
functional/cli_root/zinject/zinject_counts.ksh \
619+
functional/cli_root/zinject/zinject_probe.ksh \
619620
functional/cli_root/zdb/zdb_002_pos.ksh \
620621
functional/cli_root/zdb/zdb_003_pos.ksh \
621622
functional/cli_root/zdb/zdb_004_pos.ksh \
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/bin/ksh -p
2+
#
3+
# CDDL HEADER START
4+
#
5+
# The contents of this file are subject to the terms of the
6+
# Common Development and Distribution License (the "License").
7+
# You may not use this file except in compliance with the License.
8+
#
9+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10+
# or https://opensource.org/licenses/CDDL-1.0.
11+
# See the License for the specific language governing permissions
12+
# and limitations under the License.
13+
#
14+
# When distributing Covered Code, include this CDDL HEADER in each
15+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16+
# If applicable, add the following below this CDDL HEADER, with the
17+
# fields enclosed by brackets "[]" replaced with your own identifying
18+
# information: Portions Copyright [yyyy] [name of copyright owner]
19+
#
20+
# CDDL HEADER END
21+
#
22+
23+
#
24+
# Copyright (c) 2025, Klara, Inc.
25+
#
26+
27+
. $STF_SUITE/include/libtest.shlib
28+
29+
verify_runnable "global"
30+
31+
log_assert "Check zinject can correctly inject a probe failure."
32+
33+
DISK1=${DISKS%% *}
34+
35+
function cleanup
36+
{
37+
zinject -c all
38+
default_cleanup_noexit
39+
}
40+
41+
log_onexit cleanup
42+
43+
zpool create $TESTPOOL $DISK1
44+
45+
log_must zinject -d $DISK1 -e io -T probe $TESTPOOL
46+
log_must zinject -d $DISK1 -e io -T write $TESTPOOL
47+
48+
log_must dd if=/dev/urandom of=/$TESTPOOL/file bs=1M count=1
49+
50+
log_note "waiting for pool to suspend"
51+
typeset -i tries=10
52+
until [[ $(kstat state $TESTPOOL) == "SUSPENDED" ]] ; do
53+
if ((tries-- == 0)); then
54+
log_fail "pool didn't suspend"
55+
fi
56+
sleep 1
57+
done
58+
59+
log_must zinject -c all
60+
log_must zpool clear $TESTPOOL
61+
log_must zpool destroy -f $TESTPOOL
62+
63+
log_pass "zinject can correctly inject a probe failure."

0 commit comments

Comments
 (0)