Cache lsblk output to reduce redundant calls

Instead of calling lsblk twice per device (once for size, once for
mount points), now performs a single lsblk call at start and caches:
- LSBLK_SIZE: Device sizes
- LSBLK_MOUNTS: Mount points (accumulated for partitions)

This reduces the number of subprocess calls significantly,
especially on systems with many drives.

Fixes: #16

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-05 11:41:31 -05:00
parent 05d7fa7e37
commit b61a9305ab

View File

@@ -856,6 +856,25 @@ done
# Combine numeric bays (sorted numerically) with m2 slots (sorted alphanumerically) # Combine numeric bays (sorted numerically) with m2 slots (sorted alphanumerically)
all_bays=$(printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^[0-9]+$' | sort -n; printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^m2-' | sort) all_bays=$(printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^[0-9]+$' | sort -n; printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^m2-' | sort)
# Cache lsblk data to reduce redundant calls
# Single call gets all info we need: size and mount points
declare -A LSBLK_SIZE=()
declare -A LSBLK_MOUNTS=()
log_info "Caching block device information..."
while IFS='|' read -r name size mounts; do
[[ -z "$name" ]] && continue
LSBLK_SIZE[$name]="$size"
# Accumulate mount points for parent device
parent="${name%%[0-9]}" # Strip partition number
if [[ -n "$mounts" ]]; then
if [[ -n "${LSBLK_MOUNTS[$parent]}" ]]; then
LSBLK_MOUNTS[$parent]+=",${mounts}"
else
LSBLK_MOUNTS[$parent]="$mounts"
fi
fi
done < <(lsblk -rn -o NAME,SIZE,MOUNTPOINT 2>/dev/null)
# Parallel SMART data collection for faster execution # Parallel SMART data collection for faster execution
# Collect SMART data in background jobs, store in temp files # Collect SMART data in background jobs, store in temp files
if [[ "$SKIP_SMART" != true ]]; then if [[ "$SKIP_SMART" != true ]]; then
@@ -878,7 +897,8 @@ fi
for bay in $all_bays; do for bay in $all_bays; do
device="${DRIVE_MAP[$bay]}" device="${DRIVE_MAP[$bay]}"
if [[ -n "$device" && "$device" != "EMPTY" && -b "/dev/$device" ]]; then if [[ -n "$device" && "$device" != "EMPTY" && -b "/dev/$device" ]]; then
size="$(lsblk -d -n -o SIZE "/dev/$device" 2>/dev/null)" # Use cached lsblk data
size="${LSBLK_SIZE[$device]:-}"
# Get SMART info from cache (or defaults if skipped) # Get SMART info from cache (or defaults if skipped)
if [[ "$SKIP_SMART" == true ]]; then if [[ "$SKIP_SMART" == true ]]; then
@@ -914,11 +934,12 @@ for bay in $all_bays; do
fi fi
fi fi
# Check mount points using lsblk (includes partitions) # Check mount points using cached lsblk data
# This catches both whole-device mounts and partition mounts (e.g., /dev/sda1) # This includes both whole-device mounts and partition mounts
usage="-" usage="-"
mount_points="$(lsblk -n -o MOUNTPOINT "/dev/$device" 2>/dev/null | grep -v '^$' | head -3 | tr '\n' ',')" mount_points="${LSBLK_MOUNTS[$device]:-}"
mount_points="${mount_points%,}" # Remove trailing comma # Limit to first 3 mount points for display
mount_points="$(echo "$mount_points" | tr ',' '\n' | head -3 | tr '\n' ',' | sed 's/,$//')"
if [[ -n "$mount_points" ]]; then if [[ -n "$mount_points" ]]; then
if [[ "$mount_points" == *"/"* && ! "$mount_points" == *"/boot"* && ! "$mount_points" == *"/home"* ]]; then if [[ "$mount_points" == *"/"* && ! "$mount_points" == *"/boot"* && ! "$mount_points" == *"/home"* ]]; then
# Root filesystem mounted (but not just /boot or /home) # Root filesystem mounted (but not just /boot or /home)