xref: /freebsd/tests/sys/geom/class/mirror/sync_error.sh (revision d3d381b2b194b4d24853e92eecef55f262688d1a)
1# $FreeBSD$
2
3REG_READ_FP=debug.fail_point.g_mirror_regular_request_read
4
5atf_test_case sync_read_error_2_disks cleanup
6sync_read_error_2_disks_head()
7{
8	atf_set "descr" \
9		"Ensure that we properly handle read errors during synchronization."
10	atf_set "require.user" "root"
11}
12sync_read_error_2_disks_body()
13{
14	. $(atf_get_srcdir)/conf.sh
15
16	f1=$(mktemp ${base}.XXXXXX)
17	f2=$(mktemp ${base}.XXXXXX)
18
19	atf_check dd if=/dev/zero bs=1M count=32 of=$f1 status=none
20	atf_check truncate -s 32M $f2
21
22	md1=$(attach_md -t vnode -f ${f1})
23	md2=$(attach_md -t vnode -f ${f2})
24
25	atf_check gmirror label $name $md1
26	devwait
27
28	atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='1*return(5)'
29
30	# If a read error occurs while synchronizing and the mirror contains
31	# a single active disk, gmirror has no choice but to fail the
32	# synchronization and kick the new disk out of the mirror.
33	atf_check gmirror insert $name $md2
34	sleep 0.1
35	syncwait
36	atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
37	atf_check -s exit:0 -o match:"DEGRADED  $md1 \(ACTIVE\)" \
38		gmirror status -s $name
39}
40sync_read_error_2_disks_cleanup()
41{
42	. $(atf_get_srcdir)/conf.sh
43
44	atf_check -s exit:0 -e empty -o not-empty 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	. $(atf_get_srcdir)/conf.sh
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	md1=$(attach_md -t vnode -f ${f1})
68	md2=$(attach_md -t vnode -f ${f2})
69	md3=$(attach_md -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)'
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_get_srcdir)/conf.sh
101
102	atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='off'
103	gmirror_test_cleanup
104}
105
106atf_init_test_cases()
107{
108	atf_add_test_case sync_read_error_2_disks
109	atf_add_test_case sync_read_error_3_disks
110}
111