2024-12-09 21:59:32 -05:00
|
|
|
#!/bin/bash
|
|
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
#==============================================================================
|
|
|
|
|
# Drive Atlas - Server Drive Mapping Tool
|
|
|
|
|
# Maps physical drive bays to logical device names using PCI paths
|
|
|
|
|
#==============================================================================
|
2025-03-01 11:58:15 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Chassis Type Definitions
|
|
|
|
|
# These define the physical layout and display formatting for each chassis type
|
|
|
|
|
#------------------------------------------------------------------------------
|
2025-03-01 11:58:15 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
generate_10bay_layout() {
|
|
|
|
|
local hostname=$1
|
|
|
|
|
build_drive_map
|
2025-03-01 11:58:15 -05:00
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
# Fixed width for consistent box drawing (fits device names like "nvme0n1")
|
|
|
|
|
local drive_width=10
|
2026-01-06 15:52:24 -05:00
|
|
|
|
|
|
|
|
# Main chassis section
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐\n"
|
|
|
|
|
printf "│ %-126s │\n" "$hostname - 10-Bay Hot-swap Chassis"
|
|
|
|
|
printf "│ │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
|
|
|
|
|
# M.2 NVMe slot if present
|
|
|
|
|
if [[ -n "${DRIVE_MAP[m2-1]}" ]]; then
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "│ M.2 NVMe: %-10s │\n" "${DRIVE_MAP[m2-1]}"
|
|
|
|
|
printf "│ │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
fi
|
|
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "│ Front Hot-swap Bays: │\n"
|
|
|
|
|
printf "│ │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
# Bay top borders
|
|
|
|
|
printf "│ "
|
2026-01-06 15:52:24 -05:00
|
|
|
for bay in {1..10}; do
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "┌──────────┐ "
|
2026-01-06 15:52:24 -05:00
|
|
|
done
|
2026-01-06 16:25:56 -05:00
|
|
|
printf " │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
# Bay contents
|
|
|
|
|
printf "│ "
|
2026-01-06 15:52:24 -05:00
|
|
|
for bay in {1..10}; do
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "│%-2d:%-7s│ " "$bay" "${DRIVE_MAP[$bay]:-EMPTY}"
|
2026-01-06 15:52:24 -05:00
|
|
|
done
|
2026-01-06 16:25:56 -05:00
|
|
|
printf " │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
# Bay bottom borders
|
|
|
|
|
printf "│ "
|
2026-01-06 15:52:24 -05:00
|
|
|
for bay in {1..10}; do
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "└──────────┘ "
|
2025-03-01 13:53:08 -05:00
|
|
|
done
|
2026-01-06 16:25:56 -05:00
|
|
|
printf " │\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
|
2026-01-06 16:13:17 -05:00
|
|
|
printf "└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\n"
|
2025-03-01 13:00:53 -05:00
|
|
|
}
|
|
|
|
|
|
2026-01-24 21:05:53 -05:00
|
|
|
generate_micro_layout() {
|
|
|
|
|
local hostname=$1
|
|
|
|
|
build_drive_map
|
|
|
|
|
|
|
|
|
|
# Check for eMMC storage
|
|
|
|
|
local emmc_device=""
|
|
|
|
|
if [[ -b /dev/mmcblk0 ]]; then
|
|
|
|
|
emmc_device="mmcblk0"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
printf "┌─────────────────────────────────────────────────────────────┐\n"
|
|
|
|
|
printf "│ %-57s │\n" "$hostname - Micro SBC"
|
|
|
|
|
printf "│ │\n"
|
|
|
|
|
|
|
|
|
|
# Show eMMC if present
|
|
|
|
|
if [[ -n "$emmc_device" ]]; then
|
|
|
|
|
local emmc_size=$(lsblk -d -n -o SIZE "/dev/$emmc_device" 2>/dev/null | xargs)
|
|
|
|
|
printf "│ ┌─────────────────────────────────────────────────────┐ │\n"
|
|
|
|
|
printf "│ │ Onboard eMMC: %-10s (%s) │ │\n" "$emmc_device" "$emmc_size"
|
|
|
|
|
printf "│ └─────────────────────────────────────────────────────┘ │\n"
|
|
|
|
|
printf "│ │\n"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
printf "│ SATA Ports (rear): │\n"
|
|
|
|
|
printf "│ ┌──────────────┐ ┌──────────────┐ │\n"
|
|
|
|
|
printf "│ │ 1: %-9s │ │ 2: %-9s │ │\n" "${DRIVE_MAP[1]:-EMPTY}" "${DRIVE_MAP[2]:-EMPTY}"
|
|
|
|
|
printf "│ └──────────────┘ └──────────────┘ │\n"
|
|
|
|
|
printf "└─────────────────────────────────────────────────────────────┘\n"
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
generate_large1_layout() {
|
2026-01-24 21:10:56 -05:00
|
|
|
local hostname=$1
|
2026-01-06 15:52:24 -05:00
|
|
|
build_drive_map
|
|
|
|
|
|
2026-01-24 21:13:27 -05:00
|
|
|
# large1 has 3 stacks of 5 bays at front (15 total) + 2 M.2 slots
|
|
|
|
|
# Physical bay mapping TBD - current mapping is by controller order
|
2026-01-24 21:10:56 -05:00
|
|
|
printf "┌─────────────────────────────────────────────────────────────────────────┐\n"
|
2026-01-24 21:13:27 -05:00
|
|
|
printf "│ %-69s │\n" "$hostname - Tower (3x5 Front Bays + 2x M.2)"
|
2026-01-24 21:10:56 -05:00
|
|
|
printf "│ │\n"
|
2026-01-24 21:13:27 -05:00
|
|
|
printf "│ M.2 NVMe: M1: %-10s M2: %-10s │\n" "${DRIVE_MAP[m2-1]:-EMPTY}" "${DRIVE_MAP[m2-2]:-EMPTY}"
|
2026-01-24 21:10:56 -05:00
|
|
|
printf "│ │\n"
|
2026-01-24 21:13:27 -05:00
|
|
|
printf "│ Front Bays (3 stacks x 5 rows): [Bay mapping TBD] │\n"
|
|
|
|
|
printf "│ Stack A Stack B Stack C │\n"
|
|
|
|
|
printf "│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │\n"
|
|
|
|
|
printf "│ │1:%-8s│ │2:%-8s│ │3:%-8s│ │\n" "${DRIVE_MAP[1]:-EMPTY}" "${DRIVE_MAP[2]:-EMPTY}" "${DRIVE_MAP[3]:-EMPTY}"
|
|
|
|
|
printf "│ ├──────────┤ ├──────────┤ ├──────────┤ │\n"
|
|
|
|
|
printf "│ │4:%-8s│ │5:%-8s│ │6:%-8s│ │\n" "${DRIVE_MAP[4]:-EMPTY}" "${DRIVE_MAP[5]:-EMPTY}" "${DRIVE_MAP[6]:-EMPTY}"
|
|
|
|
|
printf "│ ├──────────┤ ├──────────┤ ├──────────┤ │\n"
|
|
|
|
|
printf "│ │7:%-8s│ │8:%-8s│ │9:%-8s│ │\n" "${DRIVE_MAP[7]:-EMPTY}" "${DRIVE_MAP[8]:-EMPTY}" "${DRIVE_MAP[9]:-EMPTY}"
|
|
|
|
|
printf "│ ├──────────┤ ├──────────┤ ├──────────┤ │\n"
|
|
|
|
|
printf "│ │10:%-7s│ │11:%-7s│ │12:%-7s│ │\n" "${DRIVE_MAP[10]:-EMPTY}" "${DRIVE_MAP[11]:-EMPTY}" "${DRIVE_MAP[12]:-EMPTY}"
|
|
|
|
|
printf "│ ├──────────┤ ├──────────┤ ├──────────┤ │\n"
|
|
|
|
|
printf "│ │13:%-7s│ │14:%-7s│ │15:%-7s│ │\n" "${DRIVE_MAP[13]:-EMPTY}" "${DRIVE_MAP[14]:-EMPTY}" "${DRIVE_MAP[15]:-EMPTY}"
|
|
|
|
|
printf "│ └──────────┘ └──────────┘ └──────────┘ │\n"
|
2026-01-24 21:10:56 -05:00
|
|
|
printf "└─────────────────────────────────────────────────────────────────────────┘\n"
|
2026-01-06 15:52:24 -05:00
|
|
|
}
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Server-Specific Drive Mappings
|
|
|
|
|
# Maps PCI paths to physical bay numbers for each server
|
|
|
|
|
# Format: "pci-path bay-number"
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
declare -A SERVER_MAPPINGS=(
|
|
|
|
|
# compute-storage-01 (formerly medium2)
|
2026-01-06 16:04:15 -05:00
|
|
|
# Motherboard: B650D4U3-2Q/BCM with AMD SATA controller
|
|
|
|
|
# HBA: LSI SAS3008 at 01:00.0 (mini-SAS HD ports)
|
|
|
|
|
# Cable mapping from user notes:
|
|
|
|
|
# - Mobo SATA: top-right=bay1, bottom-right=bay2, bottom-left=bay3, top-left=bay4
|
|
|
|
|
# - HBA bottom mini-SAS: bays 5,6,7,8
|
|
|
|
|
# - HBA top mini-SAS: bays 9,10
|
2026-01-06 15:52:24 -05:00
|
|
|
["compute-storage-01"]="
|
2026-01-06 16:13:17 -05:00
|
|
|
pci-0000:0d:00.0-ata-2 1
|
|
|
|
|
pci-0000:0d:00.0-ata-1 2
|
|
|
|
|
pci-0000:0d:00.0-ata-3 3
|
|
|
|
|
pci-0000:0d:00.0-ata-4 4
|
2026-01-06 16:21:56 -05:00
|
|
|
pci-0000:01:00.0-sas-phy6-lun-0 5
|
|
|
|
|
pci-0000:01:00.0-sas-phy7-lun-0 6
|
|
|
|
|
pci-0000:01:00.0-sas-phy5-lun-0 7
|
|
|
|
|
pci-0000:01:00.0-sas-phy2-lun-0 8
|
|
|
|
|
pci-0000:01:00.0-sas-phy4-lun-0 9
|
|
|
|
|
pci-0000:01:00.0-sas-phy3-lun-0 10
|
2026-01-06 16:04:15 -05:00
|
|
|
pci-0000:0e:00.0-nvme-1 m2-1
|
2026-01-06 15:52:24 -05:00
|
|
|
"
|
|
|
|
|
|
2026-01-24 17:27:08 -05:00
|
|
|
# compute-storage-gpu-01
|
|
|
|
|
# Motherboard: ASUS PRIME B550-PLUS with AMD SATA controller at 02:00.1
|
|
|
|
|
# 5 SATA ports + 1 M.2 NVMe slot
|
|
|
|
|
# sdf is USB/card reader - not mapped
|
|
|
|
|
["compute-storage-gpu-01"]="
|
|
|
|
|
pci-0000:02:00.1-ata-1 1
|
|
|
|
|
pci-0000:02:00.1-ata-2 2
|
|
|
|
|
pci-0000:02:00.1-ata-3 3
|
|
|
|
|
pci-0000:02:00.1-ata-4 4
|
|
|
|
|
pci-0000:02:00.1-ata-5 5
|
|
|
|
|
pci-0000:0c:00.0-nvme-1 m2-1
|
|
|
|
|
"
|
|
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
# storage-01
|
2026-01-24 17:31:05 -05:00
|
|
|
# Motherboard: ASRock A320M-HDV R4.0 with AMD SATA controller at 02:00.1
|
|
|
|
|
# 4 SATA ports used (ata-1, ata-2, ata-5, ata-6) - ata-3/4 empty
|
2026-01-06 15:52:24 -05:00
|
|
|
["storage-01"]="
|
2026-01-24 17:31:05 -05:00
|
|
|
pci-0000:02:00.1-ata-1 1
|
|
|
|
|
pci-0000:02:00.1-ata-2 2
|
|
|
|
|
pci-0000:02:00.1-ata-5 3
|
|
|
|
|
pci-0000:02:00.1-ata-6 4
|
2026-01-06 15:52:24 -05:00
|
|
|
"
|
|
|
|
|
|
|
|
|
|
# large1
|
2026-01-24 21:10:56 -05:00
|
|
|
# Custom tower with multiple controllers:
|
|
|
|
|
# - HBA: LSI SAS2008 at 10:00.0 (7 drives)
|
|
|
|
|
# - AMD SATA at 16:00.1 (3 drives)
|
|
|
|
|
# - ASMedia SATA at 25:00.0 (2 drives)
|
|
|
|
|
# - 2x NVMe slots
|
2026-01-06 15:52:24 -05:00
|
|
|
["large1"]="
|
2026-01-24 21:10:56 -05:00
|
|
|
pci-0000:10:00.0-sas-phy0-lun-0 1
|
|
|
|
|
pci-0000:10:00.0-sas-phy1-lun-0 2
|
|
|
|
|
pci-0000:10:00.0-sas-phy3-lun-0 3
|
|
|
|
|
pci-0000:10:00.0-sas-phy4-lun-0 4
|
|
|
|
|
pci-0000:10:00.0-sas-phy5-lun-0 5
|
|
|
|
|
pci-0000:10:00.0-sas-phy6-lun-0 6
|
|
|
|
|
pci-0000:10:00.0-sas-phy7-lun-0 7
|
|
|
|
|
pci-0000:16:00.1-ata-3 8
|
|
|
|
|
pci-0000:16:00.1-ata-7 9
|
|
|
|
|
pci-0000:16:00.1-ata-8 10
|
|
|
|
|
pci-0000:25:00.0-ata-1 11
|
|
|
|
|
pci-0000:25:00.0-ata-2 12
|
|
|
|
|
pci-0000:2a:00.0-nvme-1 m2-1
|
|
|
|
|
pci-0000:26:00.0-nvme-1 m2-2
|
2026-01-06 15:52:24 -05:00
|
|
|
"
|
2026-01-24 21:05:53 -05:00
|
|
|
|
2026-01-24 21:07:51 -05:00
|
|
|
# micro1
|
|
|
|
|
# ZimaBoard 832 - Single board computer
|
|
|
|
|
# 2 SATA ports on rear (currently unused)
|
|
|
|
|
# Boot from onboard eMMC (mmcblk0)
|
|
|
|
|
# SATA controller at 00:12.0
|
|
|
|
|
["micro1"]="
|
|
|
|
|
"
|
|
|
|
|
|
2026-01-24 21:05:53 -05:00
|
|
|
# monitor-02
|
|
|
|
|
# ZimaBoard 832 - Single board computer
|
|
|
|
|
# 2 SATA ports on rear (currently unused)
|
|
|
|
|
# Boot from onboard eMMC (mmcblk0)
|
|
|
|
|
# SATA controller would be at a specific PCI address when drives connected
|
|
|
|
|
["monitor-02"]="
|
|
|
|
|
"
|
2026-01-06 15:52:24 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
declare -A CHASSIS_TYPES=(
|
|
|
|
|
["compute-storage-01"]="10bay"
|
2026-01-06 15:54:53 -05:00
|
|
|
["compute-storage-gpu-01"]="10bay"
|
2026-01-06 15:52:24 -05:00
|
|
|
["storage-01"]="10bay"
|
|
|
|
|
["large1"]="large1"
|
2026-01-24 21:07:51 -05:00
|
|
|
["micro1"]="micro" # ZimaBoard 832
|
|
|
|
|
["monitor-02"]="micro" # ZimaBoard 832
|
2026-01-06 15:52:24 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Core Functions
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
build_drive_map() {
|
|
|
|
|
local host=$(hostname)
|
|
|
|
|
declare -A drive_map
|
|
|
|
|
|
|
|
|
|
local mapping=${SERVER_MAPPINGS[$host]}
|
|
|
|
|
|
|
|
|
|
if [[ -n "$mapping" ]]; then
|
|
|
|
|
while read -r path slot; do
|
|
|
|
|
[[ -z "$path" || -z "$slot" ]] && continue
|
|
|
|
|
|
|
|
|
|
if [[ -L "/dev/disk/by-path/$path" ]]; then
|
|
|
|
|
local drive=$(readlink -f "/dev/disk/by-path/$path" | sed 's/.*\///')
|
|
|
|
|
drive_map[$slot]=$drive
|
|
|
|
|
fi
|
|
|
|
|
done <<< "$mapping"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Make drive_map available globally
|
|
|
|
|
declare -g -A DRIVE_MAP=()
|
|
|
|
|
for key in "${!drive_map[@]}"; do
|
|
|
|
|
DRIVE_MAP[$key]=${drive_map[$key]}
|
2025-03-01 14:32:10 -05:00
|
|
|
done
|
2025-03-01 11:43:21 -05:00
|
|
|
}
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
get_drive_smart_info() {
|
|
|
|
|
local device=$1
|
|
|
|
|
local smart_info=$(sudo smartctl -A -i -H /dev/$device 2>/dev/null)
|
|
|
|
|
local temp=$(echo "$smart_info" | grep "Temperature" | awk '{print $10}' | head -1)
|
|
|
|
|
local type=$(echo "$smart_info" | grep "Rotation Rate" | grep -q "Solid State" && echo "SSD" || echo "HDD")
|
|
|
|
|
local health=$(echo "$smart_info" | grep "SMART overall-health" | grep -q "PASSED" && echo "✓" || echo "✗")
|
|
|
|
|
local model=$(echo "$smart_info" | grep "Device Model\|Model Number" | cut -d: -f2 | xargs)
|
2026-01-06 16:16:04 -05:00
|
|
|
local serial=$(echo "$smart_info" | grep "Serial Number" | awk '{print $3}')
|
2026-01-06 15:52:24 -05:00
|
|
|
|
2026-01-06 16:16:04 -05:00
|
|
|
echo "$type|$temp°C|$health|$model|$serial"
|
2026-01-06 15:52:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Main Display Logic
|
|
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
|
2024-12-09 21:59:32 -05:00
|
|
|
HOSTNAME=$(hostname)
|
2026-01-06 15:52:24 -05:00
|
|
|
CHASSIS_TYPE=${CHASSIS_TYPES[$HOSTNAME]:-"unknown"}
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
# Display chassis layout
|
|
|
|
|
case "$CHASSIS_TYPE" in
|
|
|
|
|
"10bay")
|
|
|
|
|
generate_10bay_layout "$HOSTNAME"
|
2024-12-09 21:59:32 -05:00
|
|
|
;;
|
2026-01-06 15:52:24 -05:00
|
|
|
"large1")
|
2026-01-24 21:10:56 -05:00
|
|
|
generate_large1_layout "$HOSTNAME"
|
2024-12-09 21:59:32 -05:00
|
|
|
;;
|
2026-01-06 15:52:24 -05:00
|
|
|
"micro")
|
2026-01-24 21:05:53 -05:00
|
|
|
generate_micro_layout "$HOSTNAME"
|
2024-12-09 21:59:32 -05:00
|
|
|
;;
|
|
|
|
|
*)
|
2026-01-06 15:52:24 -05:00
|
|
|
echo "┌─────────────────────────────────────────────────────────┐"
|
|
|
|
|
echo "│ Unknown server: $HOSTNAME"
|
|
|
|
|
echo "│ No chassis mapping defined yet"
|
|
|
|
|
echo "│ Run diagnose-drives.sh to gather PCI path information"
|
|
|
|
|
echo "└─────────────────────────────────────────────────────────┘"
|
2024-12-09 21:59:32 -05:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Drive Details Section
|
|
|
|
|
#------------------------------------------------------------------------------
|
2025-02-21 20:41:24 -05:00
|
|
|
|
2026-01-06 16:25:56 -05:00
|
|
|
echo -e "\n=== Drive Details with SMART Status (by Bay Position) ==="
|
2026-01-06 16:28:44 -05:00
|
|
|
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s\n" "BAY" "DEVICE" "SIZE" "TYPE" "TEMP" "HEALTH" "MODEL" "SERIAL" "CEPH OSD" "STATUS" "USAGE"
|
|
|
|
|
echo "----------------------------------------------------------------------------------------------------------------------------------------------------"
|
2025-03-01 13:22:51 -05:00
|
|
|
|
2026-01-06 16:25:56 -05:00
|
|
|
# Build reverse map: device -> bay
|
|
|
|
|
declare -A DEVICE_TO_BAY
|
|
|
|
|
for bay in "${!DRIVE_MAP[@]}"; do
|
|
|
|
|
device="${DRIVE_MAP[$bay]}"
|
|
|
|
|
if [[ -n "$device" && "$device" != "EMPTY" ]]; then
|
|
|
|
|
DEVICE_TO_BAY[$device]=$bay
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# Sort drives by bay position
|
|
|
|
|
for bay in $(printf '%s\n' "${!DRIVE_MAP[@]}" | grep -E '^[0-9]+$' | sort -n); do
|
|
|
|
|
device="${DRIVE_MAP[$bay]}"
|
|
|
|
|
if [[ -n "$device" && "$device" != "EMPTY" && -b "/dev/$device" ]]; then
|
2026-01-06 15:52:24 -05:00
|
|
|
size=$(lsblk -d -n -o SIZE "/dev/$device" 2>/dev/null)
|
2025-03-01 13:22:51 -05:00
|
|
|
smart_info=$(get_drive_smart_info "$device")
|
2026-01-06 16:16:04 -05:00
|
|
|
IFS='|' read -r type temp health model serial <<< "$smart_info"
|
2026-01-06 16:25:56 -05:00
|
|
|
|
|
|
|
|
# Check for Ceph OSD
|
|
|
|
|
osd_id=$(ceph-volume lvm list 2>/dev/null | grep -B 20 "/dev/$device" | grep "osd id" | awk '{print "osd."$3}' | head -1)
|
|
|
|
|
|
2026-01-06 16:28:44 -05:00
|
|
|
# Get Ceph status if OSD exists
|
|
|
|
|
ceph_status="-"
|
|
|
|
|
if [[ -n "$osd_id" ]]; then
|
|
|
|
|
# Get in/out and up/down status from ceph osd tree
|
|
|
|
|
osd_num=$(echo "$osd_id" | sed 's/osd\.//')
|
2026-01-06 16:30:21 -05:00
|
|
|
# Parse ceph osd tree output - column 5 is STATUS (up/down), column 6 is REWEIGHT (1.0 = in, 0 = out)
|
|
|
|
|
tree_line=$(ceph osd tree 2>/dev/null | grep -E "^\s*${osd_num}\s+" | grep "osd.${osd_num}")
|
|
|
|
|
up_status=$(echo "$tree_line" | awk '{print $5}')
|
|
|
|
|
reweight=$(echo "$tree_line" | awk '{print $6}')
|
|
|
|
|
|
|
|
|
|
# Default to unknown if we can't parse
|
|
|
|
|
[[ -z "$up_status" ]] && up_status="unknown"
|
|
|
|
|
[[ -z "$reweight" ]] && reweight="0"
|
|
|
|
|
|
|
|
|
|
# Determine in/out based on reweight (1.0 = in, 0 = out)
|
|
|
|
|
if (( $(echo "$reweight > 0" | bc -l 2>/dev/null || echo 0) )); then
|
|
|
|
|
in_status="in"
|
|
|
|
|
else
|
|
|
|
|
in_status="out"
|
|
|
|
|
fi
|
|
|
|
|
|
2026-01-06 16:28:44 -05:00
|
|
|
ceph_status="${up_status}/${in_status}"
|
|
|
|
|
else
|
|
|
|
|
osd_id="-"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Check if boot drive
|
|
|
|
|
usage="-"
|
|
|
|
|
if mount | grep -q "^/dev/${device}"; then
|
|
|
|
|
mount_point=$(mount | grep "^/dev/${device}" | awk '{print $3}' | head -1)
|
|
|
|
|
if [[ "$mount_point" == "/" ]]; then
|
|
|
|
|
usage="BOOT"
|
|
|
|
|
else
|
|
|
|
|
usage="$mount_point"
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
printf "%-5s %-15s %-10s %-8s %-8s %-8s %-30s %-20s %-12s %-10s %-10s\n" "$bay" "/dev/$device" "$size" "$type" "$temp" "$health" "$model" "$serial" "$osd_id" "$ceph_status" "$usage"
|
2026-01-06 15:52:24 -05:00
|
|
|
fi
|
|
|
|
|
done
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
# NVMe drives
|
2026-01-24 17:31:05 -05:00
|
|
|
nvme_devices=$(lsblk -d -n -o NAME,SIZE | grep "^nvme" 2>/dev/null)
|
|
|
|
|
if [ -n "$nvme_devices" ]; then
|
|
|
|
|
echo -e "\n=== NVMe Drives ==="
|
|
|
|
|
printf "%-15s %-10s %-10s %-40s %-25s\n" "DEVICE" "SIZE" "TYPE" "MODEL" "SERIAL"
|
|
|
|
|
echo "------------------------------------------------------------------------------------------------------"
|
|
|
|
|
echo "$nvme_devices" | while read -r name size; do
|
|
|
|
|
device="/dev/$name"
|
|
|
|
|
# Get model and serial from smartctl for accuracy
|
|
|
|
|
smart_info=$(sudo smartctl -i "$device" 2>/dev/null)
|
|
|
|
|
model=$(echo "$smart_info" | grep "Model Number" | cut -d: -f2 | xargs)
|
|
|
|
|
serial=$(echo "$smart_info" | grep "Serial Number" | cut -d: -f2 | xargs)
|
|
|
|
|
[[ -z "$model" ]] && model="-"
|
|
|
|
|
[[ -z "$serial" ]] && serial="-"
|
|
|
|
|
printf "%-15s %-10s %-10s %-40s %-25s\n" "$device" "$size" "NVMe" "$model" "$serial"
|
|
|
|
|
done
|
2024-12-12 21:42:56 -05:00
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
#------------------------------------------------------------------------------
|
|
|
|
|
# Optional sections
|
|
|
|
|
#------------------------------------------------------------------------------
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
# Ceph RBD Devices
|
2026-01-24 17:27:08 -05:00
|
|
|
rbd_devices=$(lsblk -d -n -o NAME,SIZE,TYPE 2>/dev/null | grep "rbd" | sort -V)
|
|
|
|
|
if [ -n "$rbd_devices" ]; then
|
2026-01-06 15:52:24 -05:00
|
|
|
echo -e "\n=== Ceph RBD Devices ==="
|
2026-01-24 17:27:08 -05:00
|
|
|
printf "%-15s %-10s %-10s %-30s\n" "DEVICE" "SIZE" "TYPE" "MOUNTPOINT"
|
2024-12-12 21:48:11 -05:00
|
|
|
echo "------------------------------------------------------------"
|
2026-01-24 17:27:08 -05:00
|
|
|
echo "$rbd_devices" | while read -r name size type; do
|
|
|
|
|
# Get mountpoint if any
|
|
|
|
|
mountpoint=$(lsblk -n -o MOUNTPOINT "/dev/$name" 2>/dev/null | head -1)
|
|
|
|
|
[[ -z "$mountpoint" ]] && mountpoint="-"
|
|
|
|
|
printf "%-15s %-10s %-10s %-30s\n" "/dev/$name" "$size" "$type" "$mountpoint"
|
|
|
|
|
done
|
2024-12-09 22:07:59 -05:00
|
|
|
fi
|
2024-12-09 21:59:32 -05:00
|
|
|
|
2026-01-06 15:52:24 -05:00
|
|
|
# Show mapping diagnostic info if DEBUG is set
|
|
|
|
|
if [[ -n "$DEBUG" ]]; then
|
|
|
|
|
echo -e "\n=== DEBUG: Drive Mappings ==="
|
|
|
|
|
for key in "${!DRIVE_MAP[@]}"; do
|
|
|
|
|
echo "Bay $key: ${DRIVE_MAP[$key]}"
|
|
|
|
|
done | sort -n
|
2024-12-12 21:48:11 -05:00
|
|
|
fi
|