One of the most annoying aspects of running Linux in VM's on VMware ESX/Server/Workstation is the requirement to reinstall the VMware tools modules after every kernel upgrade. This is made even more annoying by the fact that the vmware-config-tools.pl script disables network connectivity thus making it difficult to run via remote SSH connections. A similar problem also affects Linux hosts running VMware Server/Workstation since those products also require running a similar script (vmware-config.pl) to reinstall the required modules after every kernel upgrade on the host OS.
Wouldn't it be nice if the VMware modules just automatically reinstalled themselves when a new kernel was booted, requiring no special attention from the system admin? Read on for my simple method of accomplishing this.
I've seen several solutions for this problem on the VMware forums and the web, but most involved custom scripts, which always seemed buggy, and others used DKMS which still required manual effort to keep the DKMS packages updated and also required a full development environment to compile modules even on systems where VMware already included compiled modules. Some smart scripting could probably work around that, but it seemed annoying and required installing DKMS on all systems as well. I wanted something that was as close to no footprint as possible.
Now, most admins note about the "--default" option which can be used when running the vmware-config-tools.pl (or vmware-config.pl) script to cause the script automatically answer all the questions with the default answer. All we need is a way to run this automatically when a new kernel is booted. It turns out, at least with Redhat systems (and I suspect other systems), that this is exceptionally easy. For legacy reasons the Redhat init scripts check for the existence of a file called /etc/rc.modules and, if it exist, execute it. The file is typically a simple shell script and thus all we need is a simple method for detecting if the currently booting kernel already has the VMware modules installed and, if not, run the vmware config script with the "--default" option.
Here's the script that I'm currently using with Linux VM's running in VMware ESX/Server:
#!/bin/bash
if [ ! -e /lib/modules/`uname -r`/misc/.vmware_installed ]; then
/usr/bin/vmware-config-tools.pl --default
touch /lib/modules/`uname -r`/misc/.vmware_installed
fi
And this is what I'm using for Linux hosts running VMware Workstation/Server:
#!/bin/bash
if [ ! -e /lib/modules/`uname -r`/misc/.vmware_installed ]; then
/usr/bin/vmware-config.pl --default
touch /lib/modules/`uname -r`/misc/.vmware_installed
fi
Simply place these lines in /etc/rc.modules and make sure it is executable and your good to go. Note that it's possible you may already have a rc.modules file so in that case you should just add the lines to the existing file. When you install a new kernel and reboot the ".vmware_installed" file will be missing from the /lib/modules directory for that kernel and it will run the vmware-config-tools.pl (or vmware-config.pl) with the "--default" option to reinstall the VMware kernel modules. Even better, because this is called very early during startup, long before the VMware services are started, eveything will work the first time with no interaction whatsoever.
One thing to look out for, if you install an upgraded vmware-tools (or VMware Workstation/Server release) without upgrading the kernel and you want the new modules to be installed on the next reboot you need to remove the ".vmware_installed" file. Simply run the following command and the new modules will be installed on the next boot:
rm -f /lib/modules/`uname -r`/misc/.vmware_installed
One major drawback, if your system uses a separate partition/logical volume for /usr, which is common, then the rc.modules script will probably be called before that system is mounted. Possible solutions include adding a command to mount /usr at least read-only before attempting to run the vmware-config script or, you could just move the commands to rc.local. The disadvantage of rc.local is that, for Linux guest VM's using the "flexnet" adapter they will have already loaded the pcnet32 module in place of the vmxnet driver. You could easily script unloading this module and restarting the vmware-tools service, but I've seen a few applications that behave poorly if you stop networking after they've already been started.
Good luck, let me know if you have suggestions for improvements. This has been a huge timesaver for me when upgrading dozens of Linux systems running as VM's and a handful of servers running VMware Server as well as desktop systems running VMware Workstation. What used to be an annoying manual process of upgrading kernel, rebooting, logging in to the console, running vmware-config-tools.pl by hand, rebooting to make sure it worked, has now become a non-issue. Simply upgrade the kernel and reboot. Pretty slick.
Saturday, February 16. 2008 at 09:37 (Reply)
Saturday, February 16. 2008 at 13:06 (Reply)
There are many solutions to this. Simply add a "mount -o remount,rw /" command to the script prior to running the script. You could even remount read-only after the script runs if you want.
Another option is to put the command in rc.local or perhaps modify your grub.conf file to initially mount root read-write (this might have some negatives in the event of root drive corrution, but that's pretty rare and you could always override it at the boot prompt).
I actually have a more "sophisticated" version of the script which does things like check if root is read-only and automatically remount read-write, check to see if /usr is separate and automatically mount it if required, and the return the system to it's "normal" state after it's done. Once I've completely debugged it I'll post it.
Later,
Tom
Wednesday, March 12. 2008 at 10:51 (Link) (Reply)
Oh, BTW.. a possible cleaner solution would be to put the script in the /etc/sysconfig/modules/ directory as "vmware" (making sure it is chmod +x)
also, I merged both of your scripts into one (so I could just put the single script in the modules subdir) like this
#!/bin/sh
if [ ! -e /lib/modules/`uname -r`/misc/.vmware_installed ]; then
[ -x /usr/bin/vmware-config-tools.pl ] && /usr/bin/vmware-config-tools.pl --default
[ -x /usr/bin/vmware-config.pl ] && /usr/bin/vmware-config.pl --default
touch /lib/modules/`uname -r`/misc/.vmware_installed
fi
Also, if you have issues with your /usr being on a different partition, you can always put the script contents in /etc/rc.local which is the last thing ran on system startup.
Wednesday, March 12. 2008 at 17:19 (Reply)
I've actually switched all of my systems to just using rc.local. The only reason I didn't like that solution was that running the vmware-config script stops the network and we have quite a few servers with processes that die or go into strange states if you take the network down after they are started. Plus, it means that on that first reboot with a new kernel the modules aren't there yet and the network comes up with the pcnet32 driver rather than vmxnet.
In the end I decided the easy solution was to just put the commands in rc.local and simply have the script perform a reboot if the vmware-config script is run. This has the disadvantage of requiring two reboots, but since they are both automated it's not a real big deal.
Also, on ESX 3.5 the vmware-config-tools scripts seems to add a mount point for ./hgfs even through I don't use or need that (does it even work with ESX?) and even worse, causes annoying, although harmless errors during boot. I added a small sed line to remark those out if they exist.
Hopefully I'll find a little time somewhere along the way to update this page.
Even with the small bugs an annoyances this script has proven to be a big help. We just went through a major cycle upgrading ~25 RHEL4 and 5 system with new kernels and it used to be a pain to update all of the vmware-tools by hand. This time it was just two automatic reboots and they were all good to go.
Thanks again for your feedback and tweaks.
Monday, July 28. 2008 at 09:56 (Reply)
I have found that putting your script into /sbin/ifup-pre-local (which doesn't by default exist), seems to work well with CentOS 5.2 as client. The script is run (via /sbin/ifup) just before the network interfaces are brought up, and the default 'vmware-tools' startup script works fine because the tools have already been rebuilt by the time it runs. Hence, no second reboot is required.
Monday, July 28. 2008 at 13:58 (Reply)
I'm pretty sure that VMware Workstation has "vmware-config.pl" on the host, and "vmware-config-tools.pl" in the guest. I tried to make that distinction in the article, but perhaps it was not clear. Both the host and the guest have binary modules that must be compiled, but they use a slightly different script. Are you saying that you don't have a "vmware-config.pl" file on the Fedora 8 host? That would really surprise me, but I guess it would not be impossible since I still use a 5.5.x versions of Workstation.
Running the script in /sbin/ifup-pre-local is a great idea, I'll have to give it a spin.
Thanks,
Tom
Thursday, September 4. 2008 at 06:52 (Reply)
/usr/bin/vmware-config-tools.pl -d
/sbin/service network restart
/sbin/service vmware-tools restart
Thursday, September 4. 2008 at 10:08 (Reply)
In the end though, the main reason we didn't use that option is that we found that restarting the network caused some services that bind to specific network addresses to loose their binding and then they would also have to be restarted. This led to systems that randomly had one or two services not working after a reboot and I wanted something that worked 100% of the time in all cases. An extra reboot wasn't a big deal. In the end, we've actually started putting this in rc.local:
if [ ! -e /lib/modules/`uname -r`/misc/.vmware_installed ]; then
/usr/bin/vmware-config-tools.pl --default
touch /lib/modules/`uname -r`/misc/.vmware_installed
sed '/^.host:/s/^/#/g' -i /etc/fstab
depmod -a
reboot
fi
This extra sed line is for some of the newest versions of VMware Tools for ESX 3.5 which add a stupid .host line in fstab which causes non-critical errors during boot. The first time the system boots a new kernel it recompile the modules and restarts, the second restart is good. We decided this was the most reliable way for our systems and worked 100% across all versions for us.
Saturday, September 6. 2008 at 07:14 (Reply)
Tuesday, September 9. 2008 at 18:51 (Reply)
I'm sure I could write a script that extracts the modules, compiles them against the newest kernel, etc, but what would this buy me? Saving a reboot that takes maybe 60 seconds and happens automatically? It just didn't seem worth it for our use case.
Friday, October 3. 2008 at 09:59 (Reply)
--- /etc/rc.d/init.d/vmware-tools.orig 2008-10-03 09:31:19.000000000 -0400
+++ /etc/rc.d/init.d/vmware-tools 2008-10-03 09:47:43.000000000 -0400
@@ -826,12 +826,7 @@
exitcode='0'
if vmware_inVM; then
if [ -e "$vmware_etc_dir"/not_configured ]; then
- echo "`vmware_product_name`"' is installed, but it has not been '
- echo '(correctly) configured for the running kernel.'
- echo 'To (re-)configure it, invoke the following command: '
- echo "$vmdb_answer_BINDIR"'/vmware-config-tools.pl.'
- echo
- exit 1
+ "$vmdb_answer_BINDIR"/vmware-config-tools.pl --skip-stop-start --default
fi
echo 'Starting VMware Tools services in the virtual machine:'
Saturday, October 18. 2008 at 04:06 (Reply)
The script stops with:
"You must read and accept the End User License Agreement to continue.
To display End User License Agreement please restart /usr/bin/vmware-config.pl
in the interactive mode, without using `-d' option."
Any ideas?
Thursday, November 6. 2008 at 12:31 (Reply)
Thursday, March 5. 2009 at 04:57 (Link) (Reply)
/usr/bin/vmware-config.pl -d EULA_AGREED=yes
does the trick.
Wednesday, December 17. 2008 at 20:16 (Reply)
One last detail. My OS is SUSE Linux Enterprise Server 10, and \etc\rc.modules is apparently not called during the boot process, so I ended up placing it in \etc\init.d\boot.local which is called right before runlevel 3 or 5 is initiated, perfectly allowing recompile before the NIC gets loaded normally. Works like a champ!
# Following lines auto-recompile VM Tools when kernel updated
VMToolsCheckFile="/lib/modules/`uname -r`/misc/.vmware_installed"
VMToolsVersion=`vmware-config-tools.pl --help 2>&1 | awk '$0 ~ /^VMware Tools [0-9]/ { print $3,$4 }'`
printf "\nCurrent VM Tools version: $VMToolsVersion\n\n"
if [[ ! -e $VMToolsCheckFile || `grep -c "$VMToolsVersion" $VMToolsCheckFile` -eq 0 ]]; then
[ -x /usr/bin/vmware-config-tools.pl ] && \
printf "Automatically compiling new build of VMware Tools\n\n" && \
/usr/bin/vmware-config-tools.pl --default && \
printf "$VMToolsVersion" > $VMToolsCheckFile && \
rmmod pcnet32
rmmod vmxnet
depmod -a
modprobe vmxnet
fi
Wednesday, December 17. 2008 at 20:55 (Reply)
Thanks,
Tom
Tuesday, August 4. 2009 at 13:45 (Reply)
Tuesday, August 4. 2009 at 16:00 (Link) (Reply)
I don't really see why you couldn't just test for the existence of the module. I can't really remember why I didn't do that in the first place. It was probably to avoid the case of VMware deciding to change their module names.
Wednesday, November 4. 2009 at 11:18 (Reply)
Wednesday, November 4. 2009 at 17:30 (Link) (Reply)
To be totally honest, the version of this script we use in production is a little more sophisticated than just touching a file. It actually creates a file that contains the actual version of the VMware tools that are installed and, if the file already exist, it compares that string against the current version in our central repo. That way, it can automatically detect and upgrade to new versions of the VMware tools even if the kernel is not upgraded. The blog entry was just a simplified example of one possible way to do it, not the be all end all solution.
Monday, September 21. 2009 at 09:40 (Reply)
Unable to open the installer database /etc/vmware-tools/locations in append-mode. Execution aborted.
Anyone else had this problem?
Wednesday, January 20. 2010 at 22:11 (Reply)
I also ended up make a script in /etc/rc.d/init.d and setting to to run just after iptables at position 09. (This is on RHEL5.)
Thanks much for the initial idea Tom!
Monday, January 25. 2010 at 14:52 (Reply)
Thanks Rick
Sunday, February 28. 2010 at 23:59 (Reply)
chmod 755 VMware-update.sh
Then put this in the file:
--------
#!/bin/bash
if [ ! -e /lib/modules/`uname -r`/misc/.vmware_installed ]; then
/usr/bin/vmware-config.pl -d EULA_AGREED=yes
touch /lib/modules/`uname -r`/misc/.vmware_installed
fi
--------
Then:
sudo gedit /etc/rc.local
and add this before the "exit 0":
/home/your-home-path/VMware-update.sh
and save the changes.
Now on each boot-up it will check for a new kernel and update your VMware Server setup to use it.
Monday, July 12. 2010 at 14:56 (Reply)
What I miss is now the summary, global multi-purpose script which includes all fetaures and runs in every combination on every possible distribution (at least on Ubuntu, CentOS, Solaris).
Has anyone a suggestion for the final version of the script?
Thank you
Peter
Monday, July 12. 2010 at 15:03 (Link) (Reply)
Here's the link in case you can't see the pingback:
https://stomp.colorado.edu/blog/2010/06/10/on-vmware-tools-and-linux/
It should work with Redhat and Ubuntu, and pretty much other Linux distro's. Solaris might take some minor modifications but shouldn't be too bad.