feat(topo): per-socket bar layout with disks under their controller
Rework the /topo diagram from side-by-side stacked cards into one tall vertical bar per CPU socket with everything attached to it branching off sideways (socket 0 left/branches right, socket 1 right/branches left). Disks are now parented under the storage controller they physically hang off (SATA/AHCI, SAS HBA, RAID) — itself a NUMA-affine PCIe device under one socket — instead of a synthetic catch-all node. The disk->controller link is read from a new storage-controllers.txt techdump (platform.StorageControllerMapScript, a /sys/block walk); disks with no resolvable controller fall back to an "Other" bar. No board/root node. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SYjrG6bVmeG1Z2Wmc8kg3o
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b1ab866f58
commit
319f08ac4b
@@ -23,6 +23,7 @@ var techDumpFixedCommands = []struct {
|
||||
{Name: "lspci", Args: []string{"-vvv"}, File: "lspci-vvv.txt"},
|
||||
{Name: "lscpu", Args: nil, File: "lscpu.txt"},
|
||||
{Name: "lsblk", Args: []string{"-J", "-d", "-o", "NAME,TYPE,SIZE,SERIAL,MODEL,TRAN,HCTL"}, File: "lsblk.json"},
|
||||
{Name: "sh", Args: []string{"-c", StorageControllerMapScript}, File: "storage-controllers.txt"},
|
||||
{Name: "sensors", Args: []string{"-j"}, File: "sensors.json"},
|
||||
{Name: "ipmitool", Args: []string{"fru", "print"}, File: "ipmitool-fru.txt"},
|
||||
{Name: "ipmitool", Args: []string{"sdr"}, File: "ipmitool-sdr.txt"},
|
||||
@@ -85,6 +86,34 @@ wait "$burn_pid" 2>/dev/null || true
|
||||
rm -f /tmp/bee-pcie-load-burn.log
|
||||
`
|
||||
|
||||
// StorageControllerMapScript walks /sys/block to record, for every real
|
||||
// disk, the PCI function of the controller it hangs off and its SCSI HCTL
|
||||
// address. Consumed by webui's /topo page to parent each disk under its
|
||||
// actual storage controller (SATA/AHCI, SAS HBA, RAID) node in the topology
|
||||
// tree instead of a synthetic catch-all branch. Output is one
|
||||
// "name hctl=<h:c:t:l> ctrl=<dddd:bb:dd.f>" line per disk; hctl is empty for
|
||||
// NVMe (which is its own PCIe endpoint).
|
||||
const StorageControllerMapScript = `
|
||||
for dev in /sys/block/*; do
|
||||
n=$(basename "$dev")
|
||||
case "$n" in loop*|ram*|zram*|sr*|md*|dm-*|nbd*|fd*) continue;; esac
|
||||
[ -e "$dev/device" ] || continue
|
||||
real=$(readlink -f "$dev/device") || continue
|
||||
ctrl=""; hctl=""; seen_pci=0
|
||||
oldIFS=$IFS; IFS=/
|
||||
for seg in $real; do
|
||||
case "$seg" in
|
||||
pci[0-9]*:[0-9]*) seen_pci=1 ;;
|
||||
[0-9a-f][0-9a-f][0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f].[0-9a-f]) [ "$seen_pci" = 1 ] && ctrl=$seg ;;
|
||||
[0-9]*:[0-9]*:[0-9]*:[0-9]*) hctl=$seg ;;
|
||||
*) : ;;
|
||||
esac
|
||||
done
|
||||
IFS=$oldIFS
|
||||
echo "$n hctl=$hctl ctrl=$ctrl"
|
||||
done
|
||||
`
|
||||
|
||||
// KernelAERNvidiaScript filters dmesg for PCIe AER, NVRM, and Xid lines —
|
||||
// cheap (dmesg is already in memory) and the fastest way to tell a real
|
||||
// PCIe/GPU hardware fault from power-management noise.
|
||||
|
||||
Reference in New Issue
Block a user