Home | History | Annotate | Download | only in gptfdisk
      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