Parallels Desktop 14.0.1 安装 ubuntu desktop 14.04.6 后无法安装 Parallels tools
刚开始安装14.04.6之后一切正常。谁知道在"apt-get update && apt-get dist-upgrade"之后发现鼠标的指针不见了。。。
一通百度,没有找到任何有效解决方案。
一筹莫展的时候,直觉告诉我问题可能跟ParallelsTools有关,于是想着重新安装试试。
结果这货告诉我安装过程有错误。。
假装这里有个图(忘了截图了)
果然有问题!!!
百度了一下,从这个帖子得到启发,我也去看看log。
cat /var/log/parall
看到如下报错信息。
make[2]: Entering directory `/usr/src/linux-headers-4.4.0-148-generic'
CC [M] /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg.o
CC [M] /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.o
/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c: In function 'tg_req_map_user_pages':
/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c:111:2: warning: passing argument 7 of 'get_user_pages' from incompatible pointer type [enabled by default]
got = prl_get_user_pages(
^
In file included from include/linux/scatterlist.h:7:0,
from include/linux/dmapool.h:14,
from include/linux/pci.h:1232,
from /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c:7:
include/linux/mm.h:1222:6: note: expected 'struct vm_area_struct **' but argument is of type 'struct page **'
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
^
/usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c:111:2: error: too many arguments to function 'get_user_pages'
got = prl_get_user_pages(
^
In file included from include/linux/scatterlist.h:7:0,
from include/linux/dmapool.h:14,
from include/linux/pci.h:1232,
from /usr/lib/parallels-tools/kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c:7:
include/linux/mm.h:1222:6: note: declared here
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
按照提示搜索了一下源码目录。
grep prl_get_user_pages -rn ./
得到如下结果。
ctu@u14pd:~/Desktop/tools$ /
./kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_call.c:111: got = prl_get_user_pages(
./kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_compat.h:186:#define prl_get_user_pages(_1, _2, _3, _4, _5) \
./kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_compat.h:189:#define prl_get_user_pages(_1, _2, _3, _4, _5) \
./kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_compat.h:192:#define prl_get_user_pages(_1, _2, _3, _4, _5) \
查看源码(kmods/prl_tg/Toolgate/Guest/Linux/prl_tg/prltg_compat.h),找到定义处。
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) || defined(OPENSUSE_4_4_76)
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(_1, _2, (_3) ? FOLL_WRITE : 0, _4, _5)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(_1, _2, _3, 0, _4, _5)
#else
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(current, current->mm, _1, _2, _3, 0, _4, _5)
#endif
可以看出这里是根据内核版本的不同,使用不同的方法来映射参数。从上面的报错信息可以得知get_user_pages函数是定义在内核源码的mm.h文件里边的(哦,到这里要说明一下,我的内核是4.4.0-148版本)。
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
unsigned int gup_flags, struct page **pages,
struct vm_area_struct **vmas);
数一下参数数量,上边映射以后是八个,下边参数定义的是七个,明显有问题。怎么改呢?问题很显然是linux内核版本演进函数接口发生变迁导致的。联想到dist-upgrade之前,ParallelsTools是能够正常安装。所以,早个稍微老一点的linux内核源码对比一下。
4.2.0-y mm.h
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
int write, int force, struct page **pages,
struct vm_area_struct **vmas);
对比后知道原先的write和force两个参数,貌似合成了一个gup_flags。那就知道怎么改了。
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) || defined(OPENSUSE_4_4_76)
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(_1, _2, (_3) ? FOLL_WRITE : 0, _4, _5)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(_1, _2, _3, 0, _4, _5)
#else
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(current, current->mm, _1, _2, _3, 0, _4, _5)
#endif
// 上面的代码修改为
#define prl_get_user_pages(_1, _2, _3, _4, _5) \
get_user_pages(current, current->mm, _1, _2, _3, _4, _5)
再安装试试
安装成功,鼠标指针也出来了。