1a19e7429SMark Johnston
2cf551b8aSAlan SomersATF_TEST=true
3cf551b8aSAlan Somers. $(atf_get_srcdir)/conf.sh
4cf551b8aSAlan Somers
5a19e7429SMark JohnstonREG_READ_FP=debug.fail_point.g_mirror_regular_request_read
6a19e7429SMark Johnston
7a19e7429SMark Johnstonatf_test_case sync_read_error_2_disks cleanup
8a19e7429SMark Johnstonsync_read_error_2_disks_head()
9a19e7429SMark Johnston{
10a19e7429SMark Johnston	atf_set "descr" \
11a19e7429SMark Johnston		"Ensure that we properly handle read errors during synchronization."
12a19e7429SMark Johnston	atf_set "require.user" "root"
13a19e7429SMark Johnston}
14a19e7429SMark Johnstonsync_read_error_2_disks_body()
15a19e7429SMark Johnston{
16cf551b8aSAlan Somers	geom_atf_test_setup
17a19e7429SMark Johnston
18a19e7429SMark Johnston	f1=$(mktemp ${base}.XXXXXX)
19a19e7429SMark Johnston	f2=$(mktemp ${base}.XXXXXX)
20a19e7429SMark Johnston
21a19e7429SMark Johnston	atf_check dd if=/dev/zero bs=1M count=32 of=$f1 status=none
22a19e7429SMark Johnston	atf_check truncate -s 32M $f2
23a19e7429SMark Johnston
2496950419SGleb Smirnoff	attach_md md1 -t vnode -f ${f1}
2596950419SGleb Smirnoff	attach_md md2 -t vnode -f ${f2}
26a19e7429SMark Johnston
27a19e7429SMark Johnston	atf_check gmirror label $name $md1
28a19e7429SMark Johnston	devwait
29a19e7429SMark Johnston
303cee7cb2SBryan Drewery	atf_check -s ignore -e empty -o not-empty sysctl ${REG_READ_FP}="1*return(5)[pid $(gmirror_worker_pid)]"
31a19e7429SMark Johnston
32a19e7429SMark Johnston	# If a read error occurs while synchronizing and the mirror contains
33a19e7429SMark Johnston	# a single active disk, gmirror has no choice but to fail the
34a19e7429SMark Johnston	# synchronization and kick the new disk out of the mirror.
35a19e7429SMark Johnston	atf_check gmirror insert $name $md2
36a19e7429SMark Johnston	sleep 0.1
37a19e7429SMark Johnston	syncwait
38a19e7429SMark Johnston	atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
39a19e7429SMark Johnston	atf_check -s exit:0 -o match:"DEGRADED  $md1 \(ACTIVE\)" \
40a19e7429SMark Johnston		gmirror status -s $name
41a19e7429SMark Johnston}
42a19e7429SMark Johnstonsync_read_error_2_disks_cleanup()
43a19e7429SMark Johnston{
44cf551b8aSAlan Somers	atf_check -s ignore -e ignore -o ignore sysctl ${REG_READ_FP}='off'
45a19e7429SMark Johnston	gmirror_test_cleanup
46a19e7429SMark Johnston}
47a19e7429SMark Johnston
48a19e7429SMark Johnstonatf_test_case sync_read_error_3_disks cleanup
49a19e7429SMark Johnstonsync_read_error_3_disks_head()
50a19e7429SMark Johnston{
51a19e7429SMark Johnston	atf_set "descr" \
52a19e7429SMark Johnston		"Ensure that we properly handle read errors during synchronization."
53a19e7429SMark Johnston	atf_set "require.user" "root"
54a19e7429SMark Johnston}
55a19e7429SMark Johnstonsync_read_error_3_disks_body()
56a19e7429SMark Johnston{
57cf551b8aSAlan Somers	geom_atf_test_setup
58a19e7429SMark Johnston
59a19e7429SMark Johnston	f1=$(mktemp ${base}.XXXXXX)
60a19e7429SMark Johnston	f2=$(mktemp ${base}.XXXXXX)
61a19e7429SMark Johnston	f3=$(mktemp ${base}.XXXXXX)
62a19e7429SMark Johnston
63a19e7429SMark Johnston	atf_check dd if=/dev/random bs=1M count=32 of=$f1 status=none
64a19e7429SMark Johnston	atf_check truncate -s 32M $f2
65a19e7429SMark Johnston	atf_check truncate -s 32M $f3
66a19e7429SMark Johnston
6796950419SGleb Smirnoff	attach_md md1 -t vnode -f ${f1}
6896950419SGleb Smirnoff	attach_md md2 -t vnode -f ${f2}
6996950419SGleb Smirnoff	attach_md md3 -t vnode -f ${f3}
70a19e7429SMark Johnston
71a19e7429SMark Johnston	atf_check gmirror label $name $md1
72a19e7429SMark Johnston	devwait
73a19e7429SMark Johnston
74a19e7429SMark Johnston	atf_check gmirror insert $name $md2
75a19e7429SMark Johnston	syncwait
76a19e7429SMark Johnston
773cee7cb2SBryan Drewery	atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}="1*return(5)[pid $(gmirror_worker_pid)]"
78a19e7429SMark Johnston
79a19e7429SMark Johnston	# If a read error occurs while synchronizing a new disk, and we have
80a19e7429SMark Johnston	# multiple active disks, we retry the read after an error. The disk
81a19e7429SMark Johnston	# which returned the read error is kicked out of the mirror.
82a19e7429SMark Johnston	atf_check gmirror insert $name $md3
83a19e7429SMark Johnston	syncwait
84a19e7429SMark Johnston	atf_check [ $(gmirror status -s $name | wc -l) -eq 2 ]
85a19e7429SMark Johnston	atf_check -s exit:0 -o match:"DEGRADED  $md3 \(ACTIVE\)" \
86a19e7429SMark Johnston		gmirror status -s $name
87a19e7429SMark Johnston
88a19e7429SMark Johnston	# Make sure that the two active disks are identical. Destroy the
89a19e7429SMark Johnston	# mirror first so that the metadata sectors are wiped.
90a19e7429SMark Johnston	if $(gmirror status -s $name | grep -q $md1); then
91a19e7429SMark Johnston		active=$md1
92a19e7429SMark Johnston	else
93a19e7429SMark Johnston		active=$md2
94a19e7429SMark Johnston	fi
95a19e7429SMark Johnston	atf_check gmirror destroy $name
96a19e7429SMark Johnston	atf_check cmp /dev/$active /dev/$md3
97a19e7429SMark Johnston}
98a19e7429SMark Johnstonsync_read_error_3_disks_cleanup()
99a19e7429SMark Johnston{
100cf551b8aSAlan Somers	atf_check -s ignore -e ignore -o ignore sysctl ${REG_READ_FP}='off'
101a19e7429SMark Johnston	gmirror_test_cleanup
102a19e7429SMark Johnston}
103a19e7429SMark Johnston
104a19e7429SMark Johnstonatf_init_test_cases()
105a19e7429SMark Johnston{
106a19e7429SMark Johnston	atf_add_test_case sync_read_error_2_disks
107a19e7429SMark Johnston	atf_add_test_case sync_read_error_3_disks
108a19e7429SMark Johnston}
109