Programmatic Fan Speed Control for HP ProLiant DL380 G6/G7 Servers: Bypassing BIOS Limits via iLO SSH and Raw IPMI Commands


3 views

Many sysadmins encounter erratic fan behavior on HP ProLiant DL380 G6/G7 servers, particularly when:

  • Running non-HP certified OS (e.g., NexentaStor, custom Linux builds)
  • Having PCIe cards installed (especially third-party NICs/GPUs)
  • Missing HP Management Agents (hpasmd, hp-health)

HP's proprietary cooling logic follows these rules:

1. Base speed = 15% (minimum without override)
2. +10% per PCIe card detected
3. +15% per non-HP PCIe device
4. +20% if ambient >35°C

Access iLO SSH and use these IPMI raw commands:

# Get current fan mode (0x2a = standard)
ipmitool raw 0x30 0x45 0x01

# Set manual mode (0x01 = manual)
ipmitool raw 0x30 0x45 0x01 0x01

# Set fan speed (hex values, 0x14 = 20%)
for i in {1..6}; do
  ipmitool raw 0x30 0x70 0x66 0x01 0x00 0x$i 0x14
done

Create a systemd service for automatic control:

# /etc/systemd/system/hp-fan-control.service
[Unit]
Description=HP Fan Speed Control
After=network.target

[Service]
ExecStart=/usr/local/bin/fan-control.sh
Restart=always

[Install]
WantedBy=multi-user.target

Script example:

#!/bin/bash
ipmitool raw 0x30 0x45 0x01 0x01
while true; do
  TEMP=$(ipmitool sensor get "CPU 1" | awk '/Sensor Reading/ {print $4}')
  if (( $(echo "$TEMP < 50" | bc -l) )); then
    ipmitool raw 0x30 0x70 0x66 0x01 0x00 0x01 0x14
  fi
  sleep 30
done

For systems with add-on cards, modify the PCIe thermal reporting:

# Identify problematic devices
lspci -vv | grep -A10 "PLX Technology" 

# Disable power reporting (risky!)
setpci -s 01:00.0 0x80.B=0x00

Always implement temperature safeguards:

# Emergency shutdown trigger
ipmitool sensor thresh "CPU 1" upper 75 80
ipmitool sensor thresh "System Temp" upper 50 55

Many admins report inconsistent fan behavior across identical HP ProLiant DL380 G6/G7 hardware configurations. While most systems remain whisper-quiet (showing 10-15% fan speed via hplog -f), others ramp up to 40-60% without obvious triggers. This occurs particularly in:

  • NexentaStor 3.1 systems (lacking HP agents)
  • CentOS servers with HP drivers installed
  • Configurations with multiple PCIe cards

The documented BIOS cooling options (ROM-Based Thermal Configuration) often prove insufficient. The "Optimal Cooling" setting still allows unpredictable fan spikes, while "Increased Cooling" creates constant noise pollution.

# Check current thermal policy:
ipmitool raw 0x30 0x0c 0x02 0x01 0x00

# Example output for Optimal Cooling:
01 01 00 01

When HP agents aren't viable, we can use IPMI directly. This Python script forces fan speed to 20% (adjust hex values as needed):

import pyipmi

interface = pyipmi.interfaces.create_interface('lanplus',
              slave_address=0x20,
              hostname='ilo_ip',
              username='admin',
              password='password')

connection = pyipmi.create_connection(interface)
connection.target = pyipmi.Target(0x20)
connection.session.set_session_type_rmcp()

# Set fan zone 1 to 20% (0x14 in hex)
connection.send_message(0x30, 0x70, 0x66, 0x01, 0x00, 0x14)

Third-party PCIe cards often trigger HP's conservative thermal algorithms. For an LSI 9207-8i HBA card, we need additional steps:

# First, identify PCI slot thermal sensors
sensors-detect | grep -i pci

# Then create a udev rule to ignore these sensors:
echo 'SUBSYSTEM=="hwmon", ATTR{name}=="pcie_temp_1", ATTR{temp1_crit}=="0"' > /etc/udev/rules.d/90-ignore-hp-pcie.rules

ILO 4 firmware contains undocumented temperature thresholds. Use these IPMI commands to read them (CAUTION: improper values may cause hardware damage):

# Read CPU threshold table
ipmitool -I lanplus -H ilo_ip -U admin -P password raw 0x30 0x11 0x0 0x0

# Example safe adjustment for CPU zone:
ipmitool raw 0x30 0x11 0x01 0x00 0x3c 0x46 0x50
# Sets warn=60°C, crit=70°C, shutdown=80°C

For ZFS-based systems where HP tools won't install, create a cron job that polls and corrects fan speeds:

#!/bin/bash
MAX_ALLOWED=25  # Percentage

CURRENT_SPEED=$(ipmitool -I lanplus -H 127.0.0.1 -U admin -P password \
             sdr get "Fan1" | grep -Po '[0-9]{2}(?=%)')

if [ "$CURRENT_SPEED" -gt "$MAX_ALLOWED" ]; then
   for zone in {1..5}; do
      ipmitool raw 0x30 0x70 0x66 0x01 0x00 0x14 > /dev/null
   done
fi