1 #!/bin/bash 2 # test gdisk and sgdisk by creating a dd file 3 # Copyright (C) 2011 Guillaume Delacour <gui (at] iroqwa.org> 4 # 5 # This program is free software; you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation; either version 2 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License along 16 # with this program; if not, write to the Free Software Foundation, Inc., 17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 # 19 # 20 # Requires: coreutils (mktemp, dd) and 64M of disk space in /tmp (temp dd disk) 21 # 22 # This script test gdisk commands through the following scenario: 23 # - Initialize a new GPT table 24 # - Create a single Linux partition 25 # - Change name of partition 26 # - Change type of partition 27 # - Backup to file the GPT table 28 # - Delete the single partition 29 # - Restore from backup file the GPT table 30 # - Wipe the GPT table 31 32 # TODO 33 # Try to generate a wrong GPT table to detect problems (test --verify) 34 # Create MBR partition table with fdisk and migrate it with gdisk 35 36 GDISK_BIN=./gdisk 37 SGDISK_BIN=./sgdisk 38 39 OPT_CLEAR="o" 40 OPT_NEW="n" 41 OPT_CHANGE_NAME="c" 42 OPT_CHANGE_TYPE="t" 43 OPT_BACKUP="b" 44 OPT_DELETE="d" 45 OPT_ZAP="z" 46 47 # temp disk for testing gdisk 48 TEMP_DISK=$(mktemp) 49 # 64 MiB 50 TEMP_DISK_SIZE=65536 51 52 # the test partition to create 53 TEST_PART_TYPE="8300" 54 TEST_PART_DEFAULT_NAME="Linux filesystem" 55 56 # newname for the partition 57 TEST_PART_NEWNAME=$(tr -dc "[:alpha:]" < /dev/urandom | head -c 8) 58 # and new type (swap for example) 59 TEST_PART_NEWTYPE="8200" 60 61 # GPT data backup to filename 62 GPT_BACKUP_FILENAME=$(mktemp) 63 64 # Pretty print string (Red if FAILED or green if SUCCESS) 65 # $1: string to pretty print 66 pretty_print() { 67 if [ "$1" = "SUCCESS" ] 68 then 69 # green 70 color="32" 71 else 72 # red 73 color="31" 74 fi 75 76 printf "\033[0;${color}m**$1**\033[m $2\n" 77 } 78 79 # Verify that the partition exist and has the given type/name 80 # $1: Partition type to verify (ex.: 8300) 81 # $2: Partition name to verify (ex.: Linux filesystem) 82 # $3: Text to print 83 verify_part() { 84 partition=$($GDISK_BIN -l $TEMP_DISK | tail -n 1) 85 echo $partition | grep -q "$1[[:space:]]$2$" 86 87 if [ $? -eq 0 ] 88 then 89 pretty_print "SUCCESS" "$3" 90 else 91 pretty_print "FAILED" "$3" 92 exit 1 93 fi 94 } 95 96 97 ##################################### 98 # Get GUID of disk 99 ##################################### 100 get_diskguid() { 101 DISK_GUID=$($GDISK_BIN -l $TEMP_DISK | grep "^Disk identifier (GUID):" | awk '{print $4}') 102 return $DISK_GUID 103 } 104 105 106 ##################################### 107 # Create a new empty table 108 ##################################### 109 create_table() { 110 case $1 in 111 gdisk) 112 $GDISK_BIN $TEMP_DISK << EOF 113 $OPT_CLEAR 114 Y 115 w 116 Y 117 EOF 118 ;; 119 sgdisk) 120 $SGDISK_BIN $TEMP_DISK -${OPT_CLEAR} 121 ;; 122 esac 123 124 # verify that the table is empty 125 # only the columns should appear in the table 126 verify_part "Code" "Name" "Create new empty GPT table" 127 echo "" 128 } 129 130 131 132 ##################################### 133 # First create a new partition 134 ##################################### 135 create_partition() { 136 case $1 in 137 gdisk) 138 $GDISK_BIN $TEMP_DISK << EOF 139 $OPT_NEW 140 1 141 142 143 $TEST_PART_TYPE 144 w 145 Y 146 EOF 147 ;; 148 149 sgdisk) 150 $SGDISK_BIN $TEMP_DISK -${OPT_NEW} 1 -${OPT_CHANGE_NAME} 1:"${TEST_PART_DEFAULT_NAME}" 151 ;; 152 esac 153 154 verify_part "$TEST_PART_TYPE" "$TEST_PART_DEFAULT_NAME" "Create new partition" 155 echo "" 156 } 157 158 159 ##################################### 160 # Change name of partition 161 ##################################### 162 change_partition_name() { 163 case $1 in 164 gdisk) 165 $GDISK_BIN $TEMP_DISK << EOF 166 $OPT_CHANGE_NAME 167 $TEST_PART_NEWNAME 168 w 169 Y 170 EOF 171 ;; 172 173 sgdisk) 174 $SGDISK_BIN $TEMP_DISK -${OPT_CHANGE_NAME} 1:${TEST_PART_NEWNAME} 175 ;; 176 esac 177 178 verify_part "$TEST_PART_TYPE" "$TEST_PART_NEWNAME" "Change partition 1 name ($TEST_PART_DEFAULT_NAME -> $TEST_PART_NEWNAME)" 179 echo "" 180 } 181 182 183 change_partition_type() { 184 ##################################### 185 # Change type of partition 186 ##################################### 187 case $1 in 188 gdisk) 189 $GDISK_BIN $TEMP_DISK << EOF 190 $OPT_CHANGE_TYPE 191 $TEST_PART_NEWTYPE 192 w 193 Y 194 EOF 195 ;; 196 197 sgdisk) 198 $SGDISK_BIN $TEMP_DISK -${OPT_CHANGE_TYPE} 1:${TEST_PART_NEWTYPE} 199 ;; 200 esac 201 202 verify_part "$TEST_PART_NEWTYPE" "$TEST_PART_NEWNAME" "Change partition 1 type ($TEST_PART_TYPE -> $TEST_PART_NEWTYPE)" 203 echo "" 204 } 205 206 207 ##################################### 208 # Backup GPT data to file 209 ##################################### 210 backup_table() { 211 case $1 in 212 gdisk) 213 $GDISK_BIN $TEMP_DISK << EOF 214 $OPT_BACKUP 215 $GPT_BACKUP_FILENAME 216 q 217 EOF 218 echo "" 219 ;; 220 221 sgdisk) 222 $SGDISK_BIN $TEMP_DISK -${OPT_BACKUP} ${GPT_BACKUP_FILENAME} 223 ;; 224 esac 225 226 # if exist and not empty; we will test it after 227 if [ -s $GPT_BACKUP_FILENAME ] 228 then 229 pretty_print "SUCCESS" "GPT data backuped sucessfully" 230 else 231 pretty_print "FAILED" "Unable to create GPT backup file !" 232 exit 1 233 fi 234 } 235 236 237 ##################################### 238 # Now, we can delete the partition 239 ##################################### 240 delete_partition() { 241 case $1 in 242 gdisk) 243 $GDISK_BIN $TEMP_DISK << EOF 244 $OPT_DELETE 245 w 246 Y 247 EOF 248 ;; 249 250 sgdisk) 251 $SGDISK_BIN $TEMP_DISK -${OPT_DELETE} 1 252 ;; 253 esac 254 255 # verify that the table is empty (just one partition): 256 # only the columns should appear in the table 257 verify_part "Code" "Name" "Delete partition 1" 258 echo "" 259 } 260 261 262 ##################################### 263 # Restore GPT table 264 ##################################### 265 restore_table() { 266 $GDISK_BIN $TEMP_DISK << EOF 267 r 268 r 269 l 270 $GPT_BACKUP_FILENAME 271 w 272 Y 273 EOF 274 275 verify_part "$TEST_PART_NEWTYPE" "$TEST_PART_NEWNAME" "Restore the GPT backup" 276 echo "" 277 } 278 279 280 ##################################### 281 # Change UID of disk 282 ##################################### 283 change_disk_uid() { 284 285 # get UID of disk before changing it 286 GUID=get_diskguid 287 288 289 case $1 in 290 gdisk) 291 $GDISK_BIN $TEMP_DISK << EOF 292 x 293 g 294 R 295 w 296 Y 297 EOF 298 ;; 299 300 sgdisk) 301 $SGDISK_BIN $TEMP_DISK -U=R 302 ;; 303 esac 304 305 # get GUID after change 306 NEW_DISK_GUID=get_diskguid 307 308 # compare them 309 if [ "$DISK_GUID" != "$NEW_DISK_GUID" ] 310 then 311 pretty_print "SUCCESS" "GUID of disk has been sucessfully changed" 312 else 313 pretty_print "FAILED" "GUID of disk is the same as the previous one" 314 fi 315 } 316 317 ##################################### 318 # Wipe GPT table 319 ##################################### 320 wipe_table() { 321 case $1 in 322 gdisk) 323 $GDISK_BIN $TEMP_DISK << EOF 324 x 325 $OPT_ZAP 326 Y 327 Y 328 EOF 329 ;; 330 331 sgdisk) 332 $SGDISK_BIN $TEMP_DISK -${OPT_ZAP} 333 esac 334 335 # verify that the table is empty (just one partition): 336 # only the columns should appear in the table 337 verify_part "Code" "Name" "Wipe GPT table" 338 echo "" 339 } 340 341 ##################################### 342 # Test stdin EOF 343 ##################################### 344 eof_stdin() { 345 $SGDISK_BIN $TEMP_DISK << EOF 346 ^D 347 EOF 348 pretty_print "SUCCESS" "EOF successfully exit gdisk" 349 } 350 351 ################################### 352 # Main 353 ################################### 354 355 # create a file to simulate a real device 356 dd if=/dev/zero of=$TEMP_DISK bs=1024 count=$TEMP_DISK_SIZE 357 358 if [ -s $TEMP_DISK ] 359 then 360 pretty_print "SUCCESS" "Temp disk sucessfully created" 361 else 362 pretty_print "FAILED" "Unable to create temp disk !" 363 exit 1 364 fi 365 366 # test gdisk and sgdisk 367 for binary in gdisk sgdisk 368 do 369 echo "" 370 printf "\033[0;34m**Testing $binary binary**\033[m\n" 371 echo "" 372 create_table "$binary" 373 create_partition "$binary" 374 change_partition_name "$binary" 375 change_partition_type "$binary" 376 backup_table "$binary" 377 delete_partition "$binary" 378 restore_table # only with gdisk 379 change_disk_uid "$binary" 380 wipe_table "$binary" 381 eof_stdin # only with gdisk 382 done 383 384 # remove temp files 385 rm -f $TEMP_DISK $GPT_BACKUP_FILENAME 386 387 exit 0 388