VMware製品のカーネルモジュールがLinux 2.6.26に対してビルドできない件とその対処
Linux(カーネル)のバージョン2.6.25のときに続いて、2.6.26でも、VMware製品のカーネルモジュールがビルドできない問題が起きた。
(2008/9/8)vmware-any-any-update117d.tar.gzを使用したところ、そのまま問題なくビルドできた。下は一般的な適用例。
$ tar zxf [vmware-any-any-update117d.tar.gzの場所] $ cd vmware-any-any-update117d/ $ sudo ./runme.pl
Gentooのvmware-modules-1.0.0.20を使用する場合は下のebuildを使用する(any-anyの.tar.gzファイルは手動でダウンロード後配置)。
ファイル名: vmware-modules-1.0.0.20-r1.ebuild
# Copyright 1999-2008 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ inherit linux-mod vmware-mod KEYWORDS="~amd64 ~x86" VMWARE_VER="VME_V605" # THIS VALUE IS JUST A PLACE HOLDER ANY_VER="117d" VMWARE_MOD_DIR="vmware-any-any-update${ANY_VER}" VMWARE_MODULE_LIST="vmmon vmnet vmblock" SRC_URI="vmware-any-any-update${ANY_VER}.tar.gz" RESTRICT="fetch" pkg_nofetch() { elog "Please download vmware-any-any-update${ANY_VER}.tar.gz from:" elog "http://groups.google.com/group/vmkernelnewbies/files" elog "then put this file in ${DISTDIR}" } src_unpack() { unpack ${A} cd "${S}" for mod in ${VMWARE_MODULE_LIST}; do unpack ./"${VMWARE_MOD_DIR}"/${mod}.tar convert_to_m "${S}"/${mod}-only/Makefile done }
また、VMware Playerのバージョン2.0.5(Build 109488)でも、Linux 2.6.26でビルドが通るようになっている。
以下、以前の内容。
エラーメッセージ
vmware-any-any-update117cのvmblock
2008/7/27現在の最新のvmware-any-any-updateであるvmware-any-any-update117c.tar.gzを使用すると、vmmonとvmnetはビルドできたが、vmblockは失敗した。
Using 2.6.x kernel build system. make: Entering directory `/tmp/work/vmblock-only' make -C /lib/modules/2.6.26-tuxonice/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/ . modules make[1]: Entering directory `/usr/src/linux-2.6.26-tuxonice' CC [M] /tmp/work/vmblock-only/linux/block.o CC [M] /tmp/work/vmblock-only/linux/control.o /tmp/work/vmblock-only/linux/control.c: In function 'SetupProcDevice': /tmp/work/vmblock-only/linux/control.c:153: error: 'proc_root_fs' undeclared (first use in this function) /tmp/work/vmblock-only/linux/control.c:153: error: (Each undeclared identifier is reported only once /tmp/work/vmblock-only/linux/control.c:153: error: for each function it appears in.) /tmp/work/vmblock-only/linux/control.c: In function 'CleanupProcDevice': /tmp/work/vmblock-only/linux/control.c:213: error: 'proc_root_fs' undeclared (first use in this function) make[2]: *** [/tmp/work/vmblock-only/linux/control.o] Error 1 make[1]: *** [_module_/tmp/work/vmblock-only] Error 2 make[1]: Leaving directory `/usr/src/linux-2.6.26-tuxonice' make: *** [vmblock.ko] Error 2 make: Leaving directory `/tmp/work/vmblock-only'
Gentoo Linuxのvmware-modules(2.6.25対応)
Linux 2.6.25に対応したパッチの当たっているGentoo向けパッケージ(vmware-modules 1.0.0.20)では、2008/7/27現在Using 2.6.x kernel build system. make -C /usr/src/linux M=$PWD SRCROOT=$PWD/. modules make[1]: Entering directory `/usr/src/linux-2.6.26-tuxonice' make[1]: warning: jobserver unavailable: using -j1. Add `+' to parent make rule . CC [M] /var/tmp/portage/app-emulation/vmware-modules-1.0.0.20/work/vmmon-only /linux/driver.o /var/tmp/portage/app-emulation/vmware-modules-1.0.0.20/work/vmmon-only/linux/dri ver.c:197: error: unknown field 'nopage' specified in initializer /var/tmp/portage/app-emulation/vmware-modules-1.0.0.20/work/vmmon-only/linux/dri ver.c:198: warning: initialization from incompatible pointer type make[3]: *** [/var/tmp/portage/app-emulation/vmware-modules-1.0.0.20/work/vmmon- only/linux/driver.o] Error 1 make[2]: *** [_module_/var/tmp/portage/app-emulation/vmware-modules-1.0.0.20/wor k/vmmon-only] Error 2 make[1]: *** [sub-make] Error 2 make[1]: Leaving directory `/usr/src/linux-2.6.26-tuxonice' make: *** [vmmon.ko] Error 2
となってビルドに失敗する。
解決策
大変ありがたいことに、bugs.gentoo.org/show_bug.cgi?id=227303
にvmblock/vmmon/vmnetの全てに対するパッチ(vmware-modules-1.0.0.20-patches.tar.gz)がアップロードされている。このファイルに含まれるパッチはVMware Playerのバージョン2.0.4 build-93057*1に付属(vmware-player-distrib/lib/modules/source/以下)のtarファイルを展開したものに対して差分を取ったもの。*2
なお、vmblock-2.6.26.patchには機械語形式のモジュールなどの余計なファイルが含まれているため、手動でのビルドに使用する場合は一度vmblock-onlyディレクトリで「make clean」を実行したほうがよさそう。
なお、このパッチは、以下の事情により、そのまま公式のPortageツリーに入る予定はなさそう。
Gentoo Linuxのvmware-modulesを修正
以下、Gentoo Linuxの「vmware-modules」パッケージを修正してインストールする作業例。*3$ tar zxvf vmware-modules-1.0.0.20-patches.tar.gz vmblock-2.6.26.patch vmmon-2.6.26.patch vmnet-2.6.26.patch vmware-modules-1.0.0.20.ebuild.patch $ sudo mkdir -p [ローカルOverlay]/app-emulation/ 2>/dev/null $ sudo cp -a /usr/portage/app-emulation/vmware-modules/ [ローカルOverlay]/app-emulation/ $ sudo cp vm*2.6.26.patch [ローカルOverlay]/app-emulation/vmware-modules/files/patches/ $ cd [ローカルOverlay]/app-emulation/vmware-modules/ $ sudo patch -p0 < [vmware-modules-1.0.0.20.ebuild.patchの場所] patching file vmware-modules-1.0.0.20.ebuild $ sudo ebuild vmware-modules-1.0.0.20.ebuild digest $ cd - $ rm vm*2.6.26.patch *.ebuild.patch vmware-modules-1.0.0.20-patches.tar.gz -f $ sudo emerge -av1 vmware-modules
一般的な修正方法
アップロードされている差分がVMware Playerの本体に付属しているソースと比較したものなので、本体の巨大な.tar.gzファイルを用意しなくてはならずに不便な気がしたため、パッチ適用済みの状態とvmware-any-any-update-117cのモジュールとの差分を取ったものを貼り付ける。*4Linux 2.6.26未満に対しては適用しないように注意。
[転載][任意]ファイル名: any-any-update117c-2.6.26.patch
diff -ur any-any-update117c/vmblock-only/linux/dentry.c 2.6.26/vmblock-only/linux/dentry.c --- any-any-update117c/vmblock-only/linux/dentry.c +++ 2.6.26/vmblock-only/linux/dentry.c @@ -112,8 +112,14 @@ LOG(4, "DentryOpRevalidate: [%s] no longer exists\n", iinfo->name); return 0; } - ret = actualNd.path.dentry && actualNd.path.dentry->d_inode; - path_put(&(actualNd.path)); + // FIXME: am comentat asta din cauza ca spune ca: 'struct nameidata' has no member named 'dentry' + // cel mai bine e daca gasesti patchul pentru vmware pentru kernelu ista, altfel se incep miracole +// ret = actualNd.dentry && actualNd.dentry->d_inode; + ret = 1; + + // FIXME: functia asta nu pre are prototip undeva declarat, credca e legat de vreun kernel mai vechi + // incearca asta: http://forums.fedoraforum.org/printthread.php?t=192282 +// path_release(&actualNd); LOG(8, "DentryOpRevalidate: [%s] %s revalidated\n", iinfo->name, ret ? "" : "not"); diff -ur any-any-update117c/vmblock-only/linux/filesystem.c 2.6.26/vmblock-only/linux/filesystem.c --- any-any-update117c/vmblock-only/linux/filesystem.c +++ 2.6.26/vmblock-only/linux/filesystem.c @@ -218,23 +218,6 @@ return ret; } -static struct inode *vmware_iget(struct super_block *sb, unsigned long ino) -{ - struct inode *inode; - inode = iget_locked(sb, ino); - if (!inode) - return ERR_PTR(-ENOMEM); - if (!(inode->i_state & I_NEW)) - return inode; - - unlock_new_inode(inode); - return inode; -/* -error: - iget_failed(inode); - return ERR_PTR(ret); -*/ -} /* *---------------------------------------------------------------------------- @@ -244,7 +227,7 @@ * Lookup or create a new inode. * * Inode creation in detail: - * Throughout the file system, we call the VFS vmware_iget() function to get a new + * Throughout the file system, we call the VFS iget() function to get a new * inode. This in turn invokes our file system's SuperOpAllocInode() * function, which allocates an inode info structure (VMBlockInodeInfo) * using the kernel's slab allocator. When a new slab is created, each @@ -252,7 +235,7 @@ * occurs only once per struct (e.g., when a struct from a slab is freed and * reused, the constructor is not invoked again). SuperOpAllocInode() then * returns the address of the inode struct that is embedded within the inode - * info we have allocated. vmware_iget() also invokes our SuperOpReadInode() + * info we have allocated. iget() also invokes our SuperOpReadInode() * function to do any further file system wide initialization to the inode, * then returns the inode to us (this function). * @@ -290,20 +273,14 @@ ASSERT(sb); - inode = vmware_iget(sb, ino); - -/* +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) + inode = iget_locked(sb, ino); +#else + inode = iget(sb, ino); +#endif if (!inode) { return NULL; } -*/ - - if (IS_ERR(inode)) { -/* - ret = PTR_ERR(inode); -*/ - goto error_inode; - } iinfo = INODE_TO_IINFO(inode); if (!iinfo) { @@ -328,8 +305,13 @@ return inode; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) iinfo->actualDentry = actualNd.path.dentry; - path_put(&(actualNd.path)); + path_put(&actualNd.path); +#else + iinfo->actualDentry = actualNd.dentry; + path_release(&actualNd); +#endif return inode; diff -ur any-any-update117c/vmblock-only/linux/super.c 2.6.26/vmblock-only/linux/super.c --- any-any-update117c/vmblock-only/linux/super.c +++ 2.6.26/vmblock-only/linux/super.c @@ -37,9 +37,9 @@ #else static void SuperOpClearInode(struct inode *inode); #endif -/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) static void SuperOpReadInode(struct inode *inode); -*/ +#endif #ifdef VMW_STATFS_2618 static int SuperOpStatfs(struct dentry *dentry, struct compat_kstatfs *stat); #else @@ -54,9 +54,9 @@ #else .clear_inode = SuperOpClearInode, #endif -/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) .read_inode = SuperOpReadInode, -*/ +#endif .statfs = SuperOpStatfs, }; @@ -142,7 +142,7 @@ *---------------------------------------------------------------------------- */ -/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) static void SuperOpReadInode(struct inode *inode) // IN: Inode to initialize { @@ -152,7 +152,7 @@ iinfo->nameLen = 0; iinfo->actualDentry = NULL; } -*/ +#endif /* diff -ur any-any-update117c/vmblock-only/linux/vmblockInt.h 2.6.26/vmblock-only/linux/vmblockInt.h --- any-any-update117c/vmblock-only/linux/vmblockInt.h +++ 2.6.26/vmblock-only/linux/vmblockInt.h @@ -64,7 +64,8 @@ #endif /* __KERNEL__ */ #define VMBLOCK_CONTROL_MODE S_IRUSR | S_IFREG -#define VMBLOCK_CONTROL_PARENT proc_root_fs +//#define VMBLOCK_CONTROL_PARENT proc_root_fs + #define VMBLOCK_CONTROL_PARENT create_proc_entry( "fs", S_IFDIR, 0 ) /* * Our modules may be compatible with kernels built for different processors.
(処理上無関係な)改行の追加のみの修正やvmblock-only/modules.orderに関する差分は外している。
以下、vmware-any-any-update117cをもとにした修正例。
$ tar zxf [vmware-any-any-update117c.tar.gzの場所] $ for f in vmware-any-any-update117c/*.tar; do tar xf ${f}; done $ patch -p1 < [any-any-update117c-2.6.26.patchの場所] patching file vmblock-only/linux/dentry.c patching file vmblock-only/linux/filesystem.c patching file vmblock-only/linux/super.c patching file vmblock-only/linux/vmblockInt.h $ for f in vmblock vmmon vmnet; do tar cf vmware-any-any-update117c/${f}.tar ${f}-only; rm ${f}-only -fr; done $ cd vmware-any-any-update117c/ $ sudo ./runme.pl
tarファイルを更新してrunme.plを実行するように書いているが、(手元の)Gentooではrunme.plは使用しないため、実際に実行しての確認はしていない。
更に新しい問題が...
これでモジュールのビルドはできるようになり、動作自体も正常に行われる。このように、VMware Playerが動作していることが分かる。
しかし、これまでにない新しい問題が発生した。詳しくは別記事。
参考URL:
使用したバージョン: