Skip to content

Commit ebdcc85

Browse files
Merge branch 'silence-exfat-errors-for-iso9660'
PR #1602
2 parents 9d04319 + a6228b9 commit ebdcc85

File tree

3 files changed

+144
-56
lines changed

3 files changed

+144
-56
lines changed

initrd/bin/root-hashes-gui.sh

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -159,28 +159,6 @@ check_root_checksums() {
159159
fi
160160
}
161161

162-
# Check if a device is an LVM2 PV, and if so print the VG name
163-
find_lvm_vg_name() {
164-
TRACE_FUNC
165-
local DEVICE VG
166-
DEVICE="$1"
167-
168-
mkdir -p /tmp/root-hashes-gui
169-
if ! lvm pvs "$DEVICE" >/tmp/root-hashes-gui/lvm_vg 2>/dev/null; then
170-
# It's not an LVM PV
171-
return 1
172-
fi
173-
174-
VG="$(tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk '{print $2}')"
175-
if [ -z "$VG" ]; then
176-
DEBUG "Could not find LVM2 VG from lvm pvs output:"
177-
DEBUG "$(cat /tmp/root-hashes-gui/lvm_vg)"
178-
return 1
179-
fi
180-
181-
echo "$VG"
182-
}
183-
184162
# Open an LVM volume group, then continue looking for more layers in the 'root'
185163
# logical volume.
186164
open_block_device_lvm() {

initrd/etc/functions

Lines changed: 138 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ enable_usb_storage() {
154154
fi
155155
}
156156

157+
device_has_partitions() {
158+
local DEVICE="$1"
159+
# fdisk normally says "doesn't contain a valid partition table" for
160+
# devices that lack a partition table - except for FAT32.
161+
#
162+
# FAT32 devices have a volume boot record that looks enough like an MBR
163+
# to satisfy fdisk. In that case, fdisk prints a partition table header
164+
# but no partitions.
165+
#
166+
# This check covers that: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
167+
# In both cases the output is 5 lines: 3 about device info, 1 empty line
168+
# and the 5th will be the table header or the invalid message.
169+
local DISK_DATA=$(fdisk -l "$DEVICE")
170+
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || \
171+
[ "$(echo "$DISK_DATA" | wc -l)" -eq 5 ]; then
172+
# No partition table
173+
return 1
174+
fi
175+
# There is a partition table
176+
return 0
177+
}
178+
157179
list_usb_storage() {
158180
TRACE_FUNC
159181
# List all USB storage devices, including partitions unless we received argument stating we want drives only
@@ -184,16 +206,7 @@ list_usb_storage() {
184206
# never usable directly, and this allows the "wait for
185207
# disks" loop in mount-usb to correctly wait for the
186208
# partitions.
187-
# This check: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
188-
# covers the case of a device without partition table but
189-
# formatted as fat32, which contains a sortof partition table.
190-
# this causes fdisk to not print the invalid partition table
191-
# message and instead it'll print an empty table with header.
192-
# In both cases the output is 5 lines: 3 about device info,
193-
# 1 empty line and the 5th will be the table header or the
194-
# unvalid message.
195-
DISK_DATA=$(fdisk -l "$b")
196-
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" || [ $(echo "$DISK_DATA" | wc -l) -eq 5 ]; then
209+
if ! device_has_partitions "$b"; then
197210
# No partition table, include this device
198211
DEBUG "USB storage device without partition table: $b"
199212
echo "$b"
@@ -520,52 +533,143 @@ verify_checksums() {
520533
return $?
521534
}
522535

536+
# Check if a device is an LVM2 PV, and if so print the VG name
537+
find_lvm_vg_name() {
538+
TRACE_FUNC
539+
local DEVICE VG
540+
DEVICE="$1"
541+
542+
mkdir -p /tmp/root-hashes-gui
543+
if ! lvm pvs "$DEVICE" >/tmp/root-hashes-gui/lvm_vg 2>/dev/null; then
544+
# It's not an LVM PV
545+
return 1
546+
fi
547+
548+
VG="$(tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk '{print $2}')"
549+
if [ -z "$VG" ]; then
550+
DEBUG "Could not find LVM2 VG from lvm pvs output:"
551+
DEBUG "$(cat /tmp/root-hashes-gui/lvm_vg)"
552+
return 1
553+
fi
554+
555+
echo "$VG"
556+
}
557+
558+
# If a block device is a partition, check if it is a bios-grub partition on a
559+
# GPT-partitioned disk.
560+
is_gpt_bios_grub() {
561+
TRACE_FUNC
562+
563+
local PART_DEV="$1" DEVICE NUMBER
564+
565+
# Figure out the partitioned device containing this device (if there is
566+
# one) from /sys/class/block.
567+
local DEVICE_MATCHES=("/sys/class/block/"*"/$(basename "$PART_DEV")")
568+
569+
DEVICE="$(echo "${DEVICE_MATCHES[0]}" | cut -d/ -f5)"
570+
if [ "${#DEVICE_MATCHES[@]}" -ne 1 ] || [ "$DEVICE" = "*" ]; then
571+
return 0
572+
fi
573+
574+
# Extract the partition number
575+
if ! [[ $(basename "$PART_DEV") =~ ([0-9]+)$ ]]; then
576+
return 0 # Can't figure out the partition number
577+
fi
578+
579+
NUMBER="${BASH_REMATCH[1]}"
580+
581+
# Now we know the device and partition number, get the type. This is
582+
# specific to GPT disks, MBR disks are shown differently by fdisk.
583+
TRACE "$PART_DEV is partition $NUMBER of $DEVICE"
584+
if [ "$(fdisk -l "/dev/$DEVICE" | awk '$1 == '"$NUMBER"' {print $5}')" == grub ]; then
585+
return 0
586+
fi
587+
return 1
588+
}
589+
590+
# Test if a block device could be used as /boot - we can mount it and it
591+
# contains /boot/grub* files. (Here, the block device could be a partition or
592+
# an unpartitioned device.)
593+
#
594+
# If the device is a partition, its type is also checked. Some common types
595+
# that we definitely can't mount this way are excluded to silence spurious exFAT
596+
# errors.
597+
#
598+
# Any existing /boot is unmounted. If the device is a reasonable boot device,
599+
# it's left mounted on /boot.
600+
mount_possible_boot_device() {
601+
TRACE_FUNC
602+
603+
local BOOT_DEV="$1"
604+
local PARTITION_TYPE
605+
606+
# Unmount anything on /boot. Ignore failure since there might not be
607+
# anything. If there is something mounted and we cannot unmount it for
608+
# some reason, mount will fail, which is handled.
609+
umount /boot 2>/dev/null || true
610+
611+
# Skip bios-grub partitions on GPT disks, LUKS partitions, and LVM PVs,
612+
# we can't mount these as /boot.
613+
if is_gpt_bios_grub "$BOOT_DEV" || cryptsetup isLuks "$BOOT_DEV" ||
614+
find_lvm_vg_name "$BOOT_DEV" >/dev/null; then
615+
TRACE "$BOOT_DEV is not a mountable partition for /boot"
616+
return 1
617+
fi
618+
619+
TRACE "Try mounting $BOOT_DEV as /boot"
620+
if mount -o ro "$BOOT_DEV" /boot >/dev/null 2>&1; then
621+
if ls -d /boot/grub* >/dev/null 2>&1; then
622+
# This device is a reasonable boot device
623+
return 0
624+
fi
625+
umount /boot || true
626+
fi
627+
628+
return 1
629+
}
630+
523631
# detect and set /boot device
524632
# mount /boot if successful
525633
detect_boot_device() {
526634
TRACE_FUNC
635+
local devname
527636
# unmount /boot to be safe
528637
cd / && umount /boot 2>/dev/null
529638

530639
# check $CONFIG_BOOT_DEV if set/valid
531-
if [ -e "$CONFIG_BOOT_DEV" ]; then
532-
if mount -o ro $CONFIG_BOOT_DEV /boot >/dev/null 2>&1; then
533-
if ls -d /boot/grub* >/dev/null 2>&1; then
534-
# CONFIG_BOOT_DEV is valid device and contains an installed OS
535-
return 0
536-
fi
537-
fi
640+
if [ -e "$CONFIG_BOOT_DEV" ] && mount_possible_boot_device "$CONFIG_BOOT_DEV"; then
641+
# CONFIG_BOOT_DEV is valid device and contains an installed OS
642+
return 0
538643
fi
539644

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

543-
# filter out extraneous options
544-
>/tmp/boot_device_list
648+
# Check each possible boot device
545649
for i in $(cat /tmp/disklist); do
546-
# remove block device from list if numeric partitions exist, since not bootable
547-
DEV_NUM_PARTITIONS=$(($(ls -1 $i* | wc -l) - 1))
548-
if [ ${DEV_NUM_PARTITIONS} -eq 0 ]; then
549-
echo $i >>/tmp/boot_device_list
650+
# If the device has partitions, check the partitions instead
651+
if device_has_partitions "$i"; then
652+
devname="$(basename "$i")"
653+
partitions=("/sys/class/block/$devname/$devname"?*)
550654
else
551-
ls $i* | tail -${DEV_NUM_PARTITIONS} >>/tmp/boot_device_list
655+
partitions=("$i") # Use the device itself
552656
fi
553-
done
554-
555-
# iterate thru possible options and check for grub dir
556-
for i in $(cat /tmp/boot_device_list); do
557-
umount /boot 2>/dev/null
558-
if mount -o ro $i /boot >/dev/null 2>&1; then
559-
if ls -d /boot/grub* >/dev/null 2>&1; then
560-
CONFIG_BOOT_DEV="$i"
657+
for partition in "${partitions[@]}"; do
658+
partition_dev=/dev/"$(basename "$partition")"
659+
# No sense trying something we already tried above
660+
if [ "$partition_dev" = "$CONFIG_BOOT_DEV" ]; then
661+
continue
662+
fi
663+
# If this is a reasonable boot device, select it and finish
664+
if mount_possible_boot_device "$partition_dev"; then
665+
CONFIG_BOOT_DEV="$partition_dev"
561666
return 0
562667
fi
563-
fi
668+
done
564669
done
565670

566671
# no valid boot device found
567672
echo "Unable to locate /boot files on any mounted disk"
568-
umount /boot 2>/dev/null
569673
return 1
570674
}
571675

initrd/init

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ fi
4949
# Load the date from the hardware clock, setting it in local time
5050
hwclock -l -s
5151

52+
# When mounting a filesystem, try exFAT last, since it logs errors if the
53+
# filesystem is not exFAT, and the errors go to the console. Those errors are
54+
# spurious when the medium is iso9660. By default in our config, the only
55+
# filesystem after exFAT is iso9660, move exFAT last.
56+
(grep -v '^\texfat$' /proc/filesystems && echo -e '\texfat') >/etc/filesystems
57+
5258
# Read the system configuration parameters
5359
. /etc/ash_functions
5460
. /etc/config

0 commit comments

Comments
 (0)