Skip to content

Commit

Permalink
Merge branch 'silence-exfat-errors-for-iso9660'
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathonHall-Purism committed Feb 23, 2024
2 parents 9d04319 + a6228b9 commit ebdcc85
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 56 deletions.
22 changes: 0 additions & 22 deletions initrd/bin/root-hashes-gui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,28 +159,6 @@ check_root_checksums() {
fi
}

# Check if a device is an LVM2 PV, and if so print the VG name
find_lvm_vg_name() {
TRACE_FUNC
local DEVICE VG
DEVICE="$1"

mkdir -p /tmp/root-hashes-gui
if ! lvm pvs "$DEVICE" >/tmp/root-hashes-gui/lvm_vg 2>/dev/null; then
# It's not an LVM PV
return 1
fi

VG="$(tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk '{print $2}')"
if [ -z "$VG" ]; then
DEBUG "Could not find LVM2 VG from lvm pvs output:"
DEBUG "$(cat /tmp/root-hashes-gui/lvm_vg)"
return 1
fi

echo "$VG"
}

# Open an LVM volume group, then continue looking for more layers in the 'root'
# logical volume.
open_block_device_lvm() {
Expand Down
172 changes: 138 additions & 34 deletions initrd/etc/functions
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,28 @@ enable_usb_storage() {
fi
}

device_has_partitions() {
local DEVICE="$1"
# fdisk normally says "doesn't contain a valid partition table" for
# devices that lack a partition table - except for FAT32.
#
# FAT32 devices have a volume boot record that looks enough like an MBR
# to satisfy fdisk. In that case, fdisk prints a partition table header
# but no partitions.
#
# This check covers that: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
# In both cases the output is 5 lines: 3 about device info, 1 empty line
# and the 5th will be the table header or the invalid message.
local DISK_DATA=$(fdisk -l "$DEVICE")
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || \
[ "$(echo "$DISK_DATA" | wc -l)" -eq 5 ]; then
# No partition table
return 1
fi
# There is a partition table
return 0
}

list_usb_storage() {
TRACE_FUNC
# List all USB storage devices, including partitions unless we received argument stating we want drives only
Expand Down Expand Up @@ -184,16 +206,7 @@ list_usb_storage() {
# never usable directly, and this allows the "wait for
# disks" loop in mount-usb to correctly wait for the
# partitions.
# This check: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
# covers the case of a device without partition table but
# formatted as fat32, which contains a sortof partition table.
# this causes fdisk to not print the invalid partition table
# message and instead it'll print an empty table with header.
# In both cases the output is 5 lines: 3 about device info,
# 1 empty line and the 5th will be the table header or the
# unvalid message.
DISK_DATA=$(fdisk -l "$b")
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || [ $(echo "$DISK_DATA" | wc -l) -eq 5 ]; then
if ! device_has_partitions "$b"; then
# No partition table, include this device
DEBUG "USB storage device without partition table: $b"
echo "$b"
Expand Down Expand Up @@ -520,52 +533,143 @@ verify_checksums() {
return $?
}

# Check if a device is an LVM2 PV, and if so print the VG name
find_lvm_vg_name() {
TRACE_FUNC
local DEVICE VG
DEVICE="$1"

mkdir -p /tmp/root-hashes-gui
if ! lvm pvs "$DEVICE" >/tmp/root-hashes-gui/lvm_vg 2>/dev/null; then
# It's not an LVM PV
return 1
fi

VG="$(tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk '{print $2}')"
if [ -z "$VG" ]; then
DEBUG "Could not find LVM2 VG from lvm pvs output:"
DEBUG "$(cat /tmp/root-hashes-gui/lvm_vg)"
return 1
fi

echo "$VG"
}

# If a block device is a partition, check if it is a bios-grub partition on a
# GPT-partitioned disk.
is_gpt_bios_grub() {
TRACE_FUNC

local PART_DEV="$1" DEVICE NUMBER

# Figure out the partitioned device containing this device (if there is
# one) from /sys/class/block.
local DEVICE_MATCHES=("/sys/class/block/"*"/$(basename "$PART_DEV")")

DEVICE="$(echo "${DEVICE_MATCHES[0]}" | cut -d/ -f5)"
if [ "${#DEVICE_MATCHES[@]}" -ne 1 ] || [ "$DEVICE" = "*" ]; then
return 0
fi

# Extract the partition number
if ! [[ $(basename "$PART_DEV") =~ ([0-9]+)$ ]]; then
return 0 # Can't figure out the partition number
fi

NUMBER="${BASH_REMATCH[1]}"

# Now we know the device and partition number, get the type. This is
# specific to GPT disks, MBR disks are shown differently by fdisk.
TRACE "$PART_DEV is partition $NUMBER of $DEVICE"
if [ "$(fdisk -l "/dev/$DEVICE" | awk '$1 == '"$NUMBER"' {print $5}')" == grub ]; then
return 0
fi
return 1
}

# Test if a block device could be used as /boot - we can mount it and it
# contains /boot/grub* files. (Here, the block device could be a partition or
# an unpartitioned device.)
#
# If the device is a partition, its type is also checked. Some common types
# that we definitely can't mount this way are excluded to silence spurious exFAT
# errors.
#
# Any existing /boot is unmounted. If the device is a reasonable boot device,
# it's left mounted on /boot.
mount_possible_boot_device() {
TRACE_FUNC

local BOOT_DEV="$1"
local PARTITION_TYPE

# Unmount anything on /boot. Ignore failure since there might not be
# anything. If there is something mounted and we cannot unmount it for
# some reason, mount will fail, which is handled.
umount /boot 2>/dev/null || true

# Skip bios-grub partitions on GPT disks, LUKS partitions, and LVM PVs,
# we can't mount these as /boot.
if is_gpt_bios_grub "$BOOT_DEV" || cryptsetup isLuks "$BOOT_DEV" ||
find_lvm_vg_name "$BOOT_DEV" >/dev/null; then
TRACE "$BOOT_DEV is not a mountable partition for /boot"
return 1
fi

TRACE "Try mounting $BOOT_DEV as /boot"
if mount -o ro "$BOOT_DEV" /boot >/dev/null 2>&1; then
if ls -d /boot/grub* >/dev/null 2>&1; then
# This device is a reasonable boot device
return 0
fi
umount /boot || true
fi

return 1
}

# detect and set /boot device
# mount /boot if successful
detect_boot_device() {
TRACE_FUNC
local devname
# unmount /boot to be safe
cd / && umount /boot 2>/dev/null

# check $CONFIG_BOOT_DEV if set/valid
if [ -e "$CONFIG_BOOT_DEV" ]; then
if mount -o ro $CONFIG_BOOT_DEV /boot >/dev/null 2>&1; then
if ls -d /boot/grub* >/dev/null 2>&1; then
# CONFIG_BOOT_DEV is valid device and contains an installed OS
return 0
fi
fi
if [ -e "$CONFIG_BOOT_DEV" ] && mount_possible_boot_device "$CONFIG_BOOT_DEV"; then
# CONFIG_BOOT_DEV is valid device and contains an installed OS
return 0
fi

# generate list of possible boot devices
fdisk -l | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist

# filter out extraneous options
>/tmp/boot_device_list
# Check each possible boot device
for i in $(cat /tmp/disklist); do
# remove block device from list if numeric partitions exist, since not bootable
DEV_NUM_PARTITIONS=$(($(ls -1 $i* | wc -l) - 1))
if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then
echo $i >>/tmp/boot_device_list
# If the device has partitions, check the partitions instead
if device_has_partitions "$i"; then
devname="$(basename "$i")"
partitions=("/sys/class/block/$devname/$devname"?*)
else
ls $i* | tail -${DEV_NUM_PARTITIONS} >>/tmp/boot_device_list
partitions=("$i") # Use the device itself
fi
done

# iterate thru possible options and check for grub dir
for i in $(cat /tmp/boot_device_list); do
umount /boot 2>/dev/null
if mount -o ro $i /boot >/dev/null 2>&1; then
if ls -d /boot/grub* >/dev/null 2>&1; then
CONFIG_BOOT_DEV="$i"
for partition in "${partitions[@]}"; do
partition_dev=/dev/"$(basename "$partition")"
# No sense trying something we already tried above
if [ "$partition_dev" = "$CONFIG_BOOT_DEV" ]; then
continue
fi
# If this is a reasonable boot device, select it and finish
if mount_possible_boot_device "$partition_dev"; then
CONFIG_BOOT_DEV="$partition_dev"
return 0
fi
fi
done
done

# no valid boot device found
echo "Unable to locate /boot files on any mounted disk"
umount /boot 2>/dev/null
return 1
}

Expand Down
6 changes: 6 additions & 0 deletions initrd/init
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ fi
# Load the date from the hardware clock, setting it in local time
hwclock -l -s

# When mounting a filesystem, try exFAT last, since it logs errors if the
# filesystem is not exFAT, and the errors go to the console. Those errors are
# spurious when the medium is iso9660. By default in our config, the only
# filesystem after exFAT is iso9660, move exFAT last.
(grep -v '^\texfat$' /proc/filesystems && echo -e '\texfat') >/etc/filesystems

# Read the system configuration parameters
. /etc/ash_functions
. /etc/config
Expand Down

0 comments on commit ebdcc85

Please sign in to comment.