blob: 7bb24b9efc64ededdf15e816d8549ef7e5eed576 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2026 voidanix <voidanix@FreeBSD.org>
#
MD_DEV_FILE="md.dev"
alloc_zoned_md()
{
atf_check truncate -s 1025m backing_file
md=$(mdconfig -a -t vnode -f backing_file) || \
atf_fail "mdconfig -a failed"
echo ${md} > $MD_DEV_FILE
}
# Print the number of zones matching a report option.
zone_count()
{
zonectl -d /dev/${md}.zoned -c rz -o $1 -P summary | \
awk '/zones,/ {print $1}'
}
zoned_md_cleanup()
{
if [ -f "$MD_DEV_FILE" ]; then
read md < $MD_DEV_FILE
[ -c /dev/${md}.zoned ] && \
gzoned destroy ${md}.zoned 2>/dev/null
mdconfig -d -u ${md} 2>/dev/null
fi
true
}
atf_test_case report_filter cleanup
report_filter_head()
{
atf_set "descr" "zonectl -o only reports zones matching the filter"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
report_filter_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m -c 0-1 ${md}
atf_check_equal "2" \
"$(zonectl -d /dev/${md}.zoned -c rz -o nonwp -P summary | \
awk '/zones,/ {print $1}')"
atf_check_equal "2" \
"$(zonectl -d /dev/${md}.zoned -c rz -o empty -P summary | \
awk '/zones,/ {print $1}')"
atf_check_equal "0" \
"$(zonectl -d /dev/${md}.zoned -c rz -o full -P summary | \
awk '/zones,/ {print $1}')"
}
report_filter_cleanup()
{
zoned_md_cleanup
}
atf_test_case report_zones cleanup
report_zones_head()
{
atf_set "descr" "zonectl -c rz reports every zone"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
report_zones_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m ${md}
atf_check -o match:"^4 zones," \
zonectl -d /dev/${md}.zoned -c rz -P summary
atf_check_equal "4" \
"$(zonectl -d /dev/${md}.zoned -c rz -P script | \
awk 'END {print NR}')"
}
report_zones_cleanup()
{
zoned_md_cleanup
}
atf_test_case report_starting_lba cleanup
report_starting_lba_head()
{
atf_set "descr" "zonectl -c rz -l reports zones from a starting LBA"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
report_starting_lba_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m ${md}
# Only zones 2 and 3 lie at or past LBA 0x100000 (512m).
atf_check_equal "2" \
"$(zonectl -d /dev/${md}.zoned -c rz -l 0x100000 -P summary | \
awk '/zones,/ {print $1}')"
atf_check_equal "0x100000" \
"$(zonectl -d /dev/${md}.zoned -c rz -l 0x100000 -P script | \
awk -F',' 'NR == 1 {gsub(/ /, "", $1); print $1}')"
}
report_starting_lba_cleanup()
{
zoned_md_cleanup
}
atf_test_case report_params cleanup
report_params_head()
{
atf_set "descr" "zonectl -c params reports the device parameters"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
report_params_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m -m 3 ${md}
atf_check -o match:"Zone Mode: Host Managed" \
-o match:"URSWRZ.*: Yes" \
-o match:"Open Sequential Write Required Zones: 3" \
zonectl -d /dev/${md}.zoned -c params
}
report_params_cleanup()
{
zoned_md_cleanup
}
atf_test_case open_zone cleanup
open_zone_head()
{
atf_set "descr" "zonectl -c open explicitly opens a zone"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
open_zone_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m ${md}
atf_check zonectl -d /dev/${md}.zoned -c open -l 0
atf_check_equal "1" "$(zone_count exp_open)"
}
open_zone_cleanup()
{
zoned_md_cleanup
}
atf_test_case close_zone cleanup
close_zone_head()
{
atf_set "descr" "zonectl -c close closes an open zone"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
close_zone_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m ${md}
atf_check -e ignore dd if=/dev/zero of=/dev/${md}.zoned bs=1m count=1
atf_check_equal "1" "$(zone_count imp_open)"
atf_check zonectl -d /dev/${md}.zoned -c close -l 0
atf_check_equal "1" "$(zone_count closed)"
atf_check_equal "0" "$(zone_count imp_open)"
}
close_zone_cleanup()
{
zoned_md_cleanup
}
atf_test_case finish_zone cleanup
finish_zone_head()
{
atf_set "descr" "zonectl -c finish transitions a zone to full"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
finish_zone_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m ${md}
atf_check -e ignore dd if=/dev/zero of=/dev/${md}.zoned bs=1m count=1
atf_check zonectl -d /dev/${md}.zoned -c finish -l 0
atf_check_equal "1" "$(zone_count full)"
}
finish_zone_cleanup()
{
zoned_md_cleanup
}
atf_test_case zone_state_handling cleanup
zone_state_handling_head()
{
atf_set "descr" \
"zone commands follow ZBC spec outside their transition states"
atf_set "require.user" "root"
atf_set "require.kmods" "g_md g_zoned"
}
zone_state_handling_body()
{
alloc_zoned_md
atf_check gzoned create -s 256m -c 0 ${md}
# Explicitly targeting a conventional zone is the caller's error.
atf_check -s not-exit:0 -e ignore \
zonectl -d /dev/${md}.zoned -c finish -l 0
# Closing an empty zone is a no-op.
atf_check zonectl -d /dev/${md}.zoned -c close -l 0x80000
atf_check_equal "3" "$(zone_count empty)"
# So is opening a full zone: it must stay full.
atf_check zonectl -d /dev/${md}.zoned -c finish -l 0x100000
atf_check zonectl -d /dev/${md}.zoned -c open -l 0x100000
atf_check_equal "1" "$(zone_count full)"
atf_check_equal "0" "$(zone_count exp_open)"
}
zone_state_handling_cleanup()
{
zoned_md_cleanup
}
atf_init_test_cases()
{
atf_add_test_case report_filter
atf_add_test_case report_zones
atf_add_test_case report_starting_lba
atf_add_test_case report_params
atf_add_test_case open_zone
atf_add_test_case close_zone
atf_add_test_case finish_zone
atf_add_test_case zone_state_handling
}
|