问题现象
在使用嵌入式设备通过 NFS 挂载 rootfs 时,网络已经通了(能 ping 通主机),环境变量也配置完成,但内核启动后卡在挂载阶段:
约 30 秒后出现挂载失败信息:
结论是:目标板没有成功挂载到主机导出的 NFS 根文件系统。
结论
在 WSL2 中,NFS 相关服务有时不会处于可用状态。每次使用 NFS 启动前,先重建运行目录并重启 rpcbind 与 nfs-kernel-server,再重新导出共享目录,可稳定恢复挂载。
解决方案
新建脚本(例如 start_nfs.sh):
#!/bin/bash
sudo mkdir -p /run/sendsigs.omit.d
sudo service rpcbind restart
sudo service nfs-kernel-server restart
sudo exportfs -arv
赋予执行权限并运行:
chmod +x start_nfs.sh
./start_nfs.sh
然后再启动开发板进行 rootfs 挂载。
原因分析
1. WSL2 默认并不总是自动拉起完整服务链
在传统 Ubuntu(物理机/虚拟机)里,系统初始化阶段会按顺序拉起系统服务,NFS 相关组件通常能自动就绪。
WSL2 的启动机制与传统 Linux 主机不同,很多服务不会像服务器发行版那样“开机即稳定可用”。因此,rpcbind、nfs-kernel-server 可能在当前会话中未正确就绪,需要手动重启。
可用以下命令确认当前 PID 1:
ps -p 1 -o comm=
你的环境显示为 init(WSL 的初始化进程),这也解释了为什么服务行为与传统 Ubuntu 有差异。
2. /run 是易失目录,重启后会清空
/run 挂载在 tmpfs 上,属于内存文件系统。WSL 会话关闭或重启后,其内容会消失。
rpcbind 运行依赖 /run 下的若干运行时路径;当这些路径缺失时,服务可能启动异常。脚本中的 mkdir -p /run/sendsigs.omit.d 就是在补齐该类运行目录。
注意:目录应为 /run/sendsigs.omit.d,不是 /run/sendsigs.omit/d。
验证现象如下:
上图是运行完脚本后,下图是重启WSL2之后
重启后发现缺少了rpcbind、rpcbind.lock、rpcbind.pid、rpcbind.sock、sendsigs.omit.d、sudo文件。
3. NFS 依赖 RPC 注册,启动顺序很关键
NFS 服务依赖 RPC 机制进行端口与服务注册。
如果 rpcbind 未先正确运行,后续 nfs-kernel-server 的注册状态就可能异常,最终导致客户端挂载失败。
脚本中这三步的作用分别是:
service rpcbind restart:重置 RPC 端口映射服务。service nfs-kernel-server restart:重启 NFS 服务并重新注册。exportfs -arv:重新加载导出目录配置并输出详细信息,便于确认导出是否生效。
结束
如果经常用 NFS 启动开发板,建议在每次进入 WSL 开发会话后先执行一次该脚本。当然也可以把这个脚本写在一些启动文件中,让每次开启一个会话自动执行,这里不多赘述。