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 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##################################### 135create_partition() { 136 case $1 in 137 gdisk) 138 $GDISK_BIN $TEMP_DISK << EOF 139$OPT_NEW 1401 141 142 143$TEST_PART_TYPE 144w 145Y 146EOF 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##################################### 162change_partition_name() { 163 case $1 in 164 gdisk) 165 $GDISK_BIN $TEMP_DISK << EOF 166$OPT_CHANGE_NAME 167$TEST_PART_NEWNAME 168w 169Y 170EOF 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 183change_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 192w 193Y 194EOF 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##################################### 210backup_table() { 211 case $1 in 212 gdisk) 213 $GDISK_BIN $TEMP_DISK << EOF 214$OPT_BACKUP 215$GPT_BACKUP_FILENAME 216q 217EOF 218echo "" 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##################################### 240delete_partition() { 241 case $1 in 242 gdisk) 243 $GDISK_BIN $TEMP_DISK << EOF 244$OPT_DELETE 245w 246Y 247EOF 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##################################### 265restore_table() { 266 $GDISK_BIN $TEMP_DISK << EOF 267r 268r 269l 270$GPT_BACKUP_FILENAME 271w 272Y 273EOF 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##################################### 283change_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 292x 293g 294R 295w 296Y 297EOF 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##################################### 320wipe_table() { 321 case $1 in 322 gdisk) 323 $GDISK_BIN $TEMP_DISK << EOF 324x 325$OPT_ZAP 326Y 327Y 328EOF 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##################################### 344eof_stdin() { 345 $SGDISK_BIN $TEMP_DISK << EOF 346^D 347EOF 348 pretty_print "SUCCESS" "EOF successfully exit gdisk" 349} 350 351################################### 352# Main 353################################### 354 355# create a file to simulate a real device 356dd if=/dev/zero of=$TEMP_DISK bs=1024 count=$TEMP_DISK_SIZE 357 358if [ -s $TEMP_DISK ] 359then 360 pretty_print "SUCCESS" "Temp disk sucessfully created" 361else 362 pretty_print "FAILED" "Unable to create temp disk !" 363 exit 1 364fi 365 366# test gdisk and sgdisk 367for binary in gdisk sgdisk 368do 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 382done 383 384# remove temp files 385rm -f $TEMP_DISK $GPT_BACKUP_FILENAME 386 387exit 0 388