VMware Horizon Linux 云桌面 DKMS的BUG填坑记​

天锦 发表于 女票们的新建与保养 分类,标签:

揪到VMware一个BUG,吼开心

接上回《VMware Horizon Linux 云桌面 USB重定向配置》说,起初我为了省事儿,手动编译了kernel之后成功安装了VHCI驱动,实现了USB重定向功能。放手就没在管DKMS的事儿。然而,雷埋下了早晚要炸。没过几天,我随手就是一个apt update便更新了内核,VHCI驱动自然也掉了。按官网的手册一步一步部署DKMS并安装VHCI模块。安装完成之后,再次安装viewagent,得到一下报错:

Failed to install USB redirection module, because the system doesn't meet the following requirement(s):
VHCI driver should be installed.
USB Redirection depends on the VHCI module, and Horizon Agent does not contain the compiled VHCI module for cuurent Linux kernel 4.15.0-96-generic.
Please build your own VHCI module and install it to Linux kernel.
Please refer to product guide for detailed information.

可是我已经按照手册用DKMS安装了最新kernel对应的module,用modinfo也能查得到:

[root@ubuntu ~] modinfo usb-vhci-iocifc 
filename:       /lib/modules/4.15.0-99-generic/updates/dkms/usb-vhci-iocifc.ko
version:        1.15.0
license:        GPL
author:         Michael Singer <michael@a-singer.de>
description:    User-mode IOCTL-interface for USB VHCI driver
srcversion:     697AFFF0CE7CA15B5597E50
depends:        usb-vhci-hcd
retpoline:      Y
name:           usb_vhci_iocifc
vermagic:       4.15.0-99-generic SMP mod_unload

此处省略N多尝试……

打开install_viewagent.sh,通过搜索报错文字"VHCI driver should be installed."定位到函数verify_usb_environment这里。在文件2956行处。BUG就在这里。

verify_usb_environment()
{
   local arch="`uname -i`"
   local meet_all_requirements="yes"
   local meet_arch="no"
   local meet_libudev="no"
   local meet_vhci="yes"
   local version=
   if [ "${arch}" = "x86_64" ]; then
      meet_arch="yes"
      verify_udev_environment
      if [ "$?" = "0" ];then
         meet_libudev="yes"
      fi
   fi
   if [ "${meet_libudev}" = "yes" ]; then
      stat /lib/modules/`uname -r`/kernel/drivers/usb/host/usb-vhci-hcd.ko > /dev/null 2>&1 && \
      stat /lib/modules/`uname -r`/kernel/drivers/usb/host/usb-vhci-iocifc.ko > /dev/null 2>&1
      if [ "$?" = "0" ]; then
         version="`modinfo -F"version" usb-vhci-iocifc`"
         if [ "$version" !=  "1.15.0" ]; then
            echo_term "Error: VHCI modules installed in the system maybe not the correct version. Please refer to product guide to install VHCI"
            exit
         fi
      else
         extract_vhci
         if [ "$?" = "0" ]; then
            echo_term "Warning: USB Redirection depends on the VHCI module, and Horizon Agent contains the compiled VHCI module for cuurent Linux kernel `uname -r`."
            echo_term "         Installing VHCI driver ..."
            echo_term "         You need compile your own VHCI module and install it to Linux kernel if you upgrade or downgrade Linux kernel after Horizon Agent installation."
            echo_term "         Please refer to product guide for detailed information."
         else
            meet_vhci="no"
         fi
      fi
   fi
   if [ "${meet_arch}" = "no" ] ||
      [ "${meet_vhci}" = "no" ] ||
      [ "${meet_libudev}" = "no" ]; then
      meet_all_requirements="no"
   fi
   if [ "${meet_all_requirements}" = "no" ]; then
      echo_term -n "Failed to install USB redirection module, "
      echo_term "because the system doesn't meet the following requirement(s):"
      error_num=1
      if [ "${meet_arch}" = "no" ]; then
         echo_term "The USB feature has only been supported on the 64-bit system currently."
      fi
      if [ "${meet_vhci}" = "no" ]; then
         echo_term "VHCI driver should be installed."
         echo_term "USB Redirection depends on the VHCI module, and Horizon Agent does not contain the compiled VHCI module for cuurent Linux kernel `uname -r`."
         echo_term "Please build your own VHCI module and install it to Linux kernel."
         echo_term "Please refer to product guide for detailed information."
      fi
      if [ "${meet_libudev}" = "no" ]; then
         echo_term "libudev.so.0 should be installed."
      fi
      exit
   else
      echo_log "The host system meets the USB requirements."
   fi
}

可以分析出安装脚本是判断一下两个文件是否存在来确定VHCI是否安装(文件2974行):

stat /lib/modules/`uname -r`/kernel/drivers/usb/host/usb-vhci-hcd.ko > /dev/null 2>&1 && \
stat /lib/modules/`uname -r`/kernel/drivers/usb/host/usb-vhci-iocifc.ko > /dev/null 2>&1

再看dkms.conf中的配置:

PACKAGE_NAME="usb-vhci-hcd"
PACKAGE_VERSION=1.15
MAKE_CMD_TMPL="make KVERSION=$kernelver"
CLEAN="$MAKE_CMD_TMPL clean"
BUILT_MODULE_NAME[0]="usb-vhci-iocifc"
DEST_MODULE_LOCATION[0]="/kernel/drivers/usb/host"
MAKE[0]="$MAKE_CMD_TMPL"
BUILT_MODULE_NAME[1]="usb-vhci-hcd"
DEST_MODULE_LOCATION[1]="/kernel/drivers/usb/host"
MAKE[1]="$MAKE_CMD_TMPL"
AUTOINSTALL="YES"

通过modinfo得到的信息显示模块虽然被安装了但是并没有放置到指定的位置"/kernel/drivers/usb/host",而是将自动安装的模块放置到了"/updates/dkms/"下,查找了一番资料发现DKMS在Debian系的发行版系统中,即使你定义了DEST_MODULE_LOCATION也会将其重写成"/updates/dkms/"并将模块放置在"/updates/dkms/"目录下。install_viewagent.sh中并没有检测这个目录,产生了我在Ubuntu下通过DKMS安装了VHCI模块,但是脚本显示没有安装了逻辑错误。可见VMware在测试时并没有测试Ubuntu或者说是Ubuntu下用DKMS安装VHCI模块这一场景。

我给出的解决方法就是把"/updates/dkms/"目录下的两个.ko模块文件cp到"/kernel/drivers/usb/host"中去就可以了。安装可以正常安装。

对于这个BUG的看法:其实没必要用stat /lib/modules/`uname -r`/kernel/drivers/usb/host/usb-vhci-iocifc.ko去检查模块文件是否存在,直接用modinfo -F"version" usb-vhci-iocifc去检测模块版本就行了,如果模块安装了便会得到模块版本号,没有正确安装则会得到报错。

ViewAgent版本:

VMware-horizonagent-linux-x86_64-7.12.0-15765535.tar.gz

0 篇评论

发表我的评论