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