Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/geom/class/mirror/component_selection.sh
39635 views
1
2
ATF_TEST=true
3
class=mirror
4
. $(atf_get_srcdir)/conf.sh
5
6
atf_test_case run_latest_genid cleanup
7
run_latest_genid_head()
8
{
9
atf_set "descr" \
10
"Ensure that we properly select components (latest genid) during STARTING."
11
atf_set "require.user" "root"
12
}
13
run_latest_genid_body()
14
{
15
geom_atf_test_setup
16
if ! error_message=$(geom_load_class_if_needed nop); then
17
atf_skip "$error_message"
18
fi
19
20
f1=$(mktemp ${base}.XXXXXX)
21
f2=$(mktemp ${base}.XXXXXX)
22
f3=$(mktemp ${base}.XXXXXX)
23
rnd1=$(mktemp ${base}.XXXXXX)
24
rnd2=$(mktemp ${base}.XXXXXX)
25
26
atf_check truncate -s 2M $f1
27
atf_check truncate -s 2M $f2
28
atf_check truncate -s 2M $f3
29
dd if=/dev/urandom bs=512 count=1 of="$rnd1"
30
dd if=/dev/urandom bs=512 count=1 of="$rnd2"
31
32
attach_md md1 -t vnode -f ${f1}
33
attach_md md2 -t vnode -f ${f2}
34
attach_md md3 -t vnode -f ${f3}
35
36
# Use a gnop for md1 just for consistency; it's not used for anything.
37
atf_check gnop create $md1
38
atf_check gnop create $md2
39
atf_check gnop create $md3
40
# Hardcode component names so that the non-.nop device isn't tasted
41
# instead.
42
atf_check gmirror label -h $name ${md1}.nop
43
devwait
44
45
atf_check gmirror insert -h $name ${md2}.nop
46
atf_check gmirror insert -h $name ${md3}.nop
47
syncwait
48
49
# Fail mirror 3, writing known contents to mirror 1+2 block 1
50
atf_check -s exit:0 -e empty -o empty \
51
gnop configure -w 100 ${md3}.nop
52
atf_check -s exit:0 dd if="$rnd1" bs=512 count=1 oseek=1 conv=notrunc \
53
of=/dev/mirror/$name status=none
54
55
disconnectwait nop "${md3}.nop"
56
57
# Should have two mirrors remaining after md3 was evicted
58
atf_check [ $(gmirror status -s $name | wc -l) -eq 2 ]
59
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
60
gmirror status -s $name
61
atf_check -s exit:0 -o match:"DEGRADED ${md2}.nop \(ACTIVE\)" \
62
gmirror status -s $name
63
64
# Repeat:
65
# Fail mirror 2, writing known contents to mirror 1 block 2
66
atf_check -s exit:0 -e empty -o empty \
67
gnop configure -w 100 ${md2}.nop
68
atf_check -s exit:0 dd if="$rnd2" bs=512 count=2 oseek=1 conv=notrunc \
69
of=/dev/mirror/$name status=none
70
71
disconnectwait nop "${md2}.nop"
72
73
# Should have one mirror remaining after md2 was evicted
74
atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
75
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
76
gmirror status -s $name
77
78
# Stop the mirror and remove the pieces so gmirror can't see them.
79
atf_check gmirror stop $name
80
atf_check gnop destroy ${md1}.nop
81
atf_check gnop destroy ${md2}.nop
82
atf_check gnop destroy ${md3}.nop
83
84
# Rebuild; spin up "disk" with lowest genid
85
atf_check gnop create $md3
86
md3gen=$(gmirror dump /dev/${md3}.nop | grep genid | cut -d: -f2)
87
# Assert gmirror is referencing this component for now:
88
atf_check [ $(consumerrefs nop ${md3}.nop) = "r1w1e1" ]
89
90
# Adding newer genid should kick out old component
91
atf_check gnop create $md2
92
md2gen=$(gmirror dump /dev/${md2}.nop | grep genid | cut -d: -f2)
93
atf_check [ $md2gen -gt $md3gen ]
94
95
disconnectwait nop "${md3}.nop"
96
97
# Can't test this because 'status' doesn't exist until RUNNING:
98
#atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
99
# But as a substitute, assert gmirror has dropped reference to staler
100
# component in favor of newer component:
101
atf_check [ $(consumerrefs nop ${md2}.nop) = "r1w1e1" ]
102
103
# ditto
104
atf_check gnop create $md1
105
md1gen=$(gmirror dump /dev/${md1}.nop | grep genid | cut -d: -f2)
106
atf_check [ $md1gen -gt $md2gen ]
107
108
disconnectwait nop "${md2}.nop"
109
110
# Assert gmirror has dropped reference to stale component in favor of
111
# newer component:
112
atf_check [ $(consumerrefs nop ${md1}.nop) = "r1w1e1" ]
113
114
# gmirror won't start the mirror automatically with only one component
115
# ($md0) of configured three, so this waits out the
116
# kern.geom.mirror.timeout:
117
devwait
118
119
atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
120
atf_check -s exit:0 -o match:"DEGRADED ${md1}.nop \(ACTIVE\)" \
121
gmirror status -s $name
122
}
123
run_latest_genid_cleanup()
124
{
125
. $(atf_get_srcdir)/conf.sh
126
127
if [ -f "$TEST_MDS_FILE" ]; then
128
while read test_md; do
129
echo "# Removing test gnop: ${test_md}.nop"
130
gnop destroy -f "${test_md}.nop" 2>/dev/null || :
131
done < "$TEST_MDS_FILE"
132
fi
133
gmirror_test_cleanup
134
}
135
136
atf_init_test_cases()
137
{
138
atf_add_test_case run_latest_genid
139
}
140
141