Disclaimer: This is a personal document and is not official or endorsed by VMware. Feedback, suggestions, and edits are welcome.
This document is intended for someone who wants to run a VMware Fusion virtual machine at boot, and assumes basic familiarity with both OS X and Fusion, as well as A Beginner's Guide to VMware Fusion.
If you want to be notified of changes and additions to this document, you can use the "Receive email notifications" action in the sidebar on the left. Please use the comments below only for things specific to this document (e.g. inaccuracies); general questions (including questions about getting this to work) are better off in the discussion section.
Unlike Windows or Linux, where you can choose from Workstation/Server/Player/etc., on the Mac, Fusion is currently our only product. While Fusion is intended to be a consumer product, it shares the common VMware code base, and so gets a bunch of features for free. With a little bit of tweaking, you can run a virtual machine at boot and in the background. For example, you might want to do this on a server, or with a virtual machine that provides services to users on the Mac.
This section is mostly optional, but makes it easier to interact with your virtual machine. Add the following lines to the .vmx config file:
msg.autoAnswer = "TRUE"
signal.suspendOnHUP = "TRUE"
signal.powerOffOnTERM = "TRUE"
RemoteDisplay.vnc.enabled = "TRUE"
RemoteDisplay.vnc.port = "5902"
Test your virtual machine by running it normally in Fusion, connecting via VNC, and suspending and/or powering off.
You can have the virtual machine automatically restart when stopped (shuts down, suspends, crashes, etc.) or run (automatically) only once per boot. You will need administrator access for this part. A graphical editor for launchd scripts which you might find useful is Lingon.
I've tested this on a Mac mini running 10.5.4. 10.4.x has slightly different launchd syntax and defaults; you'll probably need to tweak the plists slightly. Note I'm not a launchd expert, this section is based on what I learned via Googling and playing with scripts. Improvements welcome.
With Fusion 2.0b2, you can use "vmrun start ..." instead of calling "vmware-vmx -x ..."; vmrun is meant for scripting and is probably the better way to go.
This method will restart the virtual machine if it dies (shuts down, crashes, etc.). This makes the HUP signal not very useful, because immediately after the virtual machine suspends, launchd will respawn the virtual machine and it will resume again.
Create a plain text file in /Library/LaunchDaemons, let's call it com.example.fusion-as-server. Paste in the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.fusion-as-server</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Application Support/VMware Fusion/vmx/Contents/MacOS/vmware-vmx</string>
<string>-x</string>
<string>/Users/etung/Virtual Machines/Test.vmwarevm/Test.vmx</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>UserName</key>
<string>etung</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Be sure to change the path in ProgramArguments to point at whatever virtual machine you want to run, and UserName to the owner of that virtual machine. You probably also want to give it a more descriptive name and Label.
In Re: running OSX Server with Fusion as a daemon and OSX server as host?, Dr. Wo suggests not using KeepAlive with 2.0b2 because vmware.vmsg may not be found, causing launchd to keep respawning (or something).
This method runs the virtual machine once at boot, but if the virtual machine stops (shuts down, crashes, suspends, etc.) it won't get restarted.
Running once is slightly more tricky than running all the time. The problem is that in order to run a virtual machine, various Fusion kexts need to be loaded. If we run the virtual machine before the kexts are loaded, vmware-vmx looks around, doesn't see anything to talk to, and gives up and dies. We can get away with it in the continuous case because launchd will keep respawning the virtual machine, and eventually it will succeed (after the Fusion kexts come up). In the run-once case, the lack of kexts means that the virtual machine doesn't run. We want to make sure the kexts are loaded before trying to run the virtual machine.
Unfortunately, launchd provides no way to order tasks. Apple's recommendation is to use IPC. However, from an end-user's point of view, this is not a practical possibility. Instead, let's try a hack.
When the kexts are loaded by boot.sh, various files are created. We'll make a script that waits for the creation of one of these files before starting the virtual machine. Let's call it test.sh, located in your home directory.
Note: I don't think you can use the launchd WatchPaths or QueueDirectories parameters instead of a script. First, they appear to take precedence over the LaunchOnlyOnce parameter, so it wouldn't do the right thing. According to this blog post, WatchPaths only works if the file always exists (the files used by boot.sh don't, they're created and destroyed). QueueDirectories watches an entire directory; the vmnet-*-vmnet-*.pid files are in a directory with a bunch of other stuff, so are unsuitable; vmnet-dhcpd-vmnet*.leases changes whenever a DHCP client connects or disconnects (so stopping a virtual machine would trigger it to run again). If you wanted to use these, you could probably modify boot.sh to create a sentinel file you could watch for.
TODO: Should use kextstat to see if the Fusion kexts are loaded instead of the file test
#!/bin/bash
while [! -e /var/run/vmnet-bridge-vmnet0.pid]; do
sleep 1
done
"/Library/Application Support/VMware Fusion/vmx/Contents/MacOS/vmware-vmx" -x "/Users/etung/Virtual Machines/Test.vmwarevm/Test.vmx"
Be sure to change the path to wherever your virtual machine actually is. chmod the script to be executable (e.g. `chmod +x ~/test.sh`).
Create a plain text file in /Library/LaunchDaemons, let's call it com.example.fusion-as-server. Paste in the following:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.example.fusion-as-server</string>
<key>ProgramArguments</key>
<array>
<string>/Users/etung/test.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ExitTimeOut</key>
<integer>0</integer>
<key>LaunchOnlyOnce</key>
<true/>
<key>UserName</key>
<string>etung</string>
</dict>
</plist>
Be sure to change UserName to the owner of that virtual machine, and the path in ProgramArguments to point at wherever the script actually is (you probably don't actually want to have it in your home directory). You probably also want to give it a more descriptive name and Label.
i have just recently bought a 13 inch macbook. so far it's running great. the only drawback is that i need ot run quickbooks enterprise solution edition 5.0. it's a windows only software. right now i'm using bootcamp to access it which at times can be such a hassle. i have been reading good reviews with the vmware fusion 2.0, my only inquiry is that is it compatible with the version of quickbooks that i'm using? any help or comments would be great. i am not a very savvy mac user
Very helpful document, thanks.
It may need some updating for Fusion V2. As you point out in the text, vmrun is the more appropriate method for starting VMs. I couldn't get vmware-vmx working at all, but did have success with vmrun. Also, the paths appear to have changed in V2 (or at least in my install); I only needed /Library/Application Support/VMware Fusion/vmrun and not the extra vmx/Contents/MacOS/ in the path. This may confuse some readers.
Thanks for this Howto!
That's my code using kextstat to wait for VMWare extensions in 'Run Once'
while [ 4 -gt `kextstat -k -l | grep -c "vmware.kext."` ]; do
echo "Waiting for VMWare Fusion kexts..."
sleep 1
done