@@ -822,6 +822,47 @@ device_has_partitions() {
822822 return 0
823823}
824824
825+ # Build displayable disk information using sysfs (vs current BusyBox's 2TB limit per https://bugs.busybox.net/show_bug.cgi?id=16276)
826+ # Output format: "Disk /dev/<name>: <SIZE> GB/TB" per line
827+ # (GB for smaller disks, TB for disks >= 1000 GB)
828+ # The /sys/block/*/size entry is always counted in 512‑byte sectors, so
829+ # calculate using bytes from blockdev when available or multiply by 512.
830+ disk_info_sysfs () {
831+ TRACE_FUNC
832+ local disk_info=" "
833+ for dev in /sys/block/sd* /sys/block/nvme* /sys/block/vd* /sys/block/hd* ; do
834+ if [ -e " $dev " ]; then
835+ # ignore partition entries (they contain a 'partition' file)
836+ if [ -e " $dev /partition" ]; then
837+ continue
838+ fi
839+ local devname=$( basename " $dev " )
840+ local size_bytes=" "
841+ if command -v blockdev > /dev/null 2>&1 ; then
842+ size_bytes=$( blockdev --getsize64 " /dev/${devname} " 2> /dev/null)
843+ fi
844+ if [ -z " $size_bytes " ] || ! [ " $size_bytes " -gt 0 ] 2> /dev/null; then
845+ local size_sectors_512=$( cat " $dev /size" 2> /dev/null)
846+ if [ -n " $size_sectors_512 " ] && [ " $size_sectors_512 " -gt 0 ] 2> /dev/null; then
847+ size_bytes=$(( size_sectors_512 * 512 ))
848+ fi
849+ fi
850+ if [ -n " $size_bytes " ] && [ " $size_bytes " -gt 0 ] 2> /dev/null; then
851+ local size_gb=$(( (size_bytes + 500000000 ) / 1000000000 ))
852+ # show TB when size is at least 1,000,000,000,000 bytes (≈1000 GB) for better UX
853+ if [ " $size_bytes " -ge 1000000000000 ]; then
854+ local size_tb=$(( (size_bytes + 500000000000 ) / 1000000000000 ))
855+ printf -v disk_info " %sDisk /dev/%s: %s TB\n" " $disk_info " " $devname " " $size_tb "
856+ else
857+ printf -v disk_info " %sDisk /dev/%s: %s GB\n" " $disk_info " " $devname " " $size_gb "
858+ fi
859+ fi
860+ fi
861+ done
862+ # trim trailing newline so callers don't get an extra blank line
863+ printf " %s" " ${disk_info% $' \n ' } "
864+ }
865+
825866list_usb_storage () {
826867 TRACE_FUNC
827868 # List all USB storage devices, including partitions unless we received argument stating we want drives only
@@ -1240,12 +1281,12 @@ find_lvm_vg_name() {
12401281 DEVICE=" $1 "
12411282
12421283 mkdir -p /tmp/root-hashes-gui
1243- if ! lvm pvs " $DEVICE " > /tmp/root-hashes-gui/lvm_vg 2> /dev/null; then
1284+ if ! lvm pvs --noheadings -o vg_name " $DEVICE " > /tmp/root-hashes-gui/lvm_vg 2> /dev/null; then
12441285 # It's not an LVM PV
12451286 return 1
12461287 fi
12471288
1248- VG=" $( tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk ' {print $2} ' ) "
1289+ VG=" $( awk ' NF {print $1; exit} ' /tmp/root-hashes-gui/lvm_vg) "
12491290 if [ -z " $VG " ]; then
12501291 DEBUG " Could not find LVM2 VG from lvm pvs output:"
12511292 DEBUG " $( cat /tmp/root-hashes-gui/lvm_vg) "
@@ -1259,29 +1300,37 @@ find_lvm_vg_name() {
12591300# GPT-partitioned disk.
12601301is_gpt_bios_grub () {
12611302 TRACE_FUNC
1303+ # $1 is the device path being tested (e.g. /dev/vda1)
1304+ local PART_DEV=" $1 "
1305+ DEBUG " PART_DEV=$PART_DEV "
1306+
1307+ # identify the base device and partition number using shell parameter expansion
1308+ local partname device number
1309+ partname=$( basename " $PART_DEV " )
1310+
1311+ # Split trailing digits from the base device name.
1312+ number=" ${partname##* [!0-9]} "
1313+ if [ -z " $number " ]; then
1314+ DEBUG " cannot parse partition name '$partname '"
1315+ return 1 # not a recognised partition
1316+ fi
12621317
1263- local PART_DEV=" $1 " DEVICE NUMBER
1264-
1265- # Figure out the partitioned device containing this device (if there is
1266- # one) from /sys/class/block.
1267- local DEVICE_MATCHES=(" /sys/class/block/" * " /$( basename " $PART_DEV " ) " )
1268-
1269- DEVICE=" $( echo " ${DEVICE_MATCHES[0]} " | cut -d/ -f5) "
1270- if [ " ${# DEVICE_MATCHES[@]} " -ne 1 ] || [ " $DEVICE " = " *" ]; then
1271- return 0
1318+ device=" ${partname% " $number " } "
1319+ # nvme/mmc names include an extra 'p' separator before the partition
1320+ # number (e.g. nvme0n1p2, mmcblk0p1). Remove only that separator.
1321+ if [[ " $device " == * p && " ${device% p} " == * [0-9] ]]; then
1322+ device=" ${device% p} "
12721323 fi
12731324
1274- # Extract the partition number
1275- if ! [[ $( basename " $PART_DEV " ) =~ ([0-9]+)$ ]] ; then
1276- return 0 # Can't figure out the partition number
1325+ if [ -z " $device " ] ; then
1326+ DEBUG " cannot parse partition device from ' $partname ' "
1327+ return 1
12771328 fi
12781329
1279- NUMBER=" ${BASH_REMATCH[1]} "
1330+ DEBUG " DEVICE= $device NUMBER=$number "
12801331
1281- # Now we know the device and partition number, get the type. This is
1282- # specific to GPT disks, MBR disks are shown differently by fdisk.
1283- TRACE " $PART_DEV is partition $NUMBER of $DEVICE "
1284- if [ " $( fdisk -l " /dev/$DEVICE " 2> /dev/null | awk ' $1 == ' " $NUMBER " ' {print $5}' ) " == grub ]; then
1332+ # GPT disks list type in column 5; fall through to 1 otherwise
1333+ if [ " $( fdisk -l " /dev/$device " 2> /dev/null | awk ' $1 == ' " $number " ' {print $5}' ) " == grub ]; then
12851334 return 0
12861335 fi
12871336 return 1
@@ -1310,9 +1359,17 @@ mount_possible_boot_device() {
13101359
13111360 # Skip bios-grub partitions on GPT disks, LUKS partitions, and LVM PVs,
13121361 # we can't mount these as /boot.
1313- if is_gpt_bios_grub " $BOOT_DEV " || cryptsetup isLuks " $BOOT_DEV " ||
1314- find_lvm_vg_name " $BOOT_DEV " > /dev/null; then
1315- TRACE " $BOOT_DEV is not a mountable partition for /boot"
1362+ # Skip partitions we definitely can't mount for /boot. Log each reason.
1363+ if is_gpt_bios_grub " $BOOT_DEV " ; then
1364+ DEBUG " $BOOT_DEV is GPT BIOS/GRUB partition, skipping"
1365+ return 1
1366+ fi
1367+ if cryptsetup isLuks " $BOOT_DEV " ; then
1368+ DEBUG " $BOOT_DEV is a LUKS volume, skipping"
1369+ return 1
1370+ fi
1371+ if find_lvm_vg_name " $BOOT_DEV " > /dev/null; then
1372+ DEBUG " $BOOT_DEV is an LVM PV, skipping"
13161373 return 1
13171374 fi
13181375
@@ -1343,7 +1400,17 @@ mount_possible_boot_device() {
13431400# mount /boot if successful
13441401detect_boot_device () {
13451402 TRACE_FUNC
1346- local devname
1403+ local devname mounted_boot_dev
1404+ DEBUG " CONFIG_BOOT_DEV=$CONFIG_BOOT_DEV "
1405+ # If /boot is already mounted and appears to be a valid boot tree, just
1406+ # use its device. This avoids remount churn and makes the later lookup
1407+ # fast.
1408+ mounted_boot_dev=" $( awk ' $2=="/boot" {print $1; exit}' /proc/mounts) "
1409+ if [ -n " $mounted_boot_dev " ] && ls -d /boot/grub* > /dev/null 2>&1 ; then
1410+ CONFIG_BOOT_DEV=" $mounted_boot_dev "
1411+ DEBUG " Using already-mounted /boot device as CONFIG_BOOT_DEV=$CONFIG_BOOT_DEV "
1412+ return 0
1413+ fi
13471414 # unmount /boot to be safe
13481415 cd / && umount /boot 2> /dev/null
13491416
@@ -1381,6 +1448,7 @@ detect_boot_device() {
13811448
13821449 # no valid boot device found
13831450 echo " Unable to locate /boot files on any mounted disk"
1451+ DEBUG " detect_boot_device: failed to find a bootable device"
13841452 return 1
13851453}
13861454
0 commit comments