1#!/bin/bash 2# test gdisk and sgdisk by creating a dd file 3# Copyright (C) 2011 Guillaume Delacour <gui@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 36GDISK_BIN=./gdisk 37SGDISK_BIN=./sgdisk 38 39OPT_CLEAR="o" 40OPT_NEW="n" 41OPT_CHANGE_NAME="c" 42OPT_CHANGE_TYPE="t" 43OPT_BACKUP="b" 44OPT_DELETE="d" 45OPT_ZAP="z" 46 47# temp disk for testing gdisk 48TEMP_DISK=$(mktemp) 49# 64 MiB 50TEMP_DISK_SIZE=65536 51 52# the test partition to create 53TEST_PART_TYPE="8300" 54TEST_PART_DEFAULT_NAME="Linux filesystem" 55 56# newname for the partition 57TEST_PART_NEWNAME=$(tr -dc "[:alpha:]" < /dev/urandom | head -c 8) 58# and new type (swap for example) 59TEST_PART_NEWTYPE="8200" 60 61# GPT data backup to filename 62GPT_BACKUP_FILENAME=$(mktemp) 63 64# Pretty print string (Red if FAILED or green if SUCCESS) 65# $1: string to pretty print 66pretty_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 83verify_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##################################### 100get_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##################################### 109create_table() { 110 case $1 in 111 gdisk) 112 $GDISK_BIN $TEMP_DISK << EOF 113$OPT_CLEAR 114Y 115w 116Y 117EOF 118 119 ret=$? 120 if [ $ret -ne 0 ] 121 then 122 pretty_print "FAILED" "gdisk return $ret when creating partition table" 123 exit 1 124 fi 125 ;; 126 sgdisk) 127 $SGDISK_BIN $TEMP_DISK -${OPT_CLEAR} 128 129 ret=$? 130 if [ $ret -ne 0 ] 131 then 132 pretty_print "FAILED" "sgdisk return $ret when creating partition table" 133 exit 1 134 fi 135 ;; 136 esac 137 138 # verify that the table is empty 139 # only the columns should appear in the table 140 verify_part "Code" "Name" "Create new empty GPT table" 141 echo "" 142} 143 144 145 146##################################### 147# First create a new partition 148##################################### 149create_partition() { 150 case $1 in 151 gdisk) 152 $GDISK_BIN $TEMP_DISK << EOF 153$OPT_NEW 1541 155 156 157$TEST_PART_TYPE 158w 159Y 160EOF 161 ;; 162 163 sgdisk) 164 $SGDISK_BIN $TEMP_DISK -${OPT_NEW} 1 -${OPT_CHANGE_NAME} 1:"${TEST_PART_DEFAULT_NAME}" -${OPT_CHANGE_TYPE} 1:$TEST_PART_TYPE 165 ;; 166 esac 167 168 verify_part "$TEST_PART_TYPE" "$TEST_PART_DEFAULT_NAME" "Create new partition" 169 echo "" 170} 171 172 173##################################### 174# Change name of partition 175##################################### 176change_partition_name() { 177 case $1 in 178 gdisk) 179 $GDISK_BIN $TEMP_DISK << EOF 180$OPT_CHANGE_NAME 181$TEST_PART_NEWNAME 182w 183Y 184EOF 185 ;; 186 187 sgdisk) 188 $SGDISK_BIN $TEMP_DISK -${OPT_CHANGE_NAME} 1:${TEST_PART_NEWNAME} 189 ;; 190 esac 191 192 verify_part "$TEST_PART_TYPE" "$TEST_PART_NEWNAME" "Change partition 1 name ($TEST_PART_DEFAULT_NAME -> $TEST_PART_NEWNAME)" 193 echo "" 194} 195 196 197change_partition_type() { 198##################################### 199# Change type of partition 200##################################### 201 case $1 in 202 gdisk) 203 $GDISK_BIN $TEMP_DISK << EOF 204$OPT_CHANGE_TYPE 205$TEST_PART_NEWTYPE 206w 207Y 208EOF 209 ;; 210 211 sgdisk) 212 $SGDISK_BIN $TEMP_DISK -${OPT_CHANGE_TYPE} 1:${TEST_PART_NEWTYPE} 213 ;; 214 esac 215 216 verify_part "$TEST_PART_NEWTYPE" "$TEST_PART_NEWNAME" "Change partition 1 type ($TEST_PART_TYPE -> $TEST_PART_NEWTYPE)" 217 echo "" 218} 219 220 221##################################### 222# Backup GPT data to file 223##################################### 224backup_table() { 225 case $1 in 226 gdisk) 227 $GDISK_BIN $TEMP_DISK << EOF 228$OPT_BACKUP 229$GPT_BACKUP_FILENAME 230q 231EOF 232echo "" 233 ;; 234 235 sgdisk) 236 $SGDISK_BIN $TEMP_DISK -${OPT_BACKUP} ${GPT_BACKUP_FILENAME} 237 ;; 238 esac 239 240 # if exist and not empty; we will test it after 241 if [ -s $GPT_BACKUP_FILENAME ] 242 then 243 pretty_print "SUCCESS" "GPT data backuped sucessfully" 244 else 245 pretty_print "FAILED" "Unable to create GPT backup file !" 246 exit 1 247 fi 248} 249 250 251##################################### 252# Now, we can delete the partition 253##################################### 254delete_partition() { 255 case $1 in 256 gdisk) 257 $GDISK_BIN $TEMP_DISK << EOF 258$OPT_DELETE 259w 260Y 261EOF 262 ;; 263 264 sgdisk) 265 $SGDISK_BIN $TEMP_DISK -${OPT_DELETE} 1 266 ;; 267 esac 268 269 # verify that the table is empty (just one partition): 270 # only the columns should appear in the table 271 verify_part "Code" "Name" "Delete partition 1" 272 echo "" 273} 274 275 276##################################### 277# Restore GPT table 278##################################### 279restore_table() { 280 $GDISK_BIN $TEMP_DISK << EOF 281r 282r 283l 284$GPT_BACKUP_FILENAME 285w 286Y 287EOF 288 289 verify_part "$TEST_PART_NEWTYPE" "$TEST_PART_NEWNAME" "Restore the GPT backup" 290 echo "" 291} 292 293 294##################################### 295# Change UID of disk 296##################################### 297change_disk_uid() { 298 299 # get UID of disk before changing it 300 GUID=get_diskguid 301 302 303 case $1 in 304 gdisk) 305 $GDISK_BIN $TEMP_DISK << EOF 306x 307g 308R 309w 310Y 311EOF 312 ;; 313 314 sgdisk) 315 $SGDISK_BIN $TEMP_DISK -U=R 316 ;; 317 esac 318 319 # get GUID after change 320 NEW_DISK_GUID=get_diskguid 321 322 # compare them 323 if [ "$DISK_GUID" != "$NEW_DISK_GUID" ] 324 then 325 pretty_print "SUCCESS" "GUID of disk has been sucessfully changed" 326 else 327 pretty_print "FAILED" "GUID of disk is the same as the previous one" 328 exit 1 329 fi 330} 331 332##################################### 333# Wipe GPT table 334##################################### 335wipe_table() { 336 case $1 in 337 gdisk) 338 $GDISK_BIN $TEMP_DISK << EOF 339x 340$OPT_ZAP 341Y 342Y 343EOF 344 ;; 345 346 sgdisk) 347 $SGDISK_BIN $TEMP_DISK -${OPT_ZAP} 348 esac 349 350 # verify that the table is empty (just one partition): 351 # only the columns should appear in the table 352 verify_part "Code" "Name" "Wipe GPT table" 353 echo "" 354} 355 356##################################### 357# Test stdin EOF 358##################################### 359eof_stdin() { 360 $SGDISK_BIN $TEMP_DISK << EOF 361^D 362EOF 363 pretty_print "SUCCESS" "EOF successfully exit gdisk" 364} 365 366################################### 367# Main 368################################### 369 370# create a file to simulate a real device 371dd if=/dev/zero of=$TEMP_DISK bs=1024 count=$TEMP_DISK_SIZE > /dev/null 2>&1 372 373if [ -s $TEMP_DISK ] 374then 375 pretty_print "SUCCESS" "Temp disk sucessfully created" 376else 377 pretty_print "FAILED" "Unable to create temp disk !" 378 exit 1 379fi 380 381# test gdisk and sgdisk 382for binary in gdisk sgdisk 383do 384 echo "" 385 printf "\033[0;34m**Testing $binary binary**\033[m\n" 386 echo "" 387 create_table "$binary" 388 create_partition "$binary" 389 change_partition_name "$binary" 390 change_partition_type "$binary" 391 backup_table "$binary" 392 delete_partition "$binary" 393 restore_table # only with gdisk 394 change_disk_uid "$binary" 395 wipe_table "$binary" 396 eof_stdin # only with gdisk 397done 398 399# remove temp files 400rm -f $TEMP_DISK $GPT_BACKUP_FILENAME 401 402exit 0 403