1. 升级DSM 7.0.1之后,为什么2.5G网卡和硬盘休眠会同时出问题
把一台稳定跑了两年多的黑群晖DS918+从DSM 6.2.3推到DSM 7.0.1,很多人以为只是点一下"更新"的事。结果重启之后发现两件事:一是2.5G网卡直接不认了,网络里只剩主板自带的千兆口;二是硬盘休眠彻底失效,明明设置了20分钟无操作休眠,硬盘却一直在转,功耗和噪音都上来了。这两个问题看似不相关,其实根子都在同一个地方——DSM 7.0.1更换了内核版本和驱动签名机制。
DSM 6.2.x时代用的是Linux 4.4内核,第三方驱动(比如常见的RTL8125、Intel I225系列2.5G网卡驱动)只要编译成对应的ko文件,扔进/lib/modules里,再用insmod加载就能用。但DSM 7.0.1把内核升到了4.4.180(部分版本是4.4.302),并且引入了更严格的模块签名校验和驱动白名单机制。简单说,群晖官方不希望你在系统里随便加载未签名的第三方驱动,所以默认情况下,你自己编译的2.5G网卡驱动要么加载失败,要么加载后系统不认。
硬盘休眠失效的原因更隐蔽。DSM 7.0.1修改了磁盘活动检测逻辑,系统会定期扫描所有存储卷和共享文件夹的元数据。如果你在黑群晖上用了非官方引导(比如常见的redpill或arpl),引导本身会模拟一些硬件信息,这些模拟信息在DSM 7.0.1下会被系统频繁轮询,导致硬盘始终处于"有活动"状态,自然无法进入休眠。另外,2.5G网卡驱动如果加载不完整,系统会不断尝试重新识别设备,这个轮询过程也会唤醒硬盘。
所以这两个问题必须一起解决,单独修一个没用。下面我按实际操作顺序,从引导准备、驱动编译、加载配置到休眠修复,一步步拆开讲。
1.1 先确认你的黑群晖到底跑在什么内核和引导上
动手之前,先SSH进系统,把底细摸清楚。很多人一上来就找驱动,结果编译出来的版本对不上,白折腾。
# 查看内核版本 uname -a # 查看当前已加载的网卡驱动 lsmod | grep -E "r8125|igc|r8168|e1000e" # 查看网卡硬件信息 lspci | grep -i ethernet # 查看引导类型(redpill或arpl) cat /proc/cmdline重点看uname -a输出的内核版本。DSM 7.0.1常见的有两个分支:4.4.180+和4.4.302+。这两个版本对应的驱动源码编译参数不同,尤其是4.4.302对内核头文件的要求更严格。如果你用的是arpl引导,它自带了一个驱动注入功能,但默认只注入了官方支持的网卡驱动,2.5G的RTL8125和Intel I225都不在列表里。
另外注意lspci的输出。RTL8125的硬件ID通常是10ec:8125,Intel I225-V是8086:15f3,I225-LM是8086:15f2。记下这个ID,后面编译驱动时要确认驱动源码是否支持。
提示:如果你用的是redpill引导,
/proc/cmdline里会看到syno_hw_version=DS918+之类的参数。这个参数决定了系统加载哪些硬件抽象层,也影响硬盘休眠行为。后面修休眠时会用到。
1.2 2.5G网卡驱动在DSM 7.0.1下的加载限制
DSM 7.0.1对第三方驱动做了两层限制。第一层是模块签名:系统启动时会校验/lib/modules/下的ko文件是否有群晖的签名,没有签名的模块默认拒绝加载。第二层是驱动白名单:即使你强行加载了未签名模块,系统的网络管理服务(synonetd)也不会把它纳入管理,表现为ifconfig能看到网卡,但DSM的网络界面里不显示,也无法配置IP。
绕过这两层限制的常见做法有两种:一是修改引导,在启动参数里加入allow_unsupported_modules=1,让内核跳过签名校验;二是把驱动编译进引导的initramfs里,让系统在启动早期就加载,绕过运行时的白名单检查。第一种方法简单但不够稳定,系统小版本更新后可能失效;第二种方法麻烦但一劳永逸,推荐用第二种。
硬盘休眠的问题和驱动加载是联动的。如果你只解决了网卡驱动但没处理休眠,系统会因为网卡驱动的轮询而无法休眠。反过来,如果你只修了休眠但网卡没驱动,系统会不断尝试识别网卡,同样唤醒硬盘。所以这两个必须一起搞。
2. 编译RTL8125和Intel I225驱动并注入引导的完整流程
这一章是实操核心。我以arpl引导为例,因为它的驱动注入机制最成熟,社区维护也活跃。如果你用的是redpill,思路一样,只是注入方式不同。
2.1 准备编译环境:用Docker跑一个匹配内核的编译容器
不要在黑群晖本机上编译,因为DSM 7.0.1默认没有gcc和内核头文件,装起来很麻烦。最省事的办法是在另一台Linux机器(或者黑群晖的Docker里)跑一个编译容器。
# 在任意Linux机器上拉取编译镜像 docker pull synocommunity/dsm7-build:latest # 启动容器,挂载工作目录 docker run -it --name dsm7build \ -v /path/to/workdir:/workdir \ synocommunity/dsm7-build:latest /bin/bash进入容器后,先下载对应内核版本的源码。DSM 7.0.1的内核源码群晖没有完全开源,但社区从GPL发布包里提取了足够编译驱动的头文件。你可以从arpl的GitHub仓库里找到dsm7-kernel-headers目录,直接clone下来。
cd /workdir git clone https://github.com/arpl/arpl.git cd arpl/dsm7-kernel-headers # 根据你的内核版本选择分支 git checkout 4.4.180然后下载RTL8125驱动源码。Realtek官方有发布,但版本较老,建议用社区维护的r8125分支。
cd /workdir git clone https://github.com/realtek/r8125.git cd r8125 # 查看可用版本,选最新的稳定版 git tag git checkout v9.009.00Intel I225的驱动是igc,内核4.4.180默认不带,需要从Intel官方或社区移植。
cd /workdir git clone https://github.com/intel/igc.git cd igc git checkout 5.10.22.2 编译参数怎么设:Makefile里的关键选项
编译驱动不是make一下就完事,DSM 7.0.1的内核配置和标准Linux不一样。你需要指定正确的内核路径和交叉编译参数。
对于RTL8125:
cd /workdir/r8125/src make -C /workdir/arpl/dsm7-kernel-headers/4.4.180 \ M=$(pwd) \ ARCH=x86_64 \ CROSS_COMPILE= \ CONFIG_R8125=m \ modules编译成功后会在src目录下生成r8125.ko。用modinfo检查一下:
modinfo r8125.ko | grep -E "vermagic|depends"vermagic必须包含4.4.180+,否则加载会失败。如果显示的是4.4.180没有加号,说明内核头文件版本不对,需要重新checkout。
对于Intel I225:
cd /workdir/igc/src make -C /workdir/arpl/dsm7-kernel-headers/4.4.180 \ M=$(pwd) \ ARCH=x86_64 \ CONFIG_IGC=m \ modules同样检查igc.ko的vermagic。
注意:编译时如果报错
error: implicit declaration of function 'pci_alloc_irq_vectors',说明内核头文件版本太老,需要打补丁。arpl仓库里有一个patches目录,里面有现成的补丁文件,直接patch -p1 < patches/igc-4.4.180.patch即可。
2.3 把ko文件注入arpl引导的initramfs
arpl引导的驱动注入有两种方式:一种是在编译引导时通过--add-driver参数加入,另一种是手动修改initramfs。推荐第一种,因为arpl会自动处理依赖和加载顺序。
在arpl的编译目录下:
cd /workdir/arpl ./build.sh --add-driver /workdir/r8125/src/r8125.ko \ --add-driver /workdir/igc/src/igc.ko \ --ds918p \ --dsm-version 7.0.1编译完成后会生成一个新的引导镜像。把它写入U盘,替换原来的引导盘,重启黑群晖。
重启后SSH进去,检查驱动是否加载:
lsmod | grep -E "r8125|igc" ip link show如果看到r8125和igc都在列表里,并且ip link显示了2.5G网卡对应的接口(通常是eth1或eth2),说明驱动加载成功。接下来在DSM的网络界面里配置IP即可。
2.4 驱动加载后网卡不显示在DSM界面里的处理
有时候lsmod和ip link都正常,但DSM的"网络"面板里就是看不到2.5G网卡。这是因为synonetd服务没有把新接口纳入管理。解决办法是手动触发一次网络配置重载:
# 重启网络管理服务 synosystemctl restart synonetd # 或者手动把接口加入管理 synonetd --add-interface eth1如果还是不行,检查/etc/synoinfo.conf里的eth1_mtu和eth1_force参数。DSM 7.0.1默认只管理eth0,其他接口需要手动在配置文件里声明。在/etc/synoinfo.conf末尾加上:
eth1_mtu="1500" eth1_force="1"然后重启synonetd。这个坑我踩过两次,第一次以为是驱动没编译好,折腾了半天才发现是配置文件的问题。
3. 硬盘休眠失效的根因排查:从引导参数到系统轮询
网卡搞定之后,硬盘休眠的问题就浮出水面了。DSM 7.0.1下黑群晖的硬盘休眠失效,通常有四个原因:引导参数不对、系统服务轮询、2.5G网卡驱动轮询、以及存储卷元数据扫描。我按排查顺序一个个说。
3.1 检查引导参数里的硬盘休眠相关选项
arpl引导在编译时可以指定--no-hdd-standby或--hdd-standby参数。如果你编译时没注意,默认可能是关闭休眠的。检查引导的grub.cfg:
cat /boot/grub/grub.cfg | grep -i standby如果看到syno_hdd_standby=0,说明休眠被禁用了。改成syno_hdd_standby=1,重新编译引导。
另外,DS918+的引导参数里有一个DiskIdxMap和SataPortMap,这两个参数决定了系统识别硬盘的顺序。如果设置不对,系统会认为有硬盘在"热插拔"状态,不断轮询,导致无法休眠。对于DS918+,常见的正确设置是:
DiskIdxMap=0000 SataPortMap=4如果你的主板有多个SATA控制器,SataPortMap要按实际接口数调整。比如两个控制器各4口,就写44。
3.2 揪出阻止休眠的系统服务:synoindexd和synocrond
DSM 7.0.1默认开启synoindexd(媒体索引服务)和synocrond(计划任务服务)。这两个服务会定期扫描硬盘上的文件,尤其是如果你装了Video Station或Photo Station,索引服务几乎一直在跑。
# 查看这些服务的状态 synosystemctl status synoindexd synosystemctl status synocrond # 临时停止(重启后会恢复) synosystemctl stop synoindexd synosystemctl stop synocrond如果停止后硬盘能休眠了,说明就是它们的问题。永久禁用需要修改服务配置:
# 禁用synoindexd synosystemctl disable synoindexd # 禁用synocrond synosystemctl disable synocrond但注意,禁用synoindexd后,Video Station和Photo Station的缩略图功能会失效。如果你需要这些功能,可以设置索引计划,只在特定时间段运行,避开你希望硬盘休眠的时间。
3.3 2.5G网卡驱动导致的硬盘唤醒:一个容易被忽略的细节
即使你禁用了索引服务,硬盘还是可能被2.5G网卡驱动唤醒。原因是r8125和igc驱动默认开启了中断合并和链路状态轮询,驱动会定期检查网卡链路状态,这个检查会触发系统活动,进而唤醒硬盘。
解决办法是调整驱动的模块参数:
# 查看当前参数 cat /sys/module/r8125/parameters/* # 临时调整(重启失效) echo 0 > /sys/module/r8125/parameters/eee_enable echo 1 > /sys/module/r8125/parameters/aspmeee_enable=0关闭节能以太网,aspm=1开启PCIe电源管理。这两个参数能显著降低网卡驱动的轮询频率。
永久生效需要在引导的modprobe.d里加配置文件。在arpl引导的/etc/modprobe.d/下新建r8125.conf:
options r8125 eee_enable=0 aspm=1 options igc InterruptThrottleRate=0然后重新编译引导。这个细节社区里很少有人提,但实测下来对硬盘休眠的稳定性提升很明显。
3.4 存储卷元数据扫描:btrfs的定时scrub
如果你用的是Btrfs文件系统,DSM 7.0.1默认会每月执行一次scrub(数据校验)。这个任务会持续读写硬盘,期间无法休眠。检查scrub计划:
# 查看scrub任务 btrfs scrub status /volume1 # 查看计划任务 cat /etc/crontab | grep scrub如果scrub正在运行,可以等它结束,或者调整计划到你不介意硬盘转的时间段。另外,Btrfs的commit间隔也会影响休眠。默认是30秒,可以改成300秒:
# 临时调整 echo 300 > /proc/sys/vm/dirty_writeback_centisecs永久生效需要加到/etc/sysctl.conf里。
4. 实测验证:怎么确认硬盘真的进入休眠了
修完上面这些,怎么知道硬盘到底休眠了没有?DSM的界面有时候不准,最好用命令行确认。
4.1 用hdparm和smartctl查看硬盘电源状态
# 查看硬盘是否在休眠 hdparm -C /dev/sda # 输出"standby"表示已休眠,"active/idle"表示还在转 # 用smartctl查看更详细的状态 smartctl -i -n standby /dev/sda如果smartctl返回Device is in STANDBY mode,说明休眠成功。如果返回Device is in ACTIVE or IDLE mode,说明还有活动。
4.2 用iotop和fatrace定位唤醒源
如果硬盘反复休眠又唤醒,用iotop看哪个进程在读写:
# 安装iotop(如果DSM里没有,用opkg或entware) opkg install iotop # 运行iotop,观察是否有进程在写盘 iotop -o -d 5更精确的方法是fatrace,它能追踪具体是哪个文件被访问:
# 安装fatrace opkg install fatrace # 监控所有文件访问 fatrace -f W运行后等几分钟,看输出里有没有频繁写盘的文件。常见的唤醒源包括/volume1/@synologydrive、/volume1/@database、以及Docker容器的日志文件。如果是Docker导致的,把容器日志目录挂载到SSD或者tmpfs上,避免写机械硬盘。
4.3 休眠稳定性测试:连续观察24小时
修完之后别急着收工,连续观察24小时。写个脚本每5分钟记录一次硬盘状态:
#!/bin/bash while true; do echo "$(date): $(hdparm -C /dev/sda | grep -o 'standby\|active/idle')" >> /tmp/hdd_status.log sleep 300 done第二天看日志,如果大部分时间是standby,说明修复成功。如果还是频繁active/idle,回到第3章重新排查。
5. 几个容易翻车的细节和我的个人经验
最后说几个实操中容易翻车的地方,都是我用时间和电费换来的教训。
第一,驱动编译时内核头文件版本必须和运行内核完全一致。我有一次用4.4.180的头文件编译,但系统实际跑的是4.4.180+,结果ko文件加载时报version magic mismatch。解决方法是uname -r看完整版本号,然后checkout对应的头文件分支。arpl仓库里通常有4.4.180+的单独分支,别搞混。
第二,arpl引导更新后驱动会丢失。每次arpl发布新版本,你重新编译引导时,之前注入的驱动不会自动保留。建议把驱动ko文件和编译参数写成一个脚本,每次更新引导后重新跑一遍。我现在的做法是把r8125.ko和igc.ko放在U盘的/drivers目录下,arpl编译时用--add-driver指向U盘路径,这样更新引导时不用重新编译驱动。
第三,硬盘休眠和Docker是天生冤家。如果你在黑群晖上跑Docker,容器日志、镜像层、卷数据都会频繁写盘。我的做法是把Docker的/var/lib/docker迁移到一块SSD上,机械硬盘只存冷数据。这样机械硬盘基本能稳定休眠,SSD也不怕频繁读写。
第四,DSM 7.0.1的小版本更新可能重置休眠配置。群晖在7.0.1之后又发了7.0.1-42218 Update 2和Update 3,每次更新都会覆盖/etc/synoinfo.conf和/etc/modprobe.d/下的自定义配置。更新前备份这两个目录,更新后对比恢复。我现在的习惯是每次DSM提示更新,先SSH进去把配置文件打包备份到U盘,更新完再恢复。
第五,2.5G网卡的实际速度受限于PCIe通道。如果你用的是PCIe转2.5G网卡,注意主板PCIe插槽的带宽。有些老主板的PCIe 2.0 x1插槽只有500MB/s带宽,跑不满2.5G(理论312MB/s)。实测下来,PCIe 2.0 x1跑2.5G网卡大概能到280MB/s左右,够用但别指望满速。要满速需要PCIe 3.0 x1或更高。
第六,休眠后网络唤醒(WOL)可能失效。如果你依赖WOL远程开机,硬盘休眠后网卡可能也进入低功耗状态,导致WOL包收不到。解决办法是在/etc/modprobe.d/r8125.conf里加上options r8125 wol=1,强制网卡保持WOL监听。但这样网卡功耗会略高,而且可能影响硬盘休眠。需要你自己权衡,我的做法是WOL和休眠二选一,远程访问用其他方式解决。
这些经验不一定适用于所有黑群晖配置,但大方向是通的。DSM 7.0.1对第三方硬件的限制越来越严,以后升级DSM 7.1或7.2可能还要重新折腾。建议把编译好的驱动和配置文件都存档,下次升级时直接复用,能省不少时间。