Persistent SysFS Parameter Configuration: Best Practices for Linux (RHEL/CentOS)


2 views

When tuning Linux systems through sysfs parameters, maintaining these settings across reboots becomes crucial for production environments. Unlike sysctl which has /etc/sysctl.conf for persistent configuration, sysfs lacks a built-in persistence mechanism.

The traditional method of using /etc/rc.local works but has several drawbacks:

#!/bin/bash
echo 256 > /sys/block/sda/queue/nr_requests
echo deadline > /sys/block/sda/queue/scheduler

Problems with this approach include:

  • No dependency management (parameters might set before devices are ready)
  • Lack of proper error handling
  • Difficult to maintain in configuration management systems

For RHEL/CentOS 7+, creating a systemd service provides better control:

# /etc/systemd/system/sysfs-tune.service
[Unit]
Description=Persistent sysfs tuning
After=sysinit.target local-fs.target
Before=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/sysfs-tune.sh

[Install]
WantedBy=multi-user.target

With the corresponding script:

#!/bin/bash
# /usr/local/bin/sysfs-tune.sh

# Disk scheduler settings
DISKS=$(ls /sys/block/ | grep -E 'sd|vd')
for disk in $DISKS; do
    echo "deadline" > /sys/block/${disk}/queue/scheduler 2>/dev/null
    echo "256" > /sys/block/${disk}/queue/nr_requests 2>/dev/null
done

# Network settings
echo "1" > /proc/sys/net/ipv4/tcp_fastopen 2>/dev/null

For Puppet users, a custom defined type provides clean management:

# modules/sysfs/manifests/init.pp
define sysfs::parameter (
  $value,
  $path = $title,
) {
  exec { "set_sysfs_${title}":
    command => "echo ${value} > ${path}",
    unless  => "grep -q '^${value}\$' ${path}",
    path    => ['/bin', '/usr/bin'],
  }
}

# Example usage:
sysfs::parameter { '/sys/block/sda/queue/scheduler':
  value => 'deadline',
}

For device-specific parameters, udev rules can be effective:

# /etc/udev/rules.d/99-sysfs.rules
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*", RUN+="/bin/sh -c 'echo deadline > /sys/$devpath/queue/scheduler'"

Always verify settings after boot:

#!/bin/bash
# verify-sysfs.sh
expected_values=(
  "/sys/block/sda/queue/scheduler:deadline"
  "/proc/sys/net/ipv4/tcp_fastopen:1"
)

for item in "${expected_values[@]}"; do
  path=${item%:*}
  expected=${item#*:}
  actual=$(cat $path)
  if [[ "$actual" != "$expected" ]]; then
    echo "Mismatch at $path: expected $expected, got $actual"
  fi
done
  • Use systemd services for complex setups
  • Implement proper error handling in scripts
  • Add verification mechanisms
  • Document all changes thoroughly
  • Consider configuration management integration early

When tuning Linux kernel parameters through sysfs interfaces (/sys), administrators often face the recurring issue of losing custom configurations after system reboots. Unlike sysctl.conf for /proc/sys parameters, sysfs lacks a native persistence mechanism, requiring careful implementation of maintenance solutions.

Here are the most effective approaches for RHEL/CentOS systems:

1. The rc.local Method (Simple but Limited)

Basic implementation for simple cases:


#!/bin/bash
# /etc/rc.d/rc.local

# Set block device queue depth
echo 256 > /sys/block/sda/queue/nr_requests

# Adjust VM dirty ratio
echo 20 > /proc/sys/vm/dirty_ratio

2. Systemd Service Units (Modern Approach)

Create a dedicated service for complex configurations:


# /etc/systemd/system/sysfs-tune.service
[Unit]
Description=Custom sysfs parameter configuration
After=sysinit.target
Before=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/sysfs-tune.sh

[Install]
WantedBy=multi-user.target

With corresponding shell script:


#!/bin/bash
# /usr/local/bin/sysfs-tune.sh

# RAID controller tuning
echo 4096 > /sys/block/cciss\!c0d0/queue/nr_requests
echo deadline > /sys/block/cciss\!c0d0/queue/scheduler

3. udev Rules for Device-Specific Parameters

For hardware-related settings that apply to specific devices:


# /etc/udev/rules.d/99-storage.rules
ACTION=="add", SUBSYSTEM=="block", KERNEL=="sd*", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop", ATTR{queue/nr_requests}="128"

For enterprise environments using tools like Ansible, consider this playbook example:


- name: Configure persistent sysfs parameters
  hosts: all
  tasks:
    - name: Ensure sysfs tune directory exists
      file:
        path: /etc/sysfs.d
        state: directory
        mode: 0755
        
    - name: Deploy RAID controller settings
      copy:
        dest: /etc/sysfs.d/raid.conf
        content: |
          block/cciss!c0d0/queue/nr_requests = 4096
          block/cciss!c0d0/queue/scheduler = deadline
          
    - name: Enable sysfsutils service
      service:
        name: sysfsutils
        enabled: yes
        state: started

Essential checks to validate your configuration:


# Verify service status
systemctl status sysfs-tune.service

# Check udev rules application
udevadm test /sys/block/sda

# Manual verification of parameters
cat /sys/block/sda/queue/nr_requests