試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

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。

使用したバージョン:

*1:VMware Playerのバージョン2.5系からはカーネルモジュールがインストールされていないときに自動的にビルドされるようになっているのだが、カーネルの開発パッケージ(デスクトップ向けには「kernel-desktop-devel-latest」というパッケージがある)が入っていても別の問題により失敗している