Manjaro yay 安装 Vmware workstation 缺少 vmmon 和vmnet 模块

Manjaro install Vmware workstation build vmmon vmnet modules Failed

在用yay 安装 vmware-workstation16 一直失败, 已经成功生成了 vmware-workstation16-16.2.5-9-x86_64.pkg.tar.zst 但是在安装完成后运行

1
sudo modprobe -a vmw_vmci vmmon

却找不到 vmmon 模块, 通过查看安装过程发现在编译 vmmon 和 vmnet 模块的时候出错了, 仔细查看错误日志 /var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/make.log 可以看到如下报错信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.c: In function ‘VNetBridgeReceiveFromVNet’:
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/vmnetInt.h:44:39: error: ‘dev_base_lock’ undeclared (first use in this
 function); did you mean ‘device_lock’?
   44 | #define dev_lock_list()    read_lock(&dev_base_lock)
      |                                       ^~~~~~~~~~~~~
./include/linux/rwlock.h:56:48: note: in definition of macro ‘read_lock’
   56 | #define read_lock(lock)         _raw_read_lock(lock)
      |                                                ^~~~
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.c:587:4: note: in expansion of macro ‘dev_lock_list’
  587 |    dev_lock_list();
      |    ^~~~~~~~~~~~~
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/vmnetInt.h:44:39: note: each undeclared identifier is reported only on
ce for each function it appears in
   44 | #define dev_lock_list()    read_lock(&dev_base_lock)
      |                                       ^~~~~~~~~~~~~
./include/linux/rwlock.h:56:48: note: in definition of macro ‘read_lock’
   56 | #define read_lock(lock)         _raw_read_lock(lock)
      |                                                ^~~~
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.c:587:4: note: in expansion of macro ‘dev_lock_list’
  587 |    dev_lock_list();
      |    ^~~~~~~~~~~~~
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.c: In function ‘VNetBridgeUp’:
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/vmnetInt.h:44:39: error: ‘dev_base_lock’ undeclared (first use in this
 function); did you mean ‘device_lock’?
   44 | #define dev_lock_list()    read_lock(&dev_base_lock)
      |                                       ^~~~~~~~~~~~~
./include/linux/rwlock.h:56:48: note: in definition of macro ‘read_lock’
   56 | #define read_lock(lock)         _raw_read_lock(lock)
      |                                                ^~~~
/var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.c:898:4: note: in expansion of macro ‘dev_lock_list’
  898 |    dev_lock_list();
      |    ^~~~~~~~~~~~~
make[4]: *** [scripts/Makefile.build:229: /var/lib/dkms/vmware-workstation16/16.2.5_20904516/build/vmnet-only/bridge.o] Error 1
make[4]: *** Waiting for unfinished jobs....

原因

是因为当前正在使用的Linux 内核太新了, 已经把 dev_lock_list 换成了 rtnl_lock(), 把 dev_unlock_list 换成了 rtnl_unlock()

解决办法

根据 PKGBUILD 文件的以下几行

1
2
3
4
5
  for module in vmmon vmnet; do
    tar -xf "vmware-vmx/lib/modules/source/$module.tar" -C "$dkms_dir"
    msg "Patching $module module for DKMS"
    patch -p2 --read-only=ignore --directory="$dkms_dir/$module-only" < "$srcdir/$module.patch"
  done

可以知道, 用于编译 vmmon 和 vmnet 的源码在 vmware-vmx/lib/modules/source/ 目录下, 并且会通过 vmmon.patch 和 vmnet.patch 打补丁之后再编译
那么解决办法就来了, 我们把源码改好之后再生成一个新的补丁, 替换掉 vmnet.patch 然后再安装就可以了

把源码复制到一个新的文件夹并解压, 然后建一个git 仓库并初始化

1
2
3
4
5
6
7
8
cd ~/.cache/yay/vmware-workstation16
mkdir module_src
cp src/extracted/vmware-vmx/lib/modules/source/vmnet.tar .
tar xf vmnet.tar
cp ../vmnet.patch .
git init
git add . 
git commit -m "init"

给源码打上补丁

1
patch -p2  --read-only=ignore --directory=vmnet-only < ./vmnet.patch

修改源码

1
vim vmnet-only/vmnetInt.h +44

修改部分如下:

生成新补丁并替换掉原来的旧补丁

1
2
git diff > my_vmnet.patch
cp my_vmnet.patch ../vmnet.patch

重新安装Vmware Workstation

1
2
cd ..
makepkg -si --skipchecksums

之所以加 –skipchecksums 是因为 vmnet.patch 已经更改了, checksum 变了, 加 –skipchecksums 可以路过检查