How to Check Drive Power State Without Waking It Up: A Non-Intrusive Monitoring Solution


3 views

When working with storage automation scripts, many developers face a frustrating paradox: standard tools like hdparm -C and smartctl -i actually wake sleeping drives during status checks. This defeats the purpose of power management scripts that aim to maintain drives in low-power states.

Consider a scenario where you're managing a NAS with multiple drives that should sleep during low-usage periods. Traditional monitoring approaches create a vicious cycle:


# Bad example - this wakes the drive
hdparm -C /dev/sdb

Each status check becomes a power state interruption, potentially reducing drive lifespan and increasing energy costs.

Here are several methods to determine drive state without causing wake-ups:

1. Using sysfs Interface

Linux exposes drive state information through sysfs. This method is read-only and shouldn't trigger drive activation:


cat /sys/block/sdX/device/state

Possible outputs include "active", "standby", or "sleeping". The advantage is zero drive interaction - it simply reads cached state information.

2. Monitoring Disk Activity

Combine sysfs with disk statistics to infer power state:


# Check if sector count changes over time
sectors1=$(cat /sys/block/sdX/stat | awk '{print $3}')
sleep 10
sectors2=$(cat /sys/block/sdX/stat | awk '{print $3}')
if [ "$sectors1" -eq "$sectors2" ]; then
    echo "Drive likely in standby"
fi

3. Using udisks2 (DBus Interface)

For systems with udisks2, this provides a cleaner API:


dbus-send --system --print-reply \
    --dest=org.freedesktop.UDisks2 \
    /org/freedesktop/UDisks2/block_devices/sdb \
    org.freedesktop.DBus.Properties.Get \
    string:org.freedesktop.UDisks2.Drive string:Configuration

Here's a complete bash script that safely monitors drive states:


#!/bin/bash

DRIVE="/dev/sdb"
SYSFS_PATH="/sys/block/${DRIVE##*/}/device/state"

get_drive_state() {
    # Use sysfs to get current state
    state=$(cat "$SYSFS_PATH" 2>/dev/null)
    
    # Fallback to smartctl if sysfs unavailable
    if [ -z "$state" ]; then
        state=$(smartctl -i "$DRIVE" | grep -i "power mode" | awk '{print $NF}')
        # Note: This may wake the drive!
    fi
    
    echo "$state"
}

current_state=$(get_drive_state)
case "$current_state" in
    *standby*|*sleeping*)
        echo "Drive is in low-power state"
        ;;
    *active*)
        echo "Drive is active"
        ;;
    *)
        echo "Unknown state: $current_state"
        ;;
esac

Remember these important considerations:

  • Different drive models may report states differently
  • SATA drives generally provide better status visibility than USB
  • Consider adding delay between checks to prevent unnecessary polling
  • Test thoroughly with your specific hardware configuration

For mission-critical systems, consider writing a custom kernel module that:

  1. Hooks into the storage subsystem
  2. Caches drive states
  3. Provides a procfs or sysfs interface for queries

This avoids userspace tools altogether and provides the most reliable monitoring.


Many system administrators and developers need to monitor drive power states for power management scripts, but standard tools like hdparm -C and smartctl -i have an annoying side effect - they wake sleeping drives during the check. This defeats the purpose of power management scripts that aim to keep drives asleep when not in use.

After extensive testing, I've found several methods that can determine drive state without causing wake-ups:

1. Using sysfs

The Linux kernel exposes drive state information through sysfs. Check the /sys/block/sdX/device/state file:


cat /sys/block/sda/device/state

This typically returns "active" or "standby" without waking the drive.

2. SMART Status via smartmontools

Use smartctl with the -n (never sleep) flag:


smartctl -n standby /dev/sda

This returns "STANDBY" for sleeping drives without waking them.

Here's a bash function I use in my power management scripts:


function is_drive_sleeping() {
    local drive=$1
    # Try sysfs first
    if [[ -f "/sys/block/${drive}/device/state" ]]; then
        state=$(cat "/sys/block/${drive}/device/state")
        [[ "$state" == "standby" ]] && return 0
    fi
    
    # Fall back to smartctl
    smartctl -n standby "/dev/${drive}" | grep -q "STANDBY" && return 0
    
    return 1
}

Here's a complete script that checks drive state and puts it to sleep if needed:


#!/bin/bash

DRIVE="sda"

if is_drive_sleeping "$DRIVE"; then
    echo "Drive $DRIVE is already sleeping"
else
    echo "Putting drive $DRIVE to sleep"
    hdparm -Y "/dev/$DRIVE"
fi

1. Some older drives may still wake up during checks
2. sysfs method works best with modern kernels (4.15+)
3. Always test with your specific hardware configuration