使用systemd-networkd时NFS根文件系统无DNS服务器问题咨询
我之前调试Yocto构建的NFS根文件系统时,也碰到过一模一样的问题——内核阶段能通过DHCP拿到DNS,但systemd启动后就丢了。结合systemd-networkd和resolved的工作机制,给你整理几个实用的排查方向和解决办法:
1. 先确认内核是否真的拿到了DNS信息
内核通过ip=dhcp参数获取的网络配置会存在/run/systemd/netif/leases/目录下的网卡对应文件里。先登录开发板,检查这个文件:
# 替换成你的实际网卡名,比如eth0、enp0s2 cat /run/systemd/netif/leases/eth0
如果文件里能看到DNS=开头的字段,说明内核已经成功拿到DNS,问题出在systemd的配置上;如果没有,那得先排查DHCP服务器或者U-Boot参数的问题。
2. 给网卡配置强制DHCP DNS获取
默认情况下,systemd-networkd可能不会自动启用DHCP的DNS获取功能。你需要给目标网卡创建一个网络配置文件,比如/etc/systemd/network/10-eth0.network(数字前缀决定优先级,越小越优先),内容如下:
[Match] Name=eth0 # 匹配你的网卡名称 [Network] DHCP=yes [DHCPv4] UseDNS=yes UseDomains=yes
这个配置会告诉systemd-networkd,从DHCP服务器拿到的DNS信息要同步给systemd-resolved。保存后重启服务:
systemctl restart systemd-networkd
3. 修复/etc/resolv.conf的软链接
Yocto构建的系统有时候默认的/etc/resolv.conf是静态文件,不是指向systemd-resolved的动态配置,导致resolved的DNS信息无法被应用层读取。检查并修复:
# 如果是静态文件就删掉 rm -f /etc/resolv.conf # 创建软链接到resolved的 stub 配置 ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf # 重启resolved服务 systemctl restart systemd-resolved
之后用resolvectl status命令就能看到加载的DNS服务器了,也可以用ping google.com测试域名解析是否正常。
4. 尝试在U-Boot参数中显式指定DNS
如果上面的方法都没效果,可以在U-Boot的内核启动参数里直接指定DNS服务器,强制传递到用户空间:
root=/dev/nfs nfsroot=192.168.x.x:/Path/To/Sysroot,vers=3,tcp rootwait ro ip=dhcp dns=192.168.x.x # 替换成你的DHCP服务器DNS地址
这种方法属于“兜底”方案,能绕过systemd-networkd的配置问题直接让系统拿到DNS。
5. 检查Yocto构建时的systemd配置
最后,确保你的Yocto构建环境已经正确启用了systemd-networkd和resolved的支持。在local.conf里添加这些配置:
# 启用systemd作为初始化管理器 DISTRO_FEATURES += "systemd" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED += "sysvinit" # 开启systemd的resolved和networkd组件 PACKAGECONFIG:append:pn-systemd = " resolved networkd"
如果之前没加过这些,重新构建Sysroot后再测试,避免因为构建时没编译相关组件导致功能缺失。
内容的提问来源于stack exchange,提问作者daly

