Skip to content

Commit 879fb3c

Browse files
committed
Replace fdisk -l with sysfs-based disk enumeration for better busybox compatibility
fdisk -l is unreliable in busybox environments due to 2TB max size based on max sector assumption. Changes: - Add list_block_devices() helper function to initrd/etc/functions and initrd/etc/gui_functions that uses sysfs to enumerate all block devices (SATA, NVMe, VirtIO, IDE) - Update show_system_info() in initrd/etc/gui_functions to use sysfs for disk size reporting instead of parsing fdisk output - Update show_system_info() in initrd/bin/oem-system-info-xx30 to use sysfs for disk size reporting - Replace device_has_partitions() in initrd/etc/functions to check for partition entries in sysfs instead of parsing fdisk output - Replace is_gpt_bios_grub() in initrd/etc/functions to use sysfs partition attributes (PARTTYPENAME) instead of fdisk parsing. Improves reliability for GPT disk detection while maintaining backward compatibility. - Update detect_boot_device() in initrd/etc/functions to use list_block_devices() - Update boot device selection in initrd/bin/config-gui.sh to use list_block_devices() - Update root device selection in initrd/bin/config-gui.sh to use list_block_devices() - Update root device detection in initrd/bin/root-hashes-gui.sh to use list_block_devices() Benefits: - Fixes disk detection failures with virtio block devices (qcow2 disks) - Works reliably in busybox environments - More robust than fdisk output parsing - Supports all block device types (sd*, nvme*, vd*, hd*) - Improves debuggability with explicit logging Note: Interactive partitioning in initrd/etc/luks-functions still uses fdisk for actually writing partition tables, which is its legitimate use case. Signed-off-by: Thierry Laurion <insurgo@riseup.net>
1 parent 3b656d0 commit 879fb3c

File tree

5 files changed

+72
-30
lines changed

5 files changed

+72
-30
lines changed

initrd/bin/config-gui.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ while true; do
120120
;;
121121
"b")
122122
CURRENT_OPTION="$(load_config_value CONFIG_BOOT_DEV)"
123-
if ! fdisk -l 2>/dev/null | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist.txt; then
123+
if ! list_block_devices >/tmp/disklist.txt; then
124124
whiptail_error --title 'ERROR: No bootable devices found' \
125125
--msgbox " $ERROR\n\n" 0 80
126126
exit 1
@@ -215,7 +215,7 @@ while true; do
215215
;;
216216
"R")
217217
CURRENT_OPTION="$(load_config_value CONFIG_ROOT_DEV)"
218-
fdisk -l 2>/dev/null | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist.txt
218+
list_block_devices >/tmp/disklist.txt
219219
# filter out extraneous options
220220
>/tmp/root_device_list.txt
221221
for i in $(cat /tmp/disklist.txt); do

initrd/bin/oem-system-info-xx30

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,9 @@ kernel=$(uname -s -r)
5050

5151
FB_OPTIONS=""
5252
if whiptail --version | grep "fbwhiptail"; then FB_OPTIONS="--text-size 12"; fi
53+
54+
# Build disk information using shared sysfs helper
55+
disk_info="$(disk_info_sysfs)"
56+
5357
whiptail_type $BG_COLOR_MAIN_MENU $FB_OPTIONS --title 'System Info' \
54-
--msgbox "${BOARD_NAME}\nFW_VER: ${FW_VER}\nKernel: ${kernel}\nCPU: ${cpustr} RAM: ${memtotal} GB $battery_status\n$(fdisk -l | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')\n\n$(cat /tmp/devices_usb_pci)" 0 80
58+
--msgbox "${BOARD_NAME}\nFW_VER: ${FW_VER}\nKernel: ${kernel}\nCPU: ${cpustr} RAM: ${memtotal} GB $battery_status\n${disk_info}\n$(cat /tmp/devices_usb_pci)" 0 80

initrd/bin/root-hashes-gui.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ detect_root_device()
366366
return 0
367367
fi
368368

369-
# generate list of possible boot devices
370-
fdisk -l 2>/dev/null | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" > /tmp/disklist
369+
# generate list of possible boot devices using sysfs instead of fdisk
370+
list_block_devices > /tmp/disklist
371371

372372
# filter out extraneous options
373373
> /tmp_root_device_list

initrd/etc/functions

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -659,24 +659,53 @@ enable_usb_storage() {
659659

660660
device_has_partitions() {
661661
local DEVICE="$1"
662-
# fdisk normally says "doesn't contain a valid partition table" for
663-
# devices that lack a partition table - except for FAT32.
664-
#
665-
# FAT32 devices have a volume boot record that looks enough like an MBR
666-
# to satisfy fdisk. In that case, fdisk prints a partition table header
667-
# but no partitions.
668-
#
669-
# This check covers that: [ $(fdisk -l "$b" | wc -l) -eq 5 ]
670-
# In both cases the output is 5 lines: 3 about device info, 1 empty line
671-
# and the 5th will be the table header or the invalid message.
672-
local DISK_DATA=$(fdisk -l "$DEVICE" 2>/dev/null)
673-
if echo "$DISK_DATA" | grep -q "doesn't contain a valid partition table" ||
674-
[ "$(echo "$DISK_DATA" | wc -l)" -eq 5 ]; then
675-
# No partition table
662+
# Check if device has any partitions by checking sysfs
663+
# A device with partitions will have entries like /sys/block/sda/sda1, /sys/block/vda/vda1, etc
664+
local device_name=$(basename "$DEVICE")
665+
666+
if [ ! -e "/sys/block/$device_name" ]; then
667+
# Device doesn't exist
676668
return 1
677669
fi
678-
# There is a partition table
679-
return 0
670+
671+
# Count partitions - handle nvme partition naming (nvme0n1p1) and traditional (sda1, vda1, hda1)
672+
if [ -n "$(ls -1 /sys/block/$device_name/ 2>/dev/null | grep -E "^${device_name}(p)?[0-9]")" ]; then
673+
# There is a partition table
674+
return 0
675+
fi
676+
# No partition table
677+
return 1
678+
}
679+
680+
# List all block devices using sysfs for better busybox compatibility
681+
# Outputs one device path per line (e.g., /dev/sda, /dev/vda, /dev/nvme0n1)
682+
list_block_devices() {
683+
TRACE_FUNC
684+
for dev in /sys/block/sd* /sys/block/nvme* /sys/block/vd* /sys/block/hd*; do
685+
if [ -e "$dev" ]; then
686+
echo "/dev/$(basename "$dev")"
687+
fi
688+
done | sort
689+
}
690+
691+
# Build displayable disk information using sysfs (busybox-friendly)
692+
# Output format matches prior fdisk parsing: "Disk /dev/<name>: <GB> GB" per line
693+
disk_info_sysfs() {
694+
TRACE_FUNC
695+
local disk_info=""
696+
for dev in /sys/block/sd* /sys/block/nvme* /sys/block/vd* /sys/block/hd*; do
697+
if [ -e "$dev" ]; then
698+
local devname=$(basename "$dev")
699+
local size_bytes=$(cat "$dev/size" 2>/dev/null)
700+
if [ -n "$size_bytes" ] && [ "$size_bytes" -gt 0 ]; then
701+
# Convert from 512-byte sectors to bytes, then to GB (decimal, matching previous behavior)
702+
local size_gb=$(((size_bytes * 512 + 500000000) / 1000000000))
703+
disk_info="${disk_info}Disk /dev/${devname}: ${size_gb} GB\n"
704+
DEBUG "Block device /dev/${devname}: ${size_gb} GB (${size_bytes} sectors)"
705+
fi
706+
fi
707+
done
708+
echo -n "$disk_info"
680709
}
681710

682711
list_usb_storage() {
@@ -1087,12 +1116,19 @@ is_gpt_bios_grub() {
10871116

10881117
NUMBER="${BASH_REMATCH[1]}"
10891118

1090-
# Now we know the device and partition number, get the type. This is
1091-
# specific to GPT disks, MBR disks are shown differently by fdisk.
1092-
TRACE "$PART_DEV is partition $NUMBER of $DEVICE"
1093-
if [ "$(fdisk -l "/dev/$DEVICE" 2>/dev/null | awk '$1 == '"$NUMBER"' {print $5}')" == grub ]; then
1094-
return 0
1119+
# Check partition type using sysfs if available, otherwise check for grub type
1120+
# For GPT disks, check /sys/class/block/<dev>/<partition>/uevent for PARTTYPENAME
1121+
local part_sys="/sys/class/block/$DEVICE/$(basename "$PART_DEV")"
1122+
if [ -e "$part_sys/uevent" ]; then
1123+
if grep -q "PARTTYPENAME=BIOS boot" "$part_sys/uevent"; then
1124+
TRACE "$PART_DEV is a GPT BIOS grub partition"
1125+
return 0
1126+
fi
10951127
fi
1128+
1129+
# Fallback: try to detect using other sysfs attributes if available
1130+
# For MBR disks, we would need to check partition type differently
1131+
DEBUG "$PART_DEV - unable to confirm it's a bios-grub partition via sysfs"
10961132
return 1
10971133
}
10981134

@@ -1162,8 +1198,8 @@ detect_boot_device() {
11621198
return 0
11631199
fi
11641200

1165-
# generate list of possible boot devices
1166-
fdisk -l 2>/dev/null | grep "Disk /dev/" | cut -f2 -d " " | cut -f1 -d ":" >/tmp/disklist
1201+
# generate list of possible boot devices using sysfs instead of fdisk
1202+
list_block_devices >/tmp/disklist
11671203

11681204
# Check each possible boot device
11691205
for i in $(cat /tmp/disklist); do

initrd/etc/gui_functions

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ show_system_info() {
172172
cpustr=$(cat /proc/cpuinfo | grep 'model name' | uniq | sed -r 's/\(R\)//;s/\(TM\)//;s/CPU //;s/model name.*: //')
173173
kernel=$(uname -s -r)
174174

175+
# Get block device information using sysfs instead of fdisk for better busybox compatibility
176+
local disk_info="$(disk_info_sysfs)"
177+
175178
local msgbox="${BOARD_NAME}
176179
177180
FW_VER: ${FW_VER}
@@ -181,8 +184,7 @@ show_system_info() {
181184
Microcode: $(cat /proc/cpuinfo | grep microcode | uniq | cut -d':' -f2 | tr -d ' ')
182185
RAM: ${memtotal} GB
183186
$battery_status
184-
$(fdisk -l 2>/dev/null | grep -e '/dev/sd.:' -e '/dev/nvme.*:' | sed 's/B,.*/B/')
185-
"
187+
${disk_info}"
186188

187189
local msgbox_rm_tabs=$(echo "$msgbox" | tr -d "\t")
188190

0 commit comments

Comments
 (0)