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