1# Copyright (c) 2012 Edward Tomasz Napierała <trasz@FreeBSD.org>
2#
3# Redistribution and use in source and binary forms, with or without
4# modification, are permitted provided that the following conditions
5# are met:
6# 1. Redistributions of source code must retain the above copyright
7#    notice, this list of conditions and the following disclaimer.
8# 2. Redistributions in binary form must reproduce the above copyright
9#    notice, this list of conditions and the following disclaimer in the
10#    documentation and/or other materials provided with the distribution.
11#
12# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22# SUCH DAMAGE.
23#
24#
25
26check_diskinfo()
27{
28	local md=$1
29	local mediasize_in_bytes=$2
30	local mediasize_in_sectors=$3
31	local sectorsize=${4:-512}
32	local stripesize=${5:-0}
33	local stripeoffset=${6:-0}
34
35	atf_check -s exit:0 \
36	    -o match:"/dev/$md *$sectorsize *$mediasize_in_bytes *$mediasize_in_sectors *$stripesize *$stripeoffset" \
37	    -x "diskinfo /dev/$md | expand"
38}
39
40cleanup_common()
41{
42	if [ -f mdconfig.out ]; then
43		mdconfig -d -u $(sed -e 's/md//' mdconfig.out)
44	fi
45}
46
47atf_test_case attach_vnode_non_explicit_type cleanup
48attach_vnode_non_explicit_type_head()
49{
50	atf_set "descr" "Tests out -a / -f without -t"
51}
52attach_vnode_non_explicit_type_body()
53{
54	local md
55	local size_in_mb=1024
56
57	atf_check -s exit:0 -x "truncate -s ${size_in_mb}m xxx"
58	atf_check -s exit:0 -o save:mdconfig.out -x 'mdconfig -af xxx'
59	md=$(cat mdconfig.out)
60	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
61	check_diskinfo "$md" "1073741824" "2097152"
62	# This awk strips the file path.
63	atf_check -s exit:0 -o match:"^$md vnode ${size_in_mb}M$" \
64	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
65}
66attach_vnode_non_explicit_type_cleanup()
67{
68	cleanup_common
69}
70
71atf_test_case attach_vnode_implicit_a_f cleanup
72attach_vnode_implicit_a_f_head()
73{
74	atf_set "descr" "Tests out implied -a / -f without -t"
75}
76attach_vnode_implicit_a_f_body()
77{
78	local md
79	local size_in_mb=1024
80
81	atf_check -s exit:0 -x "truncate -s ${size_in_mb}m xxx"
82	atf_check -s exit:0 -o save:mdconfig.out -x 'mdconfig xxx'
83	md=$(cat mdconfig.out)
84	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
85	check_diskinfo "$md" "1073741824" "2097152"
86	# This awk strips the file path.
87	atf_check -s exit:0 -o match:"^$md vnode ${size_in_mb}M$" \
88	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
89}
90attach_vnode_implicit_a_f_cleanup()
91{
92	cleanup_common
93}
94
95atf_test_case attach_vnode_explicit_type cleanup
96attach_vnode_explicit_type_head()
97{
98	atf_set "descr" "Tests out implied -a / -f with -t vnode"
99}
100attach_vnode_explicit_type_body()
101{
102	local md
103	local size_in_mb=1024
104
105	atf_check -s exit:0 -x "truncate -s ${size_in_mb}m xxx"
106	atf_check -s exit:0 -o save:mdconfig.out -x 'mdconfig -af xxx -t vnode'
107	md=$(cat mdconfig.out)
108	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
109	check_diskinfo "$md" "1073741824" "2097152"
110	# This awk strips the file path.
111	atf_check -s exit:0 -o match:"^$md vnode ${size_in_mb}M$" \
112	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
113}
114attach_vnode_explicit_type_cleanup()
115{
116	[ -f mdconfig.out ] && mdconfig -d -u $(sed -e 's/md//' mdconfig.out)
117	rm -f mdconfig.out xxx
118}
119
120atf_test_case attach_vnode_smaller_than_file cleanup
121attach_vnode_smaller_than_file_head()
122{
123	atf_set "descr" "Tests mdconfig -s with size less than the file size"
124}
125attach_vnode_smaller_than_file_body()
126{
127	local md
128	local size_in_mb=128
129
130	atf_check -s exit:0 -x "truncate -s 1024m xxx"
131	atf_check -s exit:0 -o save:mdconfig.out \
132	    -x "mdconfig -af xxx -s ${size_in_mb}m"
133	md=$(cat mdconfig.out)
134	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
135	check_diskinfo "$md" "134217728" "262144"
136	# This awk strips the file path.
137	atf_check -s exit:0 -o match:"^$md vnode ${size_in_mb}M$" \
138	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
139}
140attach_vnode_smaller_than_file_cleanup()
141{
142	cleanup_common
143}
144
145atf_test_case attach_vnode_larger_than_file cleanup
146attach_vnode_larger_than_file_head()
147{
148	atf_set "descr" "Tests mdconfig -s with size greater than the file size"
149}
150attach_vnode_larger_than_file_body()
151{
152	local md
153	local size_in_gb=128
154
155	atf_check -s exit:0 -x "truncate -s 1024m xxx"
156	atf_check -s exit:0 -o save:mdconfig.out \
157	    -x "mdconfig -af xxx -s ${size_in_gb}g"
158	md=$(cat mdconfig.out)
159	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
160	check_diskinfo "$md" "137438953472" "268435456"
161	# This awk strips the file path.
162	atf_check -s exit:0 -o match:"^$md vnode ${size_in_gb}G$" \
163	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
164}
165attach_vnode_larger_than_file_cleanup()
166{
167	cleanup_common
168}
169
170atf_test_case attach_vnode_sector_size cleanup
171attach_vnode_sector_size_head()
172{
173	atf_set "descr" "Tests mdconfig -S with a backing file"
174}
175attach_vnode_sector_size_body()
176{
177	local md
178	local size_in_mb=1024
179
180	atf_check -s exit:0 -x "truncate -s ${size_in_mb}m xxx"
181	atf_check -s exit:0 -o save:mdconfig.out \
182	    -x "mdconfig -af xxx -S 2048"
183	md=$(cat mdconfig.out)
184	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
185	check_diskinfo "$md" "1073741824" "524288" "2048"
186	# This awk strips the file path.
187	atf_check -s exit:0 -o match:"^$md vnode ${size_in_mb}M$" \
188	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
189}
190attach_vnode_sector_size_cleanup()
191{
192	cleanup_common
193}
194
195atf_test_case attach_malloc cleanup
196attach_malloc_head()
197{
198	atf_set "descr" "Tests mdconfig with -t malloc"
199}
200attach_malloc_body()
201{
202	local md
203	local size_in_mb=1024
204
205	atf_check -s exit:0 -o save:mdconfig.out \
206	    -x 'mdconfig -a -t malloc -s 1g'
207	md=$(cat mdconfig.out)
208	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
209	check_diskinfo "$md" "1073741824" "2097152"
210	# This awk strips the file path.
211	atf_check -s exit:0 -o match:"^$md malloc ${size_in_mb}M$" \
212	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
213}
214attach_malloc_cleanup()
215{
216	cleanup_common
217}
218
219atf_test_case attach_swap cleanup
220attach_swap_head()
221{
222	atf_set "descr" "Tests mdconfig with -t swap"
223}
224attach_swap_body()
225{
226	local md
227	local size_in_mb=1024
228
229	atf_check -s exit:0 -o save:mdconfig.out \
230	    -x 'mdconfig -a -t swap -s 1g'
231	md=$(cat mdconfig.out)
232	atf_check -s exit:0 -o match:'^md[0-9]+$' -x "echo $md"
233	check_diskinfo "$md" "1073741824" "2097152"
234	# This awk strips the file path.
235	atf_check -s exit:0 -o match:"^$md swap ${size_in_mb}M$" \
236	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
237}
238attach_swap_cleanup()
239{
240	cleanup_common
241}
242
243atf_test_case attach_with_specific_unit_number cleanup
244attach_with_specific_unit_number_head()
245{
246	atf_set "descr" "Tests mdconfig with a unit specified by -u"
247}
248attach_with_specific_unit_number_body()
249{
250	local md_unit=99
251	local size_in_mb=10
252
253	local md="md${md_unit}"
254
255	echo "$md" > mdconfig.out
256
257	atf_check -s exit:0 -o empty \
258	    -x "mdconfig -a -t malloc -s ${size_in_mb}m -u $md_unit"
259	check_diskinfo "$md" "10485760" "20480"
260	# This awk strips the file path.
261	atf_check -s exit:0 -o match:"^$md malloc "$size_in_mb"M$" \
262	    -x "mdconfig -lv | awk '\$1 == \"$md\" { print \$1, \$2, \$3 }'"
263}
264attach_with_specific_unit_number_cleanup()
265{
266	cleanup_common
267}
268
269atf_test_case attach_size_rounddown cleanup
270attach_size_rounddown()
271{
272	atf_set "descr" "Verify that md provider sizes are a multiple of the sector size"
273}
274attach_size_rounddown_body()
275{
276	local md
277	local ss=8192
278	local ms=$(($ss + 4096))
279	local ms2=$((2 * $ss + 4096))
280
281	# Use a sector size that's a likely multiple of PAGE_SIZE, as md(4)
282	# expects that for swap MDs.
283	atf_check -s exit:0 -o save:mdconfig.out -e empty \
284	    -x "mdconfig -a -t swap -S $ss -s ${ms}b"
285	md=$(cat mdconfig.out)
286	# 12288 bytes should be rounded down to one sector.
287	check_diskinfo "$md" 8192 1 $ss
288
289	# Resize and verify that the new size was also rounded down.
290	atf_check -s exit:0 -o empty -e empty \
291	    -x "mdconfig -r -u ${md#md} -s ${ms2}b"
292	check_diskinfo "$md" 16384 2 $ss
293}
294attach_size_rounddown()
295{
296	cleanup_common
297}
298
299atf_init_test_cases()
300{
301	atf_add_test_case attach_vnode_non_explicit_type
302	atf_add_test_case attach_vnode_explicit_type
303	atf_add_test_case attach_vnode_smaller_than_file
304	atf_add_test_case attach_vnode_larger_than_file
305	atf_add_test_case attach_vnode_sector_size
306	atf_add_test_case attach_malloc
307	atf_add_test_case attach_swap
308	atf_add_test_case attach_with_specific_unit_number
309	atf_add_test_case attach_size_rounddown
310}
311