默认情况下,VirtualBox 的共享文件夹特性在 Windows 下工作是有问题的,如果你运行一些需要符号连接(Symlink)的程序,比如默认设置的 yarn 或者 npm,由于 npm 包在安装之后会在 ./node_modules/.bin
创建在 package.json
中定义好的应用入口的符号连接,它会在最后一步报错。这是一个困扰了非常久的问题,我因此在这几年也一直在用 vmdk(虚拟磁盘)挂载到虚拟机上来存数据,但这样是一种非常不安全的使用方式,因为 vmdk 备份起来太难受了,粒度太大没法增量,硬盘一旦出问题很容易整个虚拟磁盘 GG,今天无意中想到了一个关键的 Windows 的权限问题(下面会说),这个问题才得以解决。
下面来讲一下如何解决这个问题。
对相应虚拟机实例启用符号链接特性
如果想正常使用符号链接,需要对虚拟机设置 VBoxInternal2/SharedFoldersEnableSymlinksCreate/<share_folder_name>
这个 extradata,这里顺带一提,对于 vagrant,这个选项只要你运行 vagrant up
之后这个选项便是自动设置好的。设置这个 extradata 可以使用 VboxManage,这个工具在 Windows 下是和 VirtualBox 图形界面在一个相同目录的,可以使用 Powershell cd 到这个目录,然后运行
.\VBoxManage.exe setextradata "[虚拟机名]" VBoxInternal2/SharedFoldersEnableSymlinksCreate/共享文件夹名称 1
注意这个共享文件夹名称是你在 VirtualBox 中设置共享时对应的“共享文件夹名称”一栏的内容,不是相应文件夹的路径或者文件夹名称。
配置 Windows 权限,允许非 Administrator 用户创建符号连接
到这里基本很多教程都结束了。但也可能很多人发现这么做之后创建符号连接依然是无法使用的状态,会报错
ln: failed to create symbolic link "name": Protocol error
这是因为 Windows 的默认配置,非 Administrator 用户是没有创建符号连接权限的(至少在我的 Win10 20h2 上是这样,不太清楚其他版本是怎么设计的)
解决这个问题有两种办法
VBoxHeadless
等相关实际承载虚拟机实例的进程用 Administrator 用户运行。- 配置本地安全策略,允许其他用户创建符号连接
至于第一种方法,我不太了解 Windows 的一些权限与进程模型设计,我尝试直接管理员运行 VirtualBox GUI 发现似乎并没有生效,并且看对应进程也没在相应用户下。
于是我使用了第二种方法即去改本地安全策略。方法如下
- 运行
secpol.msc
打开本地安全策略 - 依次进入本地策略->用户权限分配,选择创建符号连接
- 添加你当前的用户,保存退出,注销当前用户重新登陆
所以说就很奇怪啊!为什么 Windows 默认连符号连接的权限都不给低权帐户啊!
我按照这样测试之后尝试创建符号连接已经没有任何问题了。
附上我目前的软件版本
- Win10 20h2
- VirtualBox 6.1.18