t_gpt.sh revision 1.8 1 # $NetBSD: t_gpt.sh,v 1.8 2015/12/05 18:45:35 christos Exp $
2 #
3 # Copyright (c) 2015 The NetBSD Foundation, Inc.
4 # All rights reserved.
5 #
6 # This code is derived from software contributed to The NetBSD Foundation
7 # by Christos Zoulas
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions
11 # are met:
12 # 1. Redistributions of source code must retain the above copyright
13 # notice, this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright
15 # notice, this list of conditions and the following disclaimer in the
16 # documentation and/or other materials provided with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 # POSSIBILITY OF SUCH DAMAGE.
29 #
30
31 bootblk=/usr/mdec/gptmbr.bin
32 size=10240
33 newsize=20480
34 shdr=34
35 disk=gpt.disk
36 uuid="........-....-....-....-............"
37 zero="00000000-0000-0000-0000-000000000000"
38 src=$(atf_get_srcdir)
39
40 silence() {
41 atf_check -s exit:0 -o empty -e empty "$@"
42 }
43
44 match() {
45 local match="$1"
46 shift
47 atf_check -s exit:0 -e empty -o match:"$match" "$@"
48 }
49
50 matcherr() {
51 local match="$1"
52 shift
53 atf_check -s exit:0 -o empty -e match:"$match" "$@"
54 }
55
56 file() {
57 local file="$1"
58 shift
59 atf_check -s exit:0 -e empty -o file:"$file" "$@"
60 }
61
62 save() {
63 local save="$1"
64 shift
65 atf_check -s exit:0 -e empty -o save:"$save" "$@"
66 }
67
68 zerodd() {
69 silence dd conv=notrunc msgfmt=quiet if=/dev/zero of="$disk" "$@"
70 }
71
72 prepare() {
73 rm -f "$disk"
74 zerodd seek="$size" count=1
75 }
76
77 prepare_2part() {
78 prepare
79 silence gpt create "$disk"
80 match "$(partaddmsg 1 34 1024)" gpt add -t efi -s 1024 "$disk"
81 match "$(partaddmsg 2 1058 9150)" gpt add "$disk"
82 }
83
84 # Calling this from tests does not work. BUG!
85 check_2part() {
86 file "$src/gpt.2part.show.normal" gpt show "$disk"
87 file "$src/gpt.2part.show.uuid" gpt show -u "$disk"
88 }
89
90 partaddmsg() {
91 echo "^$disk: Partition $1 added: $uuid $2 $3\$"
92 }
93
94 partresmsg() {
95 echo "^$disk: Partition $1 resized: $2 $3\$"
96 }
97
98 partremmsg() {
99 echo "^$disk: Partition $1 removed\$"
100 }
101
102 partlblmsg() {
103 echo "^$disk: Partition $1 label changed\$"
104 }
105
106 partbootmsg() {
107 echo "^$disk: Partition $1 marked as bootable\$"
108
109 }
110
111 recovermsg() {
112 echo "^$disk: Recovered $1 GPT [a-z]* from $2\$"
113 }
114
115 migratemsg() {
116 echo -n "^gpt: $disk: Partition $1 unknown type MSDOS, "
117 echo 'using "Microsoft Basic Data"$'
118 }
119
120 atf_test_case create_empty
121 create_empty_head() {
122 atf_set "descr" "Create empty disk"
123 }
124
125 create_empty_body() {
126 prepare
127 silence gpt create "$disk"
128 file "$src/gpt.empty.show.normal" gpt show "$disk"
129 }
130
131 atf_test_case create_2part
132 create_2part_head() {
133 atf_set "descr" "Create 2 partition disk"
134 }
135
136 create_2part_body() {
137 prepare_2part
138 check_2part
139 }
140
141 atf_test_case backup_2part
142 backup_2part_head() {
143 atf_set "descr" "Backup 2 partition disk"
144 }
145
146 backup_2part_body() {
147 prepare_2part
148 save test.backup gpt backup "$disk"
149 file "$src/gpt.backup" sed -e "s/$uuid/$zero/g" "test.backup"
150 }
151
152 atf_test_case restore_2part
153 restore_2part_head() {
154 atf_set "descr" "Restore 2 partition disk"
155 }
156
157 restore_2part_body() {
158 prepare_2part
159 save test.backup gpt backup "$disk"
160 prepare
161 silence gpt restore -i test.backup "$disk"
162 check_2part
163 }
164
165 atf_test_case recover_backup
166 recover_backup_head() {
167 atf_set "descr" "Recover the backup GPT header and table"
168 }
169
170 recover_backup_body() {
171 prepare_2part
172 zerodd seek="$((size - shdr))" count="$shdr"
173 match "$(recovermsg secondary primary)" gpt recover "$disk"
174 check_2part
175 }
176
177 atf_test_case recover_primary
178 recover_primary_head() {
179 atf_set "descr" "Recover the primary GPT header and table"
180 }
181
182 recover_primary_body() {
183 prepare_2part
184 zerodd seek=1 count="$shdr"
185 match "$(recovermsg primary secondary)" gpt recover "$disk"
186 check_2part
187 }
188
189 atf_test_case resize_2part
190 resize_2part_head() {
191 atf_set "descr" "Resize a 2 partition disk and partition"
192 }
193
194 resize_2part_body() {
195 prepare_2part
196 zerodd seek="$newsize" count=1
197 silence gpt resizedisk "$disk"
198 file "$src/gpt.resizedisk.show.normal" gpt show "$disk"
199 match "$(partresmsg 2 1058 19390)" gpt resize -i 2 "$disk"
200 file "$src/gpt.resizepart.show.normal" gpt show "$disk"
201 }
202
203 atf_test_case remove_2part
204 remove_2part_head() {
205 atf_set "descr" "Remove a partition from a 2 partition disk"
206 }
207
208 remove_2part_body() {
209 prepare_2part
210 match "$(partremmsg 1)" -e empty gpt remove \
211 -i 1 "$disk"
212 file "$src/gpt.removepart.show.normal" \
213 gpt show "$disk"
214 }
215
216 atf_test_case label_2part
217 label_2part_head() {
218 atf_set "descr" "Label partitions in a 2 partition disk"
219 }
220
221 label_2part_body() {
222 prepare_2part
223 match "$(partlblmsg 1)" gpt label -i 1 -l potato "$disk"
224 match "$(partlblmsg 2)" gpt label -i 2 -l tomato "$disk"
225 file "$src/gpt.2part.show.label" \
226 gpt show -l "$disk"
227 }
228
229 atf_test_case bootable_2part
230 bootable_2part_head() {
231 atf_set "descr" "Make partition 2 bootable in a 2 partition disk"
232 }
233
234 bootable_2part_body() {
235 prepare_2part
236 match "$(partbootmsg 2)" gpt biosboot -i 2 "$disk"
237 local bootsz="$(ls -l "$bootblk" | awk '{ print $5 }')"
238 silence dd msgfmt=quiet if="$disk" of=bootblk bs=1 count="$bootsz"
239 silence cmp "$bootblk" bootblk
240 save bootattr gpt show -i 2 "$disk"
241 match "^ legacy BIOS boot partition\$" tail -1 bootattr
242 }
243
244 atf_test_case migrate_disklabel
245 migrate_disklabel_head() {
246 atf_set "descr" "Migrate an MBR+disklabel disk to GPT"
247 }
248
249 migrate_disklabel_body() {
250 prepare
251 silence fdisk -fi gpt.disk
252 silence fdisk -fu0s 169/63/$((size / 10)) gpt.disk
253 silence disklabel -R gpt.disk "$src/disklabel"
254 matcherr "$(migratemsg 5)" gpt migrate "$disk"
255 file "$src/gpt.disklabel" gpt show "$disk"
256 }
257
258 atf_init_test_cases() {
259 atf_add_test_case create_empty
260 atf_add_test_case create_2part
261 atf_add_test_case backup_2part
262 atf_add_test_case remove_2part
263 atf_add_test_case restore_2part
264 atf_add_test_case recover_backup
265 atf_add_test_case recover_primary
266 atf_add_test_case resize_2part
267 atf_add_test_case label_2part
268 atf_add_test_case bootable_2part
269 atf_add_test_case migrate_disklabel
270 }
271