Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

init: Silence exFAT errors when mounting iso9660; reorder exfat last #1602

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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