SOLVED: VMware Tools __devexit_p Error on Linux Kernel 3.8 and Earlier
If you run a current version of VMware Workstation, VMware Server, ESXi or VMware Fusion with a recent Linux kernel as a guest, you’ve most-likely run into this already.
UPDATE: If you’re using Linux kernel 3.11.0, see my updated blog post for the patch and fix for that revision.
Using 2.6.x kernel build system. make: Entering directory `/tmp/modconfig-N9AMbf/vmci-only' /usr/bin/make -C /lib/modules/3.8.0-19-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. \ MODULEBUILDDIR= modules make[1]: Entering directory `/usr/src/linux-headers-3.8.0-19-generic' CC [M] /tmp/modconfig-N9AMbf/vmci-only/linux/vmciKernelIf.o CC [M] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.o /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:127:4: error: implicit declaration of function ‘__devexit_p’ [-Werror=implicit-function-declaration] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:127:4: error: initializer element is not constant /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:127:4: error: (near initialization for ‘vmci_driver.remove’) /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:1754:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘vmci_probe_device’ /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:1982:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘vmci_remove_device’ /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:119:12: warning: ‘vmci_probe_device’ used but never defined [enabled by default] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:121:13: warning: ‘vmci_remove_device’ used but never defined [enabled by default] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:2063:1: warning: ‘vmci_interrupt’ defined but not used [-Wunused-function] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:2137:1: warning: ‘vmci_interrupt_bm’ defined but not used [-Wunused-function] /tmp/modconfig-N9AMbf/vmci-only/linux/driver.c:1717:1: warning: ‘vmci_enable_msix’ defined but not used [-Wunused-function] cc1: some warnings being treated as errors make[2]: *** [/tmp/modconfig-N9AMbf/vmci-only/linux/driver.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [_module_/tmp/modconfig-N9AMbf/vmci-only] Error 2 make[1]: Leaving directory `/usr/src/linux-headers-3.8.0-19-generic' make: *** [vmci.ko] Error 2 make: Leaving directory `/tmp/modconfig-N9AMbf/vmci-only'
Here’s the patch to fix it. Either cut-and-paste the code snippet below and save it to a file, or you can download it here.
--- vmci-only/linux/driver.c 2012-11-01 16:22:03.000000000 +0900 +++ vmci-only/linux/driver.c.patched 2013-03-01 04:21:08.402942111 +0900 @@ -124,7 +124,11 @@ static struct pci_driver vmci_driver = { .name = "vmci", .id_table = vmci_ids, .probe = vmci_probe_device, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) .remove = __devexit_p(vmci_remove_device), +#else + .remove = vmci_remove_device, +#endif }; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) @@ -1750,7 +1754,11 @@ vmci_enable_msix(struct pci_dev *pdev) / *----------------------------------------------------------------------------- */ -static int __devinit +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) + static int __devinit +#else + static int +#endif vmci_probe_device(struct pci_dev *pdev, // IN: vmci PCI device const struct pci_device_id *id) // IN: matching device ID { @@ -1978,7 +1986,11 @@ vmci_probe_device(struct pci_dev *pdev, *----------------------------------------------------------------------------- */ -static void __devexit +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) + static void __devexit +#else + static void +#endif vmci_remove_device(struct pci_dev* pdev) { struct vmci_device *dev = pci_get_drvdata(pdev);
And here's how to apply it and fix the problem:
- Mount your VMware Tools ISO somewhere
# mkdir /tmp/cdrom # mount /dev/sr0 /tmp/cdrom
- Extract the tarball to /tmp/
# cd /tmp/cdrom # tar zxvf VMwareTools-9.0.5-1065307.tar.gz -C /tmp/
- Change into the VMware Tools directory that was just created
# cd /tmp/vmware-tools-distrib/
- Patch the tree with the above patch
# cd lib/modules/source/ # tar -xvf vmci.tar # patch -p0 < /tmp/vmware-tools-linux-kernel-3.8_vmci_pci_hotplug_struct.patch
- Tar up the patched source so we can rebuild using the new tarball
# tar -cf vmci.tar vmci-only/
- Now let's rebuild it!
# cd /tmp/vmware-tools-distrib/ # ./vmware-install.pl
If you've done it right, it will build cleanly:
Using 2.6.x kernel build system. make: Entering directory `/tmp/modconfig-qs1htj/vmci-only' /usr/bin/make -C /lib/modules/3.8.0-19-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. \ MODULEBUILDDIR= modules make[1]: Entering directory `/usr/src/linux-headers-3.8.0-19-generic' CC [M] /tmp/modconfig-qs1htj/vmci-only/linux/driver.o CC [M] /tmp/modconfig-qs1htj/vmci-only/linux/vmciKernelIf.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciContext.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciDatagram.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciDoorbell.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciDriver.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciEvent.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciHashtable.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciQPair.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciQueuePair.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciResource.o CC [M] /tmp/modconfig-qs1htj/vmci-only/common/vmciRoute.o CC [M] /tmp/modconfig-qs1htj/vmci-only/driverLog.o LD [M] /tmp/modconfig-qs1htj/vmci-only/vmci.o Building modules, stage 2. MODPOST 1 modules CC /tmp/modconfig-qs1htj/vmci-only/vmci.mod.o LD [M] /tmp/modconfig-qs1htj/vmci-only/vmci.ko make[1]: Leaving directory `/usr/src/linux-headers-3.8.0-19-generic' /usr/bin/make -C $PWD SRCROOT=$PWD/. \ MODULEBUILDDIR= postbuild make[1]: Entering directory `/tmp/modconfig-qs1htj/vmci-only' make[1]: `postbuild' is up to date. make[1]: Leaving directory `/tmp/modconfig-qs1htj/vmci-only' cp -f vmci.ko ./../vmci.o make: Leaving directory `/tmp/modconfig-qs1htj/vmci-only'
That's it! This same patch will work with all previous kernels, as well as those up to the most current 3.8 kernels.
If you're rebuilding your kernel modules using the command vmware-install.pl from the VMware Tools package, remember to use the following, to force a module rebuild:
vmware-install.pl --clobber-kernel-modules=vmci \ --clobber-kernel-modules=vsock \ --clobber-kernel-modules=vmxnet3 \ --clobber-kernel-modules=pvscsi \ --clobber-kernel-modules=vmmemctl
Note: I haven't tested Linux kernel 3.10.9 or later yet, but I will shortly and update this post to reflect those results (see here for the fix for the 3.11.0 kernel).
Good luck!