在 Homelab 圈子里,折腾 Unraid 的终点往往是“省电”和“静音”。
许多人的 Unraid 服务器上插满了各种 PCIe 扩展卡:万兆网卡、多口 SATA 扩展卡、甚至用于推流或 AI 的独立显卡。这些设备在白天提供了强大的性能,但在深夜(比如凌晨 1 点到 6 点),服务器基本处于闲置状态。此时,这些 PCIe 设备依然在空载消耗 5W 到 20W 不等的电量,累积起来是一笔不小的开销。
在 Linux(Unraid 基于 Slackware)下,我们无法像关灯一样直接物理切断 PCIe 插槽的供电,但我们可以通过内核的 Runtime PM(运行期电源管理)和 PCIe 热插拔(Hotplug)机制,在软件层面将设备卸载并强行推入最深的 D3cold 节能状态,并在清晨自动重新扫描并唤醒它们。
以下是全套优雅、安全、可落地的自动化脚本方案。
核心原理:Remove 与 Rescan
Linux 内核允许我们动态地从 PCI 总线树中“移除(Remove)”某个设备。当我们向设备的 remove 接口写入 1 时,内核会卸载该设备的驱动程序,并协调 ACPI 电源管理将该 PCIe 插槽置于最低功耗状态(如果主板和设备支持,会进入 D3cold 状态,此时功耗接近于 0)。
当需要重新使用该设备时,我们只需向 PCI 总线写入 rescan(重新扫描),系统就会重新发现设备、加载驱动并恢复正常工作。
第一步:定位你的 PCIe 设备
在开始写脚本前,必须精准定位目标设备的 PCI 地址(BDF,即 Bus:Device.Function)。
- 打开 Unraid 的终端(Terminal)。
- 输入以下命令列出所有的 PCI 设备:
输出会类似这样:lspci -D0000:00:01.0 PCI bridge: Intel Corporation 6th-10th Gen Core Processor PCIe Controller (x16) 0000:01:00.0 VGA compatible controller: NVIDIA Corporation GP107 [GeForce GTX 1050 Ti] (rev a1) 0000:04:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01) - 记下你需要夜间关闭的设备地址。例如:
- 万兆网卡:
0000:04:00.0 - 独立显卡:
0000:01:00.0
- 万兆网卡:
⚠️ 高危警告: 绝对不要将此操作应用在系统引导盘所在的 USB 控制器、系统盘/阵列盘连接的 HBA 卡/SATA 控制器上!否则会导致系统崩溃或数据丢失。
第二步:编写自动化脚本
我们将使用 Unraid 自带的 User Scripts(用户脚本) 插件来实现定时运行。如果还未安装该插件,请先在 Unraid 应用市场(Community Applications)搜索并安装。
进入 Unraid 的 Tools(工具) -> User Scripts,新建两个脚本。
脚本 1:夜间优雅停用并断电(Sleep_PCIe)
新建脚本,命名为 Sleep_PCIe,写入以下内容:
#!/bin/bash
# -------------------------------------------------------------------------
# Unraid 夜间 PCIe 设备深度节能脚本
# -------------------------------------------------------------------------
# 在此处填写你需要关闭的 PCIe 设备地址(支持填入多个,用空格隔开)
TARGET_DEVICES=("0000:04:00.0" "0000:01:00.0")
echo "================ $(date '+%Y-%m-%d %H:%M:%S') ================"
echo "开始执行夜间 PCIe 设备节能降噪流程..."
for dev in "${TARGET_DEVICES[@]}"; do
DEV_PATH="/sys/bus/pci/devices/$dev"
if [ -e "$DEV_PATH" ]; then
echo "发现目标设备: $dev"
# 1. 尝试开启 D3cold 允许状态
if [ -e "$DEV_PATH/power/d3cold_allowed" ]; then
echo "1" > "$DEV_PATH/power/d3cold_allowed"
echo "已开启 d3cold 允许状态"
fi
# 2. 将电源控制设置为 auto
if [ -e "$DEV_PATH/power/control" ]; then
echo "auto" > "$DEV_PATH/power/control"
echo "已设置电源管理为 auto"
fi
# 3. 从 PCI 树中安全移除设备(触发最深节能状态)
echo "正在卸载并移除设备 $dev ..."
echo "1" > "$DEV_PATH/remove"
# 再次确认是否成功移除
if [ ! -e "$DEV_PATH" ]; then
echo "成功:设备 $dev 已下线并进入休眠状态。"
else
echo "警告:设备 $dev 移除失败,请检查是否有进程或虚拟机占用。"
fi
else
echo "未发现设备 $dev ,可能已经处于离线状态。"
fi
echo "------------------------------------------------"
done
echo "所有指定的 PCIe 设备已完成节能处置。"
脚本 2:清晨重新扫描并启用(Wake_PCIe)
新建脚本,命名为 Wake_PCIe,写入以下内容:
#!/bin/bash
# -------------------------------------------------------------------------
# Unraid 晨间 PCIe 设备唤醒脚本
# -------------------------------------------------------------------------
echo "================ $(date '+%Y-%m-%d %H:%M:%S') ================"
echo "正在重新扫描 PCI 总线以唤醒休眠设备..."
# 触发内核重新扫描 PCI 总线
echo "1" > /sys/bus/pci/rescan
# 验证设备是否重新上线(以你配置的设备为例,可自行修改验证)
sleep 2
CHECK_DEVICES=("0000:04:00.0" "0000:01:00.0")
for dev in "${CHECK_DEVICES[@]}"; do
if [ -e "/sys/bus/pci/devices/$dev" ]; then
echo "成功:设备 $dev 已重新上线并正常加载驱动。"
else
echo "错误:未能成功唤醒设备 $dev ,请查看系统日志。"
fi
done
echo "PCIe 唤醒流程执行完毕。"
第三步:配置定时计划(Cron)
在 User Scripts 界面中,为这两个脚本设置定时执行任务。
Sleep_PCIe脚本:- 将运行时间设置为 Custom(自定义)。
- Cron 表达式填写:
0 1 * * *(代表每天凌晨 1:00 执行)。
Wake_PCIe脚本:- 将运行时间设置为 Custom(自定义)。
- Cron 表达式填写:
0 6 * * *(代表每天早晨 6:00 执行)。
避坑指南与进阶技巧
1. 虚拟机(VM)与容器(Docker)的绑定问题
如果你的独显已经直通(Passthrough)给了某个 Windows 虚拟机,或者网卡正在被某个运行中的 Docker 容器直接独占,请勿在它们运行期间执行移除脚本。
- 优雅的解决方式:在
Sleep_PCIe脚本的最开头,加入停止相关虚拟机或容器的命令。
在# 停止名为 Win10 的虚拟机 virsh destroy Win10 2>/dev/null # 停止某个特定容器 docker stop qbittorrent 2>/dev/nullWake_PCIe脚本的最后,再重新启动它们:virsh start Win10 docker start qbittorrent
2. 为什么重新扫描后设备没有恢复?
部分极少数老旧、山寨的 PCIe 设备(如某些便宜的非标多口网卡)或非标主板,其固件对 PCI Hotplug 标准支持较差,断电后可能无法通过 rescan 重新拉起。
- 测试方法:在正式配置定时任务前,请手动在 Web 界面点击 Run Script 测试一次
Sleep和Wake。如果运行Wake_PCIe后,设备能够正常出现在 Unraid 的硬件列表中且功能完好,说明你的硬件完美支持这种优雅的省电方案。
3. 主板 BIOS 设置配合
要达到极致的省电效果,建议重启进入 Unraid 主板 BIOS,检查并开启以下设置:
- ASPM (Active State Power Management):设置为 Enabled 或 L1/L1.1/L1.2(不要设为 Disabled 或 Auto)。
- PCIe Speed:若无极高带宽需求,可将闲置插槽的 Gen 速率从 Gen4/Gen3 限制到 Gen2,空载功耗也会有微妙的下降。
- PCIe Tunneling / ACPI States:确保允许系统控制 PCIe 设备状态。