Initial commit
This commit is contained in:
193
scripts/drive-info
Executable file
193
scripts/drive-info
Executable file
@@ -0,0 +1,193 @@
|
||||
#!/usr/bin/env bash
|
||||
# Gathers disk info including:
|
||||
# Hardware info
|
||||
# Filesystem data
|
||||
# Btrfs array membership
|
||||
# LUKS encryption
|
||||
# SMART status
|
||||
#
|
||||
# Usage: sudo ./drive-info.sh
|
||||
#
|
||||
# Requires root privileges for complete information access
|
||||
|
||||
# Check for root privileges
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "This script must be run as root for complete information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get list of block devices (excluding loop devices, partitions, and virtual devices)
|
||||
devices=$(lsblk -dn -o NAME,TYPE | grep disk | awk '{print $1}')
|
||||
|
||||
for device in $devices; do
|
||||
dev_path="/dev/$device"
|
||||
|
||||
# Get basic size info
|
||||
size=$(lsblk -dno SIZE "$dev_path" 2>/dev/null)
|
||||
|
||||
# Get comprehensive SMART information
|
||||
smart_info=$(smartctl -i "$dev_path" 2>/dev/null)
|
||||
smart_health=$(smartctl -H "$dev_path" 2>/dev/null | grep "SMART overall-health" | awk '{print $NF}')
|
||||
smart_all=$(smartctl -A "$dev_path" 2>/dev/null)
|
||||
|
||||
# Extract model
|
||||
model=$(echo "$smart_info" | grep "Device Model:" | cut -d: -f2- | xargs)
|
||||
[[ -z "$model" ]] && model=$(echo "$smart_info" | grep "Model Number:" | cut -d: -f2- | xargs)
|
||||
[[ -z "$model" ]] && model=$(cat "/sys/block/$device/device/model" 2>/dev/null | xargs)
|
||||
|
||||
# Extract serial number
|
||||
serial=$(echo "$smart_info" | grep "Serial Number:" | cut -d: -f2- | xargs)
|
||||
[[ -z "$serial" ]] && serial=$(lsblk -dno SERIAL "$dev_path" 2>/dev/null)
|
||||
|
||||
# Extract WWN
|
||||
wwn=$(echo "$smart_info" | grep "LU WWN Device Id:" | cut -d: -f2- | xargs | sed 's/ //g')
|
||||
[[ -z "$wwn" ]] && wwn=$(lsblk -dno WWN "$dev_path" 2>/dev/null)
|
||||
|
||||
# Extract rotation rate
|
||||
rpm=$(echo "$smart_info" | grep "Rotation Rate:" | cut -d: -f2- | xargs)
|
||||
if [[ -z "$rpm" || "$rpm" == "Solid State Device" ]]; then
|
||||
rot=$(cat "/sys/block/$device/queue/rotational" 2>/dev/null)
|
||||
[[ "$rot" == "0" ]] && rpm="SSD"
|
||||
fi
|
||||
|
||||
# Extract form factor
|
||||
form_factor=$(echo "$smart_info" | grep "Form Factor:" | cut -d: -f2- | xargs)
|
||||
|
||||
# Extract interface and link speed
|
||||
interface=$(echo "$smart_info" | grep "SATA Version" | cut -d: -f2- | xargs)
|
||||
[[ -z "$interface" ]] && interface=$(echo "$smart_info" | grep "Transport protocol:" | cut -d: -f2- | xargs)
|
||||
[[ -z "$interface" ]] && interface=$(echo "$smart_info" | grep "NVMe Version:" | cut -d: -f2- | xargs | awk '{print "NVMe " $1}')
|
||||
|
||||
# Extract temperature
|
||||
temp=$(echo "$smart_all" | grep -i "Temperature" | head -1 | awk '{print $10}')
|
||||
[[ -n "$temp" ]] && temp="${temp}°C"
|
||||
|
||||
# Extract power-on hours
|
||||
power_hours=$(echo "$smart_all" | grep "Power_On_Hours" | awk '{print $10}')
|
||||
[[ -z "$power_hours" ]] && power_hours=$(echo "$smart_all" | grep "Power On Hours" | awk '{print $3}')
|
||||
|
||||
# Get disk ID
|
||||
disk_id=""
|
||||
for f in /dev/disk/by-id/*; do
|
||||
[[ -e "$f" ]] || continue
|
||||
# resolve symlink target and compare basename to device, skip entries that reference partitions
|
||||
target=$(readlink -f "$f" 2>/dev/null) || continue
|
||||
if [[ "$(basename "$target")" == "$device" && "$f" != *part* ]]; then
|
||||
disk_id=$(basename "$f")
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Get filesystem UUID
|
||||
uuid=$(lsblk -no UUID "$dev_path" 2>/dev/null | head -1)
|
||||
[[ -z "$uuid" ]] && uuid=$(lsblk -no UUID "${dev_path}1" 2>/dev/null)
|
||||
|
||||
# Check for LUKS encryption
|
||||
luks_uuid=""
|
||||
luks_mapper=""
|
||||
if cryptsetup isLuks "$dev_path" 2>/dev/null; then
|
||||
luks_uuid=$(cryptsetup luksUUID "$dev_path" 2>/dev/null)
|
||||
for mapper in /dev/mapper/luks-*; do
|
||||
[[ -e "$mapper" ]] || continue
|
||||
mapper_name=$(basename "$mapper")
|
||||
[[ "$mapper_name" == "luks-$luks_uuid" ]] && luks_mapper="$mapper_name" && break
|
||||
done
|
||||
fi
|
||||
|
||||
# Get partition table type
|
||||
ptable=$(blkid -p -s PTTYPE "$dev_path" 2>/dev/null | grep -oP 'PTTYPE="\K[^"]+')
|
||||
[[ -z "$ptable" ]] && ptable="none"
|
||||
|
||||
# Get initial mount point
|
||||
mount_point=$(findmnt -no TARGET "$dev_path" 2>/dev/null | head -1)
|
||||
if [[ -z "$mount_point" && -n "$luks_mapper" ]]; then
|
||||
mount_point=$(findmnt -no TARGET "/dev/mapper/$luks_mapper" 2>/dev/null | head -1)
|
||||
fi
|
||||
|
||||
# Get HBA information
|
||||
hba_info=""
|
||||
if [[ -L "/sys/block/$device" ]]; then
|
||||
dev_path_sys=$(readlink -f "/sys/block/$device")
|
||||
|
||||
# Exclude USB, virtual, and NVMe devices from HBA detection
|
||||
if [[ ! "$dev_path_sys" =~ (usb|virtual|nvme) ]]; then
|
||||
phy=$(echo "$dev_path_sys" | grep -oP 'phy-\K[0-9]+' | head -1)
|
||||
port=$(echo "$dev_path_sys" | grep -oP 'port-\K[0-9]+' | head -1)
|
||||
target=$(echo "$dev_path_sys" | grep -oP 'target\K[0-9:]+' | head -1)
|
||||
|
||||
# Find the actual storage controller in the PCI chain
|
||||
mapfile -t pci_addrs < <(echo "$dev_path_sys" | grep -oP '\d+:\d+:\d+\.\d+')
|
||||
for addr in "${pci_addrs[@]}"; do
|
||||
desc=$(lspci -s "$addr" 2>/dev/null | cut -d: -f3-)
|
||||
if [[ "$desc" =~ (SAS|SATA|RAID|HBA|LSI|Adaptec|AHCI) ]]; then
|
||||
pci_addr="$addr"
|
||||
pci_desc="$desc"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Build HBA info string
|
||||
if [[ -n "$pci_addr" ]]; then
|
||||
hba_info="PCI: $pci_addr ($pci_desc)"
|
||||
[[ -n "$phy" ]] && hba_info="$hba_info | PHY: $phy"
|
||||
[[ -n "$port" ]] && hba_info="$hba_info | Port: $port"
|
||||
[[ -n "$target" ]] && hba_info="$hba_info | Target: $target"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get Btrfs information
|
||||
btrfs_label=""
|
||||
btrfs_uuid=""
|
||||
btrfs_devid=""
|
||||
|
||||
# Check device or its LUKS mapper for btrfs
|
||||
check_dev="$dev_path"
|
||||
if [[ -n "$luks_mapper" ]]; then
|
||||
check_dev="/dev/mapper/$luks_mapper"
|
||||
fi
|
||||
|
||||
btrfs_show=$(btrfs filesystem show "$check_dev" 2>/dev/null)
|
||||
if btrfs filesystem show "$check_dev" &>/dev/null; then
|
||||
btrfs_label=$(echo "$btrfs_show" | head -1 | grep -oP "Label: '\K[^']+")
|
||||
btrfs_uuid=$(echo "$btrfs_show" | head -1 | grep -oP "uuid: \K[a-f0-9-]+")
|
||||
btrfs_devid=$(echo "$btrfs_show" | grep -E "(${check_dev}|${dev_path})" | grep -oP "devid\s+\K[0-9]+" | head -1)
|
||||
|
||||
# If not mounted, check if any other device in the btrfs array is mounted
|
||||
if [[ -z "$mount_point" && -n "$btrfs_uuid" ]]; then
|
||||
all_devs=$(echo "$btrfs_show" | grep "path" | grep -oP "path \K[^ ]+")
|
||||
for btrfs_dev in $all_devs; do
|
||||
mount_point=$(findmnt -no TARGET "$btrfs_dev" 2>/dev/null | head -1)
|
||||
[[ -n "$mount_point" ]] && break
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Default mount point if still empty
|
||||
[[ -z "$mount_point" ]] && mount_point="Not mounted"
|
||||
|
||||
# Text output
|
||||
echo "╔════════════════════════════════════════╗"
|
||||
echo "║ Device: $dev_path"
|
||||
echo "╚════════════════════════════════════════╝"
|
||||
echo "Model: $model"
|
||||
echo "Serial: $serial"
|
||||
echo "WWN: $wwn"
|
||||
echo "Size: $size"
|
||||
echo "Rotation: $rpm"
|
||||
echo "Form Factor: $form_factor"
|
||||
echo "Interface: $interface"
|
||||
echo "Disk ID: $disk_id"
|
||||
echo "Filesystem UUID: $uuid"
|
||||
echo "LUKS UUID: $luks_uuid"
|
||||
echo "Partition Table: $ptable"
|
||||
echo "Mount: $mount_point"
|
||||
echo "HBA Info: $hba_info"
|
||||
echo "SMART Health: $smart_health"
|
||||
echo "Temperature: $temp"
|
||||
echo "Power On Hours: $power_hours"
|
||||
echo "Btrfs Label: $btrfs_label"
|
||||
echo "Btrfs UUID: $btrfs_uuid"
|
||||
echo "Btrfs devid: $btrfs_devid"
|
||||
echo
|
||||
done
|
||||
Reference in New Issue
Block a user