2 Jun 2007

Automaticly suspend VMWare virtual machines on shutdown

I am using the VMWare Server on my workstation for testing. Because this computer has the fast nVidia card installed, I also boot in to windows now and then for gaming. It sometimes happens that I do forget to shutdown or suspend the VMs which is not really good for the virtual machines.

Fortunately, the VMWare server on linux comes with a handy command line client (vmware-cmd) for manipulating the configured virtual machines. This done from a System V init script solved my problem: suspending all running vms on shutdown and resuming them on start up. The solution works only if you are using vms with the VMware Tools installed. Three steps are needed to set up such a scripted solution on debian linux.

VMWare Tools
For no apparent reason vmware-cmd insists in having vmware tools installed in the vm or will refuse to work (the vmware-server-console can suspend clients without vmware tools installed). So you must make sure that auto suspended clients have the VMWare tools installed.

init script
Install the init script below in /etc/init.d and create the needed links. Both steps may vary a little depending on your distro (examples are for debian/ubuntu).

Create start/stop links
Make sure the start part of the script is run after vmware is started and the stop part must be called before vmware is suspended.

cd /etc/rc2
sudo ln -s /etc/init.d/vmware-suspend S21vmware-resume
sudo ln -s /etc/init.d/vmware-suspend K19vmware-suspend
/etc/rc2.d should look lik this now:

ls -la /etc/rc2.d/*vmware*
lrwxrwxrwx 1 root root 26 2007-06-02 13:29 /etc/rc2.d/K19vmware-suspend -> /etc/init.d/vmware-suspend
lrwxrwxrwx 1 root root 23 2007-05-31 13:58 /etc/rc2.d/S20vmware-server -> ../init.d/vmware-server
lrwxrwxrwx 1 root root 26 2007-06-02 13:28 /etc/rc2.d/S21vmware-resume -> /etc/init.d/vmware-suspend

That's it.

/etc/init.d/vmware-suspend
#!/bin/bash
# $Id$

# store cfg file names of automaticly suspended vms in this file, so we
# can auto resume on the next start.
STATE=/var/run/vmware.suspended;

# this function suspends running vms.
function vmware_suspend {
running="";
for vm in `vmware-cmd -l`; do
state="`vmware-cmd \"$vm\" getstate | grep on`";
if [[ ! -z "$state" ]]; then
running=`echo -e "$running\n$vm"`;
echo "Suspending vm: $vm";
vmware-cmd "$vm" suspend;
fi
done
echo "$running" > "$STATE";
}

# resume suspended vms.
function vmware_resume {
if [[ -f "$STATE" ]]; then
for vm in `cat "$STATE"`; do
echo "Resuming vm: $vm";
vmware-cmd "$vm" start;
done
rm "$STATE";
fi
}

case "$1" in
start)
echo "Starting";
vmware_resume;;
stop)
echo "Stopping";
vmware_suspend;;
esac

exit 0;

No comments: