Proactively fix GPT partition tables, see SWL-3971

- try to find the boot device
- try to determine if the boot device is GPT
- use sgdisk to correct simple errors
This commit is contained in:
Carl D. Roth
2017-08-08 19:51:05 -07:00
parent 8c1df07a86
commit 6c4983faad
2 changed files with 116 additions and 0 deletions

View File

@@ -548,6 +548,9 @@ if test -f preinstall.sh; then
./preinstall.sh $rootdir
fi
# make sure any GPT data is valid and clean
installer_fixup_gpt || :
chroot "${rootdir}" $installer_shell
if test -f "$postinst"; then

View File

@@ -186,6 +186,119 @@ visit_blkid()
return 0
}
##############################
#
# Fixup a corrupted GPT partition, within reason
# See SWL-3971
#
##############################
blkid_find_gpt_boot() {
local dev label
dev=$1; shift
label=$1; shift
rest="$@"
installer_say "Examining $dev --> $label"
# EFI partition shows up as a valid partition with blkid
if test "$label" = "EFI System"; then
installer_say "Found EFI System partition at $dev"
ESP_DEVICE=$(echo "$dev" | sed -e 's/[0-9]$//')
# this is definitely the boot disk
return 2
fi
# sometimes this is hidden from blkid (no filesystem)
if test "$label" = "GRUB-BOOT"; then
installer_say "Found GRUB boot partition at $dev"
GRUB_DEVICE=$(echo "$dev" | sed -e 's/[0-9]$//')
# probably the boot disk, look for a GPT header
return 0
fi
# shows up in blkid but may not be GPT
if test "$label" = "ONIE-BOOT"; then
installer_say "Found ONIE boot partition at $dev"
ONIE_DEVICE=$(echo "$dev" | sed -e 's/[0-9]$//')
# probably the boot disk, look for a GPT header
return 0
fi
# not found, skip
return 0
}
installer_fixup_gpt() {
local buf dat sts dev
buf=$(mktemp -u -t sgdisk-XXXXXX)
ESP_DEVICE=
GRUB_DEVICE=
ONIE_DEVICE=
visit_blkid blkid_find_gpt_boot
dev=
if test -b "$ESP_DEVICE"; then
dev=$ESP_DEVICE
elif test -b "$GRUB_DEVICE"; then
sgdisk -p "$GRUB_DEVICE" > "$buf" 2>&1 || :
if grep -q GUID "$buf"; then
dev=$GRUB_DEVICE
fi
elif test -b "$ONIE_DEVICE"; then
sgdisk -p "$ONIE_DEVICE" > "$buf" 2>&1 || :
if grep -q GUID "$buf"; then
# here we assume that the ONIE boot partition is on
# the boot disk
# (additionally we could also look for 'GRUB-BOOT')
dev=$ONIE_DEVICE
fi
fi
test -b "$dev" || return 0
# see if it's a clean GPT partition table
if sgdisk -p "$dev" > "$buf" 2>&1; then
sts=0
else
sts=$?
fi
if test $sts -ne 0; then
cat "$buf" 1>&2
rm -f "$buf"
installer_say "Cannot reliably get GPT partition table"
return 1
fi
case $(cat "$buf") in
*Caution*|*Warning*)
cat $buf 1>&2
installer_say "Found issues with the GPT partition table"
rm -f "$buf"
;;
*)
installer_say "Found a clean GPT partition table"
rm -f "$buf"
return 0
;;
esac
installer_say "Attempting to correct the GPT partition table"
# this is the simple method; gdisk/sfgdisk will correct
# simple errors but not horrendous faults
dat=$(mktemp -u -t sgdisk-XXXXXX)
sgdisk -b "$dat" "$dev" || return 1
sgdisk -l "$dat" "$dev" || return 1
rm -f "$dat"
return 0
}
# Local variables
# mode: sh
# sh-basic-offset: 2