I have been experimenting with Linux servers for a while now. My latest experiment was at using VirtualBox to run virtual servers. I used a helpful tutorial from howtoforge.com to guide me through the setup. After setting up VirtualBox on CentOS and installing Fedora in a VM, I wanted the Fedora VM to automatically start up and shut down when the CentOS host started up and shut down.
With the help of google, I found a post by Jochem Kossen that included a script for controlling VirtualBox VMs.
I made some changes to it to remove the TAP configuration since it is no longer necessary in the latest version of VirtualBox.
After getting it working with the TAP functions removed I found that it would startup fine when the host booted up, but it didn't shut down cleanly. I eventually learned that CentOS (and other Red Hat based distros) use a lock file to know if the service is running. If the lock file is not created, the rc script assumes that the service isn't running and doesn't run the stop script.
The code below is the results of my modification.
#! /bin/sh # vboxcontrol Startup script for VirtualBox Virtual Machines # # chkconfig: 345 98 02 # description: Manages VirtualBox VMs # processname: vboxcontrol # # pidfile: /var/run/vboxcontrol/vboxcontrol.pid # ### BEGIN INIT INFO # ### END INIT INFO # # Version 20090301 by Kevin Swanson <kswan.info> based on: # Version 2008051100 by Jochem Kossen <jochem.kossen@gmail.com> # http://farfewertoes.com # # Released in the public domain # # This file came with a README file containing the instructions on how # to use this script. # # Source function library. if [ -f /etc/init.d/functions ] ; then . /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions else exit 1 fi ################################################################################ # INITIAL CONFIGURATION VBOXDIR="/etc/virtualbox" VM_USER="vboxadmin" USE_NAT="no" export PATH="${PATH:+$PATH:}/bin:/usr/bin:/usr/sbin:/sbin" if [ -f $VBOXDIR/config ]; then . $VBOXDIR/config fi SU="su $VM_USER -c" VBOXMANAGE="VBoxManage -nologo" ################################################################################ # FUNCTIONS # Determine if USE_NAT is set to "yes" use_nat() { if [ "$USE_NAT" = "yes" ]; then return `true` else return `false` fi } log_failure_msg() { echo $1 } log_action_msg() { echo $1 } # Check for running machines every few seconds; return when all machines are # down wait_for_closing_machines() { RUNNING_MACHINES=`$SU "$VBOXMANAGE list runningvms" | wc -l` if [ $RUNNING_MACHINES != 0 ]; then sleep 5 wait_for_closing_machines fi } ################################################################################ # RUN case "$1" in start) if [ -f /etc/virtualbox/machines_enabled ]; then cat /etc/virtualbox/machines_enabled | while read VM; do log_action_msg "Starting VM: $VM ..." $SU "$VBOXMANAGE startvm "$VM" -type vrdp" RETVAL=$? done touch /var/lock/subsys/vboxcontrol fi ;; stop) # NOTE: this stops all running VM's. Not just the ones listed in the # config $SU "$VBOXMANAGE list runningvms" | while read VM; do log_action_msg "Shutting down VM: $VM ..." $SU "$VBOXMANAGE controlvm "$VM" acpipowerbutton" done rm -f /var/lock/subsys/vboxcontrol wait_for_closing_machines ;; start-vm) log_action_msg "Starting VM: $2 ..." $SU "$VBOXMANAGE startvm "$2" -type vrdp" ;; stop-vm) log_action_msg "Stopping VM: $2 ..." $SU "$VBOXMANAGE controlvm "$2" acpipowerbutton" ;; poweroff-vm) log_action_msg "Powering off VM: $2 ..." $SU "$VBOXMANAGE controlvm "$2" poweroff" ;; status) echo "The following virtual machines are currently running:" $SU "$VBOXMANAGE list runningvms" | while read VM; do echo -n "$VM (" echo -n `$SU "VBoxManage showvminfo $VM|grep Name:|sed -e 's/^Name:s*//g'"` echo ')' done ;; *) echo "Usage: $0 {start|stop|status|start-vm <VM name>|stop-vm <VM name>|poweroff-vm <VM name>}" exit 3 esac exit 0
VirtualBox version
VirtualBox version 2.2
----------------------
I change:
$SU “$VBOXMANAGE controlvm \”$VM\” acpipowerbutton”
to:
$SU “$VBOXMANAGE controlvm \”${VM%% *}\” acpipowerbutton”
and
echo -n `$SU “VBoxManage showvminfo $VM|grep Name:|sed -e ’s/^Name:\s*//g’”`
to
echo -n `$SU “VBoxManage showvminfo ${VM%% *}|grep Name:|sed -e ’s/^Name:\s*//g’”`
because VBoxManage list vms|runningvms returns "VMname {VMpid}" and this string cannot used in subsequent commands.
That makes sense. I can't
That makes sense. I can't confirm because I switched my host to Ubuntu. I had to make several changes to the script because of the differences between CentOS and Ubuntu.
Thank you for the feedback.
Hi, good post. I have been
Hi, good post. I have been wondering about this issue,so thanks for posting. I’ll definitely be coming back to your site.
Thank you to Fabio Milano
Thank you to Fabio Milano from kernelhardware.org for providing an excellent explanation of this.
http://www.kernelhardware.org/virtualbox-auto-start-vm-centos-fedora-red...
Thanks for the update to the
Thanks for the update to the script in comments, all commands (start, stop and status) work.
One question, has anyone been able to use the VirtualBox GUI after doing this to show the VM? Right now the option to SHOW is greyed out after using the startup script, wondering if there is some way to allow it.
Thanks again!
VB Show
The 'show' option is not available on running VMs.