VMware

HOWTO: Run a Virtual Machine at Boot

VERSION 6 Published

Created on: Jul 10, 2008 10:42 PM by etung - Last Modified:  Aug 18, 2008 10:42 AM by etung

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.

Motivation

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.

Prepare the Virtual Machine

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"

  • msg.autoAnswer is because sometimes Fusion wants to prompt you with some information (e.g. Tools aren't installed). Without this, the virtual machine will sit around waiting for an answer, but we don't want that since the idea is to run automatically.
  • signal.suspendOnHUP and signal.powerOffOnTERM give us ways to suspend or shut down the virtual machine by sending signals (via `kill`, e.g. `kill -HUP $PID` where $PID is the ID of the vmware-vmx process).
  • RemoteDisplay.vnc.enabled and RemoteDisplay.vnc.port give us a way to connect to the virtual machine. Note that by default, Fusion virtual machines already come with RemoteDisplay.vnc.port; edit this rather than creating a duplicate entry.

Test your virtual machine by running it normally in Fusion, connecting via VNC, and suspending and/or powering off.

Run at Boot

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.

Run Continuously

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).

Run Once

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

{noformat}
#!/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"
{noformat}


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.

Tags: howto, fusion
Average User Rating
(0 ratings)




Dec 6, 2008 12:01 AM ann2x168  says:

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

Jan 13, 2009 5:09 AM blurk  says:

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.

Oct 7, 2009 7:44 AM Chimgan  says:

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

VMware Beta Programs

Want to be Considered for Future Beta Programs?

Learn More

VMware Developer

Download SDKs, APIs, videos,
training, and more in the Developer community.

Learn More

Developer
Sample Code

Increase your developer productivity with VMware API sample code.

Learn More

VMworld
Sessions & Labs

Online access to the latest VMworld Sessions & Labs and online services.

Learn more

Purchase PSO Credits Online

Purchase credits to redeem training and consulting services online.

Buy Now

Community Hardware Software

View reported configurations or report your own.

Learn More

Only VMware ... Delivers Nexus 1000V

Ensure consistent, policy-based network capabilities to virtual machines across your data center.

Learn More

Communities