xfyyzy

摘要

目录用途 /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 是两条独立的流程:

系统启动

rc.d/sysctl

应用 sysctl.conf

rc 加载模块

应用 sysctl.kld.d/模块.conf

sysctl_lastload 补充应用

时序关系

配置文件 应用时机
/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 可能处理得太早。

参考:sysctl.conf(5)

配置方法

假设模块名为 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

模块加载成功后参数立即生效。

参考:rG5ac2a874d070

3. 手动验证

kldload foo
sysctl -f /etc/sysctl.kld.d/foo.conf
sysctl net.foo.bar

注意事项

  • /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

模块一加载,参数立即生效。