WSL 中如何用 mount -t drvfs 手动挂载 Windows 驱动器并理解提权与非提权挂载点?
2026/9/12 11:00:30 网站建设 项目流程

WSL 中如何用 mount -t drvfs 手动挂载 Windows 驱动器并理解提权与非提权挂载点?

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

在 WSL 中,Windows 驱动器默认以挂载点形式出现在/mnt目录下(指向驱动器根目录)。当默认挂载点不满足需求——例如想把C:挂到自定义目录、或挂载一个 UNC 路径——可以用mount -t drvfs手动完成挂载。同时,WSL 在发行版内部用两套挂载命名空间区分提权(管理员级)和非提权(用户级)上下文,这决定了你的手动挂载会连接哪一个 plan9 文件服务。以下内容基于 WSL 仓库的技术文档(drvfs.md)与文档指向的实现源码整理。

挂载前需要了解的默认状态

  • WSL 提供的 Windows 驱动器挂载点默认位于/mnt,指向 Windows 驱动器根目录。
  • 在 WSL2 发行版中,当一个 session leader 被创建时,wslservice.exe 会启动一个 plan9 文件服务,WSL2 虚拟机内的发行版通过它来挂载 Windows 驱动器。这一机制仅适用于 WSL2 发行版。
  • 只要 Windows 侧的 plan9 服务在运行,Linux 侧随时可以用mount挂载 Windows 驱动器,无需重启发行版。
  • 发行版初始化时,init 的常规任务之一也是挂载drvfs驱动器;每个发行版运行在独立的 mount/pid/UTS 命名空间中,但/mnt/wsl挂载点在全部发行版之间共享。

手动挂载一条 Windows 驱动器

文档给出的标准示例是把 C 盘挂载到自定义挂载点:

mount -t drvfs C: /tmp/my-mount-point

执行前注意两点:

  1. 目标挂载点目录需要已存在。mount.drvfs内部会先校验目标目录是否可用,目录不存在时直接失败。
  2. C:只是示例源,可替换为实际要挂载的 Windows 驱动器或路径。

命令成功时正常退出;失败时会在 stderr 输出形如mount: <错误描述>的信息,退出码非零。

mount -t drvfs实际执行了什么

这条命令并不是普通内核模块挂载,而是由 WSL 自带的一个入口处理的:

  • /usr/sbin/mount.drvfs是指向/init的符号链接。/init启动后根据argv[0]判断要运行哪个入口点:当argv[0]mount.drvfs时,/init执行mount.drvfs入口(见 MountDrvfsEntry())。
  • 根据发行版配置,mount.drvfs会把驱动器挂载为drvfs(WSL1),或plan9virtio-plan9virtiofs(WSL2),具体取决于.wslconfig。也就是说,用户侧命令始终是mount -t drvfs,底层实际的文件系统类型可能不同。
  • 参数个数不足 3 个(缺少源和目标)时按错误用法处理,退出码为 1;挂载失败时退出码为 32(见 exit code 常量定义)。
  • 在 WSL2 的 plan9 路径下,以/\开头的 UNC 风格源路径会被转换后通过 plan9 协议挂载(见 MountPlan9)。
  • 当配置为 virtiofs 时,若向宿主添加 virtiofs 共享失败,实现会自动回退到 Plan9 路径完成挂载(见 MountVirtioFs)。

提权与非提权挂载点的区别

这是理解手动挂载行为的关键部分,机制描述来自 drvfs.md:

  • WSL 在发行版内部区分从提权(管理员级)上下文创建和从非提权(用户级)上下文创建的 Linux 进程。实现方式是发行版内存在两个独立的 mount namespace:一个提供对 Windows 驱动器的提权访问,另一个提供非提权访问。
  • 当某个 Linux 进程被创建时,wslservice.exe判断其提权状态,并通知init在相应的 mount namespace 中创建该进程。
  • 发行版创建时,wslservice.exe通过LX_INIT_CONFIGURATION_INFORMATION消息告知创建该发行版的进程是否提权,init据此先挂载提权版或非提权版的 plan9 服务器。
  • 之后,当未挂载的那个命名空间中创建第一条命令时,wslservice.exe会向init发送LxInitMessageRemountDrvfs消息,让init补挂另一个命名空间。即另一侧的挂载点是按需延迟挂载的,而不是启动时就同时存在。
  • 在 virtiofs 场景下,两个服务器分别对应 tagdrvfs(非提权)和drvfsa(提权),定义见 lxinitshared.h。
  • mount.drvfs入口在没有被显式指定时使用哪个服务器由 IsDrvfsElevated() 决定:它先检查环境变量WSL_DRVFS_ELEVATED,取值为1时强制使用提权服务器,0时强制使用非提权服务器;未设置该变量时,通过 interop 服务器查询当前上下文应使用的端口;若无法建立该连接,则回退到非管理员 DrvFs 端口。该环境变量在发行版启动早期 interop 服务器尚未就绪时也会由 init 使用(定义见 util.h)。

对你的实际影响是:同一个mount -t drvfs C: <目标>命令,在不同提权状态下执行时,连接的是不同的 plan9/virtiofs 服务器实例,获得的驱动器访问权限级别也相应不同。

如何判断挂载成功或失败

  • 退出码 0 表示挂载成功;1 表示用法错误(参数不足);32 表示挂载失败。
  • 失败时观察 stderr:mount.drvfs会输出mount: <strerror>形式的错误行。
  • 若怀疑是 Windows 侧问题(例如/mnt共享访问异常),可查看Microsoft.Windows.Plan9.Server日志,这是 Windows plan9 服务的日志,用于访问/mnt/共享相关场景,说明见 debugging.md。

限制与适用边界

  • “创建 session leader 时启动 plan9 文件服务”这一小节仅适用于 WSL2 发行版;WSL1 发行版的mount.drvfs直接以drvfs文件系统类型挂载。
  • 手动挂载的前提是 Windows plan9 服务在运行,且发行版内init正常工作;发行版的挂载相关行为见 init.md。
  • 涉及 WSL2 虚拟机与发行版之间挂载交互的服务端逻辑位于 WslCoreInstance.cpp,Linux 侧实现位于 src/linux/init/drvfs.cpp,可供进一步阅读。

【免费下载链接】WSLWindows Subsystem for Linux项目地址: https://gitcode.com/GitHub_Trending/ws/WSL

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询