diff --git a/builds/any/installer/installer.sh.in b/builds/any/installer/installer.sh.in index da7a24cb..76b33987 100644 --- a/builds/any/installer/installer.sh.in +++ b/builds/any/installer/installer.sh.in @@ -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 diff --git a/packages/base/all/vendor-config-onl/src/lib/install/lib.sh b/packages/base/all/vendor-config-onl/src/lib/install/lib.sh index 311bd5d5..72f6290f 100644 --- a/packages/base/all/vendor-config-onl/src/lib/install/lib.sh +++ b/packages/base/all/vendor-config-onl/src/lib/install/lib.sh @@ -189,6 +189,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