jaredandClaude Opus 4.8 a55fa85875
Lint / Shell (shellcheck) (push) Successful in 17s
driveAtlas: make ZimaBoard front-panel connectors recognisable
The four front ports were identical 2-char stubs under one lumped
"GbE/USB" label, so they read as anonymous blobs. Draw them as the
hardware actually is and give each connector type its own silhouette:

  RJ45   ██▄██   solid jack with a notch cut into the top centre (latch slot)
  USB-A  █▀▀▀█   side walls plus a tongue bar filling the upper half
  mDP    ╱██╲    chamfered slot
  DC     (█)     round barrel with a centre pin

The 2x GbE and 2x USB now share ONE housing with the ethernet row sitting
directly on top of the USB row and no divider between them, matching the
physical stacked connector module. Each jack stays one row tall by using
half-block glyphs to get two vertical pixels per cell. GbE and USB get
separate labels; mDP and DC 12V sit beneath their own connectors.

Front-face height HC grows 3 -> 5 for the room. Knock-on: HC feeds FB,
which decides where the left side face stops being a vertical edge, so the
PCIe row now lands on the last vertical row and its card edge makes a real
T-junction into the chassis (▐▓▓┤) instead of floating. HC and the PCIe row
are therefore coupled if this is tuned further.

Still a fixed 66-column canvas, identical display width on every line in
monochrome and colour, SAFE width-1 glyphs only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 02:58:04 -04:00

Drive Atlas

Lint

A powerful server drive mapping tool that generates visual ASCII representations of server layouts and provides comprehensive drive information. Maps physical drive bays to logical Linux device names using PCI bus paths for reliable, persistent identification.

Features

  • 🗺️ Visual ASCII art maps showing physical drive bay layouts
  • 🔗 Persistent drive identification using PCI paths (not device letters)
  • 🌡️ SMART health monitoring with temperature and status
  • 💾 Multi-drive support for SATA, NVMe, SAS, and USB drives
  • 🏷️ Serial number tracking for physical verification
  • 📊 Bay-sorted output matching physical layout
  • 🔵 Ceph integration showing OSD IDs and up/in status
  • 🥾 Boot drive detection identifying system drives
  • 🖥️ Per-server configuration for accurate physical-to-logical mapping

Quick Start

Execute remotely using curl:

bash <(curl -s http://10.10.10.63:3000/LotusGuild/driveAtlas/raw/branch/main/driveAtlas.sh)

Or using wget:

bash <(wget -qO- http://10.10.10.63:3000/LotusGuild/driveAtlas/raw/branch/main/driveAtlas.sh)

Requirements

  • Linux environment with bash
  • sudo privileges for SMART operations
  • smartctl (from smartmontools package)
  • lsblk and lspci (typically pre-installed)
  • Optional: nvme-cli for NVMe drives
  • Optional: ceph-volume and ceph for Ceph OSD tracking

Server Configurations

Chassis Types

Chassis Type Description Servers Using It
10-Bay Hot-swap Sliger CX4712 4U 10x 3.5" NAS (with unused 2x 5.25" bays) compute-storage-01, compute-storage-gpu-01, storage-01
Large1 Grid Unique 3x5 grid layout (1/1 configuration) large1
Micro Compact 2-drive layout micro1, monitor-02

Server Details

compute-storage-01 (formerly medium2)

  • Chassis: Sliger CX4712 4U (10-Bay Hot-swap)
  • Motherboard: B650D4U3-2Q/BCM
  • Controllers:
    • 01:00.0 - LSI SAS3008 HBA (bays 5-10 via 2x mini-SAS HD)
    • 0d:00.0 - AMD SATA controller (bays 1-4)
    • 0e:00.0 - M.2 NVMe slot
  • Status: Fully mapped and verified

storage-01

  • Chassis: Sliger CX4712 4U (10-Bay Hot-swap)
  • Motherboard: ASRock A320M-HDV R4.0
  • Controllers: AMD SATA (bays 1-4), LSI SAS3416 HBA (bays 5+, U.2 NVMe)
  • Status: ⚠️ Partially mapped (5 of 10 bays)

large1

  • Chassis: Unique 3x5 grid (15 bays total)
  • Note: 1/1 configuration, will not be replicated
  • Status: ⚠️ Partially mapped (14 bays + 2 M.2)

compute-storage-gpu-01

  • Chassis: Sliger CX4712 4U (10-Bay Hot-swap)
  • Motherboard: ASUS PRIME B550-PLUS
  • Status: ⚠️ Partially mapped (5 SATA + 1 M.2)

Output Example

┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│  compute-storage-01 - 10-Bay Hot-swap Chassis                                                                                    │
│                                                                                                                                │
│    M.2 NVMe: nvme0n1                                                                                                             │
│                                                                                                                                │
│    Front Hot-swap Bays:                                                                                                        │
│                                                                                                                                │
│    ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐   │
│    │1 :sdh    │ │2 :sdg    │ │3 :sdi    │ │4 :sdj    │ │5 :sde    │ │6 :sdf    │ │7 :sdd    │ │8 :sda    │ │9 :sdc    │ │10:sdb    │   │
│    └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘   │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

=== Drive Details with SMART Status (by Bay Position) ===
BAY   DEVICE          SIZE       TYPE     TEMP     HEALTH   MODEL                          SERIAL               CEPH OSD     STATUS     USAGE
----------------------------------------------------------------------------------------------------------------------------------------------------
1     /dev/sdh        223.6G     SSD      27°C    ✓      Crucial_CT240M500SSD1          14130C0E06DD         -            -          /boot/efi
2     /dev/sdg         1.8T      HDD      26°C    ✓      ST2000DM001-1ER164             Z4ZC4B6R             osd.25       up/in      -
3     /dev/sdi        12.7T      HDD      29°C    ✓      OOS14000G                      000DXND6             osd.9        up/in      -
...

How It Works

PCI Path-Based Mapping

Drive Atlas uses /dev/disk/by-path/ to create persistent mappings between physical drive bays and Linux device names. This is superior to using device letters (sda, sdb, etc.) which can change between boots.

Example PCI path:

pci-0000:01:00.0-sas-phy6-lun-0 → /dev/sde → Bay 5

This tells us:

  • 0000:01:00.0 - PCI bus address of the LSI SAS3008 HBA
  • sas-phy6 - SAS PHY 6 on that controller
  • lun-0 - Logical Unit Number
  • Maps to physical bay 5 on compute-storage-01

Configuration

Server mappings are defined in the SERVER_MAPPINGS associative array in driveAtlas.sh:

declare -A SERVER_MAPPINGS=(
    ["compute-storage-01"]="
        pci-0000:0d:00.0-ata-2 1
        pci-0000:0d:00.0-ata-1 2
        pci-0000:01:00.0-sas-phy6-lun-0 5
        pci-0000:0e:00.0-nvme-1 m2-1
    "
)

Setting Up a New Server

Step 1: Run Diagnostic Mode

First, gather PCI path information:

bash driveAtlas.sh --diagnose

This will show all available PCI paths, storage controllers, and their associated drives.

Step 2: Physical Bay Identification

For each populated drive bay:

  1. Note the physical bay number (labeled on chassis)
  2. Run the main script to see serial numbers
  3. Match visible serial numbers on drives to the output
  4. Map PCI paths to bay numbers

Pro tip: The script shows serial numbers - compare them to visible labels on drive trays to verify physical locations.

Step 3: Create Mapping

Add a new entry to SERVER_MAPPINGS in driveAtlas.sh:

["your-hostname"]="
    pci-0000:XX:XX.X-ata-1 1
    pci-0000:XX:XX.X-ata-2 2
    # ... etc
"

Also add the chassis type to CHASSIS_TYPES:

["your-hostname"]="10bay"

Step 4: Test

Run the main script and verify the layout matches your physical configuration:

bash driveAtlas.sh

Use debug mode to see the mappings:

DEBUG=1 bash driveAtlas.sh

Output Columns Explained

Column Description
BAY Physical bay number (1-10, m2-1, etc.)
DEVICE Linux device name (/dev/sdX, /dev/nvmeXnY)
SIZE Drive capacity
TYPE SSD or HDD (detected via SMART)
TEMP Current temperature from SMART
HEALTH SMART health status (✓ = passed, ⚠ = passed with warnings, ✗ = failed)
MODEL Drive model number
SERIAL Drive serial number (for physical verification)
CEPH OSD Ceph OSD ID if drive hosts an OSD
STATUS Ceph OSD status (up/in, down/out, etc.)
USAGE Mount point or "BOOT" for system drive

Troubleshooting

Drive shows as EMPTY but is physically present

  • Check if the drive is detected: ls -la /dev/disk/by-path/
  • Verify the PCI path in the mapping matches the actual path
  • Ensure the drive has power and SATA/power connections are secure

PCI paths don't match between servers with "identical" hardware

  • Even identical motherboards can have different PCI addressing
  • BIOS settings can affect PCI enumeration
  • HBA installation in different PCIe slots changes addresses
  • Cable routing to different SATA ports changes the ata-N or phy-N number

SMART data not showing

  • Ensure smartmontools is installed: sudo apt install smartmontools
  • Some drives don't report temperature
  • USB-connected drives may not support SMART
  • Run sudo smartctl -i /dev/sdX manually to check

Ceph OSD status shows "unknown/out"

  • Ensure ceph and ceph-volume commands are available
  • Check if the Ceph cluster is healthy: ceph -s
  • Verify OSD is actually up: ceph osd tree

Serial numbers don't match visible labels

  • Some manufacturers use different serials for SMART vs. physical labels
  • Cross-reference by drive model and size
  • Use the removal method: power down, remove drive, check which bay becomes EMPTY

Files

Contributing

When adding support for a new server:

  1. Run driveAtlas.sh --diagnose and save output
  2. Physically label or identify drives by serial number
  3. Create mapping in SERVER_MAPPINGS
  4. Test thoroughly
  5. Document any unique hardware configurations
  6. Update this README

Technical Notes

Why PCI Paths?

Linux device names (sda, sdb, etc.) are assigned in discovery order, which can change:

  • Between kernel versions
  • After BIOS updates
  • When drives are added/removed
  • Due to timing variations at boot

PCI paths are deterministic and based on physical hardware topology.

Bay Numbering Conventions

  • 10-bay chassis: Bays numbered 1-10 (left to right, typically)
  • M.2 slots: Labeled as m2-1, m2-2, etc.
  • USB drives: Labeled as usb1, usb2, etc.
  • Large1: Grid numbering 1-15 (documented in mapping)

Ceph Integration

The script automatically detects Ceph OSDs using:

  1. ceph-volume lvm list to map devices to OSD IDs
  2. ceph osd tree to get up/down and in/out status

Status format: up/in means OSD is running and participating in the cluster.

CI

Workflow Purpose Triggers
lint.yml shellcheck on all .sh files Every push and PR

Branch protection is enabled on main — the lint check must pass before any PR can merge.

S
Description
A Bash-based server drive mapping utility that generates ASCII visualizations of server layouts and provides comprehensive drive information for data center operations.
Readme
902 KiB
Languages
Shell 100%