Skip to content

Commit 2df54b1

Browse files
robnbehlendorf
authored andcommitted
zts: test syncfs() behaviour when pool suspends
Fairly coarse, but if it returns while the pool suspends, it must be with an error. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Paul Dagnelie <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Rob Norris <[email protected]> Closes #17420
1 parent a6d6c21 commit 2df54b1

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

tests/runfiles/linux.run

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ tags = ['functional', 'simd']
210210
tests = ['snapshot_015_pos', 'snapshot_016_pos']
211211
tags = ['functional', 'snapshot']
212212

213+
[tests/functional/syncfs:Linux]
214+
tests = ['syncfs_suspend']
215+
tags = ['functional', 'syncfs']
216+
213217
[tests/functional/tmpfile:Linux]
214218
tests = ['tmpfile_001_pos', 'tmpfile_002_pos', 'tmpfile_003_pos',
215219
'tmpfile_stat_mode']

tests/zfs-tests/tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,6 +2064,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \
20642064
functional/stat/setup.ksh \
20652065
functional/stat/stat_001_pos.ksh \
20662066
functional/stat/statx_dioalign.ksh \
2067+
functional/syncfs/syncfs_suspend.ksh \
20672068
functional/suid/cleanup.ksh \
20682069
functional/suid/setup.ksh \
20692070
functional/suid/suid_write_to_none.ksh \
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/bin/ksh -p
2+
# SPDX-License-Identifier: CDDL-1.0
3+
#
4+
# CDDL HEADER START
5+
#
6+
# The contents of this file are subject to the terms of the
7+
# Common Development and Distribution License (the "License").
8+
# You may not use this file except in compliance with the License.
9+
#
10+
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11+
# or https://opensource.org/licenses/CDDL-1.0.
12+
# See the License for the specific language governing permissions
13+
# and limitations under the License.
14+
#
15+
# When distributing Covered Code, include this CDDL HEADER in each
16+
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17+
# If applicable, add the following below this CDDL HEADER, with the
18+
# fields enclosed by brackets "[]" replaced with your own identifying
19+
# information: Portions Copyright [yyyy] [name of copyright owner]
20+
#
21+
# CDDL HEADER END
22+
#
23+
24+
#
25+
# Copyright (c) 2025, Klara, Inc.
26+
#
27+
28+
. $STF_SUITE/include/libtest.shlib
29+
30+
log_assert "syncfs() does not return success while the pool is suspended"
31+
32+
typeset -i syncfs_pid=0
33+
34+
function cleanup
35+
{
36+
zinject -c all || true
37+
zpool clear $TESTPOOL || true
38+
test $syncfs_pid -gt 0 && kill -9 $syncfs_pid || true
39+
destroy_pool $TESTPOOL
40+
}
41+
42+
log_onexit cleanup
43+
44+
DISK=${DISKS%% *}
45+
46+
# create a single-disk pool, set failmode=wait
47+
log_must zpool create -o failmode=wait -f $TESTPOOL $DISK
48+
log_must zfs create -o recordsize=128k $TESTPOOL/$TESTFS
49+
50+
# generate a write, then syncfs(), confirm success
51+
log_must touch /$TESTPOOL/$TESTFS/file1
52+
log_must sync -f /$TESTPOOL/$TESTFS
53+
54+
# and again with no changes
55+
log_must sync -f /$TESTPOOL/$TESTFS
56+
57+
# set up error injections to force the pool to suspend on next write
58+
log_must zinject -d $DISK -e io -T write $TESTPOOL
59+
log_must zinject -d $DISK -e nxio -T probe $TESTPOOL
60+
61+
# generate another write
62+
log_must touch /$TESTPOOL/$TESTFS/file2
63+
64+
# wait for the pool to suspend
65+
log_note "waiting for pool to suspend"
66+
typeset -i tries=10
67+
until [[ $(kstat_pool $TESTPOOL state) == "SUSPENDED" ]] ; do
68+
if ((tries-- == 0)); then
69+
log_fail "pool didn't suspend"
70+
fi
71+
sleep 1
72+
done
73+
74+
# pool suspended. syncfs() in the background, as it may block
75+
sync -f /$TESTPOOL/$TESTFS &
76+
syncfs_pid=$!
77+
78+
# give it a moment to get stuck
79+
sleep 1
80+
81+
# depending on kernel version and pool config, syncfs should have either
82+
# returned an error, or be blocked in the kernel
83+
typeset -i blocked
84+
typeset -i rc
85+
if kill -0 $syncfs_pid ; then
86+
blocked=1
87+
log_note "syncfs() is blocked in the kernel"
88+
else
89+
blocked=0
90+
log_note "syncfs() returned while pool was suspended"
91+
92+
# exited, capture its error code directly
93+
wait $syncfs_pid
94+
rc=$?
95+
syncfs_pid=0
96+
fi
97+
98+
# bring the pool back online
99+
log_must zinject -c all
100+
log_must zpool clear $TESTPOOL
101+
102+
if [[ $syncfs_pid -gt 0 ]] ; then
103+
# it blocked, clean it up now
104+
wait $syncfs_pid
105+
rc=$?
106+
syncfs_pid=0
107+
fi
108+
109+
# if it returned when the pool was suspended, it must not claim success. if
110+
# it blocked and returned after the pool suspended, then we don't care about
111+
# the error (it depends on what happened after the pool resumed, which we're
112+
# not testing here)
113+
log_must test $blocked -eq 1 -o $rc -ne 0
114+
115+
log_pass "syncfs() does not return success while the pool is suspended"

0 commit comments

Comments
 (0)