Binary location: /opt/MegaRAID/perccli/perccli64
Add alias to ~/.bashrc:
alias perccli='sudo /opt/MegaRAID/perccli/perccli64'
Allow passwordless sudo:
echo "guernica ALL=(ALL) NOPASSWD: /opt/MegaRAID/perccli/perccli64" | sudo tee /etc/sudoers.d/perccli
sudo chmod 440 /etc/sudoers.d/perccli
Copy to second node:
sudo scp /opt/MegaRAID/perccli/perccli64 thing-2:/tmp/perccli64
ssh thing-2 "sudo mkdir -p /opt/MegaRAID/perccli && sudo mv /tmp/perccli64 /opt/MegaRAID/perccli/perccli64 && sudo chmod +x /opt/MegaRAID/perccli/perccli64"
# Show controller summary
perccli /c0 show
# Show all controllers
perccli show
# List all virtual disks
perccli /c0/vall show
# Detailed info including cache policy
perccli /c0/vall show all
# Show specific virtual disk
perccli /c0/v0 show
# List all physical disks
perccli /c0/eall/sall show
# Detailed disk info (temperature, errors, S.M.A.R.T.)
perccli /c0/eall/sall show all
# Show specific drive (enclosure:slot)
perccli /c0/e32/s0 show
# Show BBU status
perccli /c0/bbu show
# Show full BBU details (capacity, firmware, gas gauge)
perccli /c0/bbu show all
show all is the definitive check — show alone can be misleading. Key fields in show all:
| Field | Good Value |
|---|---|
| Battery State | Optimal |
| Replacement required | No |
| Pack is about to fail | No |
| Relative State of Charge | 100% |
| Average time to empty | >10 min |
| Is SOH Good | Yes |
Good output:
Model State RetentionTime Temp MfgDate
BBU Optimal 0 hour(s) 38C 0/00/00
Bad output:
Battery is absent!
If BBU is absent, write cache runs in write-through mode (slower but safe). Replace the BBU to restore write-back caching.
# Blink a drive LED to physically identify it
perccli /c0/e32/s0 start locate
# Stop blinking
perccli /c0/e32/s0 stop locate
Create /usr/local/bin/raid-check.sh:
#!/bin/bash
PERCCLI="/opt/MegaRAID/perccli/perccli64"
echo "=== RAID STATUS ==="
sudo $PERCCLI /c0/vall show | grep -E "DG|VD|State|Type|Size"
echo ""
echo "=== PHYSICAL DRIVES ==="
sudo $PERCCLI /c0/eall/sall show | grep -E "EID|State|Size|Med"
echo ""
echo "=== BBU ==="
sudo $PERCCLI /c0/bbu show | grep -E "Model|State|Temp"
sudo chmod +x /usr/local/bin/raid-check.sh
| State | Meaning |
|---|---|
| Optl | Optimal — healthy |
| Dgrd | Degraded — running with failed drive |
| Pdgd | Partially degraded |
| Rbld | Rebuilding after drive replacement |
| Onln | Drive online |
| Offln | Drive offline/failed |
| GHS | Global Hot Spare |
| UGood | Unconfigured good — available |
| UBad | Unconfigured bad — failed |
# Show cache policy
perccli /c0/v0 show all | grep -i cache
# Set write-back cache (requires BBU)
perccli /c0/v0 set wrcache=wb
# Set write-through (no BBU required, slower)
perccli /c0/v0 set wrcache=wt
Without a BBU the controller forces write-through regardless of setting.
perccli /c0/vall show && perccli /c0/bbu show
This runs on login via /etc/profile.d/raid-check.sh.
/usr/local/bin/raid-check.sh:
#!/bin/bash
echo ""
echo "================================="
echo " RAID STATUS CHECK"
echo "================================="
STATUS=$(sudo /opt/MegaRAID/perccli/perccli64 /c0/vall show 2>/dev/null | grep "RAID10")
if echo "$STATUS" | grep -q "Optl"; then
echo "✅ RAID STATUS: Optimal"
else
echo "🔴 WARNING: RAID DEGRADED!"
fi
echo "================================="
echo ""
/etc/profile.d/raid-check.sh:
#!/bin/bash
/usr/local/bin/raid-check.sh
This runs automatically on every SSH login. If RAID is degraded you see it immediately.
The script calls perccli with sudo. To allow this without a password prompt, check /etc/sudoers.d/:
sudo visudo -f /etc/sudoers.d/perccli
Should contain:
guernica ALL=(ALL) NOPASSWD: /opt/MegaRAID/perccli/perccli64
If the file doesn't exist, create it:
echo "guernica ALL=(ALL) NOPASSWD: /opt/MegaRAID/perccli/perccli64" | sudo tee /etc/sudoers.d/perccli
sudo chmod 440 /etc/sudoers.d/perccli
Applied on thing-2 (Dell R240, PERC H730P, 4x Samsung 860 PRO 1TB, RAID 10).
Default PERC virtual disk settings are tuned for spinning disks, not SSDs:
| Parameter | Default | Optimal for SSD |
|---|---|---|
| Read cache | Read Ahead Always (RA) |
No Read Ahead (NoRA) |
| IO policy | Cached IO (C) |
Direct IO (D) |
Read Ahead Always pre-fetches adjacent sectors anticipating sequential access — a significant win on spinning disks where seek time is expensive. On SSDs with near-zero seek time it just wastes controller cache.
Cached IO splits the onboard cache between reads and writes. With Write-Back already handling the write path, dedicating the full cache to writes is more efficient.
perccli /c0/v0 set rdcache=nora
perccli /c0/v0 set iopolicy=direct
| Metric | Before | After |
|---|---|---|
| Sequential write | 986 MB/s | 1.1 GB/s |
| Sequential read | 1.1 GB/s | 1.1 GB/s |
Write speed now matches read speed. Array is running at the controller and drive ceiling, sufficient to saturate a 10GbE link (1.25 GB/s theoretical max).
perccli /c0/v0 show all | grep "0/0"
# Should show: NRWD
# N=NoRA R=ReadAhead(position) W=WriteBack D=DirectIO
perccli /c0/v0 set rdcache=ra
perccli /c0/v0 set iopolicy=cached
The kernel's mq-deadline scheduler is designed for spinning disks to minimize head seeks. Behind a hardware RAID controller that already does its own I/O scheduling, it adds redundant overhead. Set to none to pass I/O directly to the PERC.
# Apply immediately
echo none | sudo tee /sys/block/sda/queue/scheduler
# Persist across reboots
echo 'ACTION=="add|change", KERNEL=="sda", ATTR{queue/scheduler}="none"' | \
sudo tee /etc/udev/rules.d/60-iosched-raid.rules
Revert:
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler
rm /etc/udev/rules.d/60-iosched-raid.rules
Note:
sudo echo none > /sys/block/...does not work — the shell handles the redirect before sudo runs. Always usetee.