• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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