VMware製品のカーネルモジュールがLinux 2.6.29に対してビルドできない件とその対処
Mandriva Linux 2009.1にした後VMware Playerをインストールしたときにモジュールのビルドに失敗しているのに気づいた。*1
Using 2.6.x kernel build system. make: ディレクトリ `/tmp/vmware-root/modules/vmmon-only' に入ります make -C /lib/modules/2.6.29.1-desktop-4mnb/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules make[1]: ディレクトリ `/usr/src/linux-2.6.29.1-desktop-4mnb' に入ります CC [M] /tmp/vmware-root/modules/vmmon-only/linux/driver.o In file included from /tmp/vmware-root/modules/vmmon-only/linux/driver.c:31: /tmp/vmware-root/modules/vmmon-only/./include/compat_wait.h:78: error: conflicting types for ‘poll_initwait’ include/linux/poll.h:67: error: previous declaration of ‘poll_initwait’ was here /tmp/vmware-root/modules/vmmon-only/linux/driver.c: In function ‘LinuxDriverSyncCallOnEachCPU’: /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1423: error: too many arguments to function ‘smp_call_function’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c: In function ‘LinuxDriver_Ioctl’: /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1987: error: ‘struct task_struct’ has no member named ‘euid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1987: error: ‘struct task_struct’ has no member named ‘uid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1988: error: ‘struct task_struct’ has no member named ‘fsuid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1988: error: ‘struct task_struct’ has no member named ‘uid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1989: error: ‘struct task_struct’ has no member named ‘egid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1989: error: ‘struct task_struct’ has no member named ‘gid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1990: error: ‘struct task_struct’ has no member named ‘fsgid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:1990: error: ‘struct task_struct’ has no member named ‘gid’ /tmp/vmware-root/modules/vmmon-only/linux/driver.c:2007: error: too many arguments to function ‘smp_call_function’ make[1]: ディレクトリ `/usr/src/linux-2.6.29.1-desktop-4mnb' から出ます make: ディレクトリ `/tmp/vmware-root/modules/vmmon-only' から出ます make[2]: *** [/tmp/vmware-root/modules/vmmon-only/linux/driver.o] エラー 1 make[1]: *** [_module_/tmp/vmware-root/modules/vmmon-only] エラー 2 make: *** [vmmon.ko] エラー 2 modinfo: could not find module vmmon
のようになり、モジュールビルドに失敗する。GUIウィンドウ上のメッセージからは情報がつかめなかった。
パッチは既に出回っていて
http://d.hatena.ne.jp/pyopyopyo/20090410/p1
のリンク先が良好に動作するとのこと。試してみると
$ patch -p1 < vmware-modules-2.6.29-portable.patch patching file vmblock-only/Makefile Hunk #1 succeeded at 122 (offset 9 lines). patching file vmci-only/Makefile Hunk #1 succeeded at 122 (offset 9 lines). patching file vmmon-only/include/x86apic.h Hunk #1 FAILED at 94. 1 out of 1 hunk FAILED -- saving rejects to file vmmon-only/include/x86apic.h.rej patching file vmmon-only/linux/driver.c patching file vmmon-only/linux/hostif.c Hunk #1 succeeded at 3424 (offset 1 line). Hunk #2 succeeded at 3538 (offset 1 line). Hunk #3 succeeded at 3662 (offset 1 line). patching file vmmon-only/Makefile Hunk #1 succeeded at 122 (offset 9 lines). patching file vmnet-only/Makefile Hunk #1 succeeded at 122 (offset 9 lines). patching file vmnet-only/netif.c patching file vsock-only/Makefile Hunk #1 succeeded at 122 (offset 9 lines).
となり、1箇所だけ適用できない部分があったものの
$ grep APIC_BASE_MSR -r *-only vmmon-only/include/x86apic.h.rej: #define APIC_BASE_MSR 0x1b vmmon-only/include/x86apic.h.rej: #define APIC_BASE_MSR 0x1b vmmon-only/include/x86apic.h.rej:+ #define APIC_BASE_MSR 0x800
モジュールのソースにこの値を使用したところはないため、影響はないと思われる。
パッチ適用作業を自動化するシェルスクリプトを作成したので下に貼り付ける(管理者権限で実行する必要がある)。
[任意]ファイル名: vmware-modules-updater-2.6.29.sh ライセンス: CC0
#! /bin/sh # vmware-modules-updater-2.6.29.sh # CC0 PATH=/bin:/usr/bin MODULEDIR=/usr/lib/vmware/modules/source/ MODULES="vmblock vmci vmmon vmnet vsock" PATCH_URL="http://communities.vmware.com/servlet/JiveServlet/download/1213985-20879/vmware-modules-2.6.29-portable.patch" cd /tmp/ WORKDIR=$(mktemp -d vmware-modules-updater-2.6.29-XXXXXXXXXX) cd ${WORKDIR}/ for MOD in ${MODULES}; do tar xf ${MODULEDIR}/${MOD}.tar done if ! wget -O patch ${PATCH_URL}; then echo "Error: cannot download patch" >&2 rm /tmp/${WORKDIR} -fr exit 1 fi ls patch -p1 < patch for MOD in ${MODULES}; do tar cf ${MOD}.tar ${MOD}-only mv ${MODULEDIR}/${MOD}.tar{,.old} done mv *.tar ${MODULEDIR}/ rm /tmp/${WORKDIR} -fr echo "Update succeeded"
古いファイルは/usr/lib/vmware/modules/source/以下の.oldファイルに名前変更しているが、必要がなければ削除してもOK。
使用したバージョン: