摘要
目录用途 /etc/sysctl.kld.d/ 不是存放内核模块的位置,而是为通过 rc 机制加载的模块提供 sysctl 参数配置。
工作原理
- 模块通过 rc 机制(如 kld_list)加载成功后,系统立即读取对应的 conf 文件并应用参数
- 这与 sysctl.conf 是两条独立的流程
解决的问题
- sysctl.conf 在系统启动早期处理,此时某些模块可能尚未加载,导致参数设置失败
- sysctl.kld.d/ 解决了这一时序问题:模块加载完成后参数立即生效
注意事项
- 该机制仅在通过 rc.subr 途径加载模块时生效
- 内核自动加载模块时不会读取该目录
- 推荐配置方式:在 rc.conf 中使用 kld_list 加载模块,在对应的 conf 文件中设置参数
工作原理
当某个模块被 rc 机制加载成功后,系统立即读取 /etc/sysctl.kld.d/<模块名>.conf 并执行 sysctl -f 应用参数。
这与 /etc/sysctl.conf 是两条独立的流程:
时序关系
| 配置文件 | 应用时机 |
|---|---|
/etc/sysctl.conf |
multi-user 早期由 /etc/rc.d/sysctl 统一处理 |
/etc/sysctl.kld.d/*.conf |
模块被 rc 加载成功后立即应用 |
sysctl_lastload |
FreeBSD 14.x 在 multi-user 前二次应用,补充后加载模块的参数 |
官方手册明确提示:如果可装载模块提供了新的 sysctl,sysctl.conf 可能处理得太早。
配置方法
假设模块名为 foo,需设置 net.foo.bar=1。
1. 通过 rc.conf 加载模块
编辑 /etc/rc.conf:
kld_list+=" foo "
kld_list 在本地磁盘挂载完成后加载模块,比 /boot/loader.conf 时机更晚但更灵活。
参考:rc.conf(5)
2. 创建模块专属 sysctl 配置
创建 /etc/sysctl.kld.d/foo.conf:
net.foo.bar=1
模块加载成功后参数立即生效。
3. 手动验证
注意事项
/etc/sysctl.kld.d/仅在通过 rc.subr 途径加载模块时生效(如kld_list或 rc 脚本的load_kld)- 内核按需自动加载模块时不会读取该目录
- 若模块放在
/boot/loader.conf中早期加载,参数可在sysctl.conf中设置,但依赖性强的参数仍推荐使用sysctl.kld.d/
总结
解决"模块未加载时设置 sysctl 报错"的稳妥方案:
kld_list+=" 模块名 " # /etc/rc.conf
net.模块.参数=值 # /etc/sysctl.kld.d/模块名.conf
模块一加载,参数立即生效。