2021-06-06

WSL2下配置nfs服务器

导语

最近搞了一块stm32mp173的板子学习,第一步当然是要搭建Linux编译环境,要求开发板和Linux环境互通,能够使用NFS服务让开发板访问Linux编译环境下的文件。搭建Linux开发环境其实有不少选择,但我实在是不太想用VMware或者Hyper-V,因为它们一个是收费软件,一个又不太好用,所以我还是选择了WSL2,因为WSL2使用起来更为方便,而WSL内的文件系统与WINDOWS是互通的,加上vscode后更是能够完美配合,这些都是它的亮点。


关于WSL2的详细介绍可以看微软的介绍 比较 WSL 1 和 WSL 2 | Microsoft Docs


虽然WSL2真的非常好用,但也有坑。由于其网络拓扑发生了变化,导致其反而不能像WSL一样舒舒服服的网络互通。比如,我的PC与开发板都位于同一子网内,然后开发板能ping通我的PC,但无法ping通WSL内的IP,然而相反的,从WSL内ping开发板却是可以ping通的。经过大量实验,抓包,上网寻找解决方案,最后猜想这是因为windows上的WSL做了NAT,导致外面无法访问到WSL内部。本文是我在GITHUB上找到的一个最简单的,能够在WSL2下使用NFS服务(理论上其他服务也可以)的方法,希望对各位有帮助。


环境:
 WIN10 19043.985 21H1
 WSL2,UBUNTU 20.04.1 LTS
组网:
2021-06-06


步骤

(LINUX侧)安装NFS服务

参考这篇文章配置。

Ubuntu启动NFS出错出现错误* Not starting: portmapper is not running的解决方案_xiao哦草的博客-CSDN博客

例如我配置的/etc/exports如下,增加了insecure参数

/home/chasel *(insecure,rw,sync,no_subtree_check)

这个部分的安装比较简单,如果遇到错误可能是缺东西,按照提示操作就可以了。安装配置完成后,可以尝试从windows确认是否能使用NFS了,可以用windows自己的工具或者第三方工具,这里不详述了。

(Windows侧)配置网络

最为关键的部分来了。我翻了GitHub上的讨论,最后看到一个解决方案可以解决问题。

CzBiX/WSLHostPatcher: Dynamic patch WSL2 to listen port on any interface. (github.com)

直接找到release下载预编译的版本就可以了,解压开来是一个exe和一个dll文件,找个方便的地方存起来。

2021-06-06

配置windows防火墙

有两个选择:

  1. 直接关闭防火墙(不推荐)
  2. Win10下搜索“允许应用通过 windows 防火墙”,点击更改设置, 允许Microsoft Windows Subsystem for Linux Background Host通过
    2021-06-06

运行服务

开启WSL后,首先运行我们下载到的WSLHostPatcher.exe
比如我放在D盘下,WSL直接运行命令

chasel@DESKTOP-08BJ577:~$ /mnt/d/WSLHostPatcher.exe
Dll path: D:\WSLHostPatch.dll
Found 2 WSL host
Patched 2

然后运行

chasel@DESKTOP-08BJ577:~$ sudo rpcbind
[sudo] password for chasel:
chasel@DESKTOP-08BJ577:~$ sudo /etc/init.d/nfs-kernel-server start
 * Exporting directories for NFS kernel daemon...                                                                [ OK ]
 * Starting NFS kernel daemon                                                                                    [ OK ]

没有看到错误信息就可以了
在开发板上运行命令挂载文件系统:

mkdir wsl
mount -t nfs -o nolock,vers=3 10.0.0.5:/home/chasel wsl

顺利的话应该就可以通过开发板上的wsl目录访问文件了
为了方便使用,还可以将上述命令服务的启动写到~/.profile文件中,这样启动wsl的时候就能自动开启nfs服务了。


原理分析

WSL2下网络访问由上面提到的Windows Subsystem for Linux Background Host提供,即wslhost.exe。默认情况下,当在WSL2中启动了一个服务,那么你只能在PC本地访问WSL2中的服务,如果从网络中另一个设备访问WSL2中的服务,请求不会被转发到WSL2中。
分析WSLHostPatcher的源码很简单,可以看到WSLHostPatcher.exe先找到所有wslhost.exe进程然后hook它们的bind函数,无论参数传入什么,bind的目标总变为0.0.0.0,这样就总会监听网络上所有IP的报文。


后记

上面的方法虽然基本解决我的需求,但还是有一些不完美的地方:

1. 从设备还是无法ping通WSL2的IP
2. 有时候突然不能使用。我的解决方法就是重启一下电脑。有时候重启也没有用,我也不知道怎么回事,过了一个小时就好了。我感觉可能和防火墙有关,有时候更新了系统就会突然出现问题,非常玄学,不过大体来说都是稳定能用的。另外如果你安装的过程中出现问题,也建议你在windows环境下运行 wsl --shutdown或者直接重启电脑。

上一篇:WSL2与VMware不兼容问题解决


下一篇:windows 10 中安装 WSL2