@@ -822,6 +822,46 @@ 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+ printf " %s" " $disk_info "
863+ }
864+
825865list_usb_storage () {
826866 TRACE_FUNC
827867 # List all USB storage devices, including partitions unless we received argument stating we want drives only
@@ -1240,12 +1280,12 @@ find_lvm_vg_name() {
12401280 DEVICE=" $1 "
12411281
12421282 mkdir -p /tmp/root-hashes-gui
1243- if ! lvm pvs " $DEVICE " > /tmp/root-hashes-gui/lvm_vg 2> /dev/null; then
1283+ if ! lvm pvs --noheadings -o vg_name " $DEVICE " > /tmp/root-hashes-gui/lvm_vg 2> /dev/null; then
12441284 # It's not an LVM PV
12451285 return 1
12461286 fi
12471287
1248- VG=" $( tail -n +2 /tmp/root-hashes-gui/lvm_vg | awk ' {print $2} ' ) "
1288+ VG=" $( awk ' NF {print $1; exit} ' /tmp/root-hashes-gui/lvm_vg) "
12491289 if [ -z " $VG " ]; then
12501290 DEBUG " Could not find LVM2 VG from lvm pvs output:"
12511291 DEBUG " $( cat /tmp/root-hashes-gui/lvm_vg) "
@@ -1259,29 +1299,37 @@ find_lvm_vg_name() {
12591299# GPT-partitioned disk.
12601300is_gpt_bios_grub () {
12611301 TRACE_FUNC
1302+ # $1 is the device path being tested (e.g. /dev/vda1)
1303+ local PART_DEV=" $1 "
1304+ DEBUG " PART_DEV=$PART_DEV "
1305+
1306+ # identify the base device and partition number with a regex
1307+ local partname device number
1308+ partname=$( basename " $PART_DEV " )
1309+
1310+ # Split trailing digits from the base device name.
1311+ number=" ${partname##* [!0-9]} "
1312+ if [ -z " $number " ]; then
1313+ DEBUG " cannot parse partition name '$partname '"
1314+ return 1 # not a recognised partition
1315+ fi
12621316
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
1317+ device=" ${partname% " $number " } "
1318+ # nvme/mmc names include an extra 'p' separator before the partition
1319+ # number (e.g. nvme0n1p2, mmcblk0p1). Remove only that separator.
1320+ if [[ " $device " == * p && " ${device% p} " == * [0-9] ]]; then
1321+ device=" ${device% p} "
12721322 fi
12731323
1274- # Extract the partition number
1275- if ! [[ $( basename " $PART_DEV " ) =~ ([0-9]+)$ ]] ; then
1276- return 0 # Can't figure out the partition number
1324+ if [ -z " $device " ] ; then
1325+ DEBUG " cannot parse partition device from ' $partname ' "
1326+ return 1
12771327 fi
12781328
1279- NUMBER=" ${BASH_REMATCH[1]} "
1329+ DEBUG " DEVICE= $device NUMBER=$number "
12801330
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
1331+ # GPT disks list type in column 5; fall through to 1 otherwise
1332+ if [ " $( fdisk -l " /dev/$device " 2> /dev/null | awk ' $1 == ' " $number " ' {print $5}' ) " == grub ]; then
12851333 return 0
12861334 fi
12871335 return 1
@@ -1310,9 +1358,17 @@ mount_possible_boot_device() {
13101358
13111359 # Skip bios-grub partitions on GPT disks, LUKS partitions, and LVM PVs,
13121360 # 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"
1361+ # Skip partitions we definitely can't mount for /boot. Log each reason.
1362+ if is_gpt_bios_grub " $BOOT_DEV " ; then
1363+ DEBUG " $BOOT_DEV is GPT BIOS/GRUB partition, skipping"
1364+ return 1
1365+ fi
1366+ if cryptsetup isLuks " $BOOT_DEV " ; then
1367+ DEBUG " $BOOT_DEV is a LUKS volume, skipping"
1368+ return 1
1369+ fi
1370+ if find_lvm_vg_name " $BOOT_DEV " > /dev/null; then
1371+ DEBUG " $BOOT_DEV is an LVM PV, skipping"
13161372 return 1
13171373 fi
13181374
@@ -1343,7 +1399,17 @@ mount_possible_boot_device() {
13431399# mount /boot if successful
13441400detect_boot_device () {
13451401 TRACE_FUNC
1346- local devname
1402+ local devname mounted_boot_dev
1403+ DEBUG " CONFIG_BOOT_DEV=$CONFIG_BOOT_DEV "
1404+ # If /boot is already mounted and appears to be a valid boot tree, just
1405+ # use its device. This avoids remount churn and makes the later lookup
1406+ # fast.
1407+ mounted_boot_dev=" $( awk ' $2=="/boot" {print $1; exit}' /proc/mounts) "
1408+ if [ -n " $mounted_boot_dev " ] && ls -d /boot/grub* > /dev/null 2>&1 ; then
1409+ CONFIG_BOOT_DEV=" $mounted_boot_dev "
1410+ DEBUG " Using already-mounted /boot device as CONFIG_BOOT_DEV=$CONFIG_BOOT_DEV "
1411+ return 0
1412+ fi
13471413 # unmount /boot to be safe
13481414 cd / && umount /boot 2> /dev/null
13491415
@@ -1381,6 +1447,7 @@ detect_boot_device() {
13811447
13821448 # no valid boot device found
13831449 echo " Unable to locate /boot files on any mounted disk"
1450+ DEBUG " detect_boot_device: failed to find a bootable device"
13841451 return 1
13851452}
13861453
0 commit comments