Wednesday 10 March 2010

VirtualBox - hibernation of a host system may cause problems

Your virtual machines may not resume properly after thawing (i.e. starting the system after hibernation) - problems with vboxdrv kernel module. Here is my script which solves this issue (most of you can just put it in /etc/pm/sleep.d/action_virtualbox). I use Debian GNU/Linux but the script should work perfectly with other distros as well (e.g. Ubuntu, Fedora or Suse). The script puts all VMs to sleep (saves their state) and stores information about the associated processes (X Window display, real uid) in a file and tries to resume all VMs upon thawing, running them with correct user/display combination.

Do not worry if you cannot see the whole script (i.e. it appears to be clipped) just select and copy it with your mouse (or make your browser window wider).

#!/bin/sh
# suspend virtual machines on hibernate and resume them on thaw

# a file for storing a list of running vms
RVF='/var/run/running_vms'

PATH=/sbin:/usr/sbin:/bin:/usr/bin

if [ ! -x $SCRIPT ]; then
      exit 0
fi

SELF=action_virtualbox
COMMAND=

# pm-action(8) -  
#
# On hibernate, suspend all running VMs to disk
# resume them on thaw.

case "${1}" in
      hibernate)
              # 1. get a list of processes for all running virtual machines
              # 2. for each list item extract a login name, vm uid and display and store them in $RVF file
              # 3. save state of each vm
              ps eax -o user,cmd|
              grep '\bVirtualBox\b.*--startvm\b'|
              grep -v '\bgrep\b'|
              sed 's/\(^\w*\b\).*--startvm\( [[:alnum:]-]*\b\).*\( DISPLAY=:[0-9.]*\).*\($\)/\1\2\3\4/'|
              awk -v rvf=$RVF '
                      BEGIN {system(">"rvf)}
                      {print "\nSuspending VM "$2" (user: "$1")";
                       system("su -c \47VBoxManage -q controlvm "$2" savestate\47 "$1);
                       print "Appending VM data to file "rvf".\n";
                       system("echo "$0">>"rvf)}'
              # \47 is the single quote (i.e. "'")
              ;;
      thaw)
              if [ ! -s $RVF ]
              then
                      echo "No virtual machines suspended at the last hibernate which haven't already been thawed, therefore nothing to thaw."
                      exit 0
              fi
              cat $RVF|awk '
                      {print "\nResuming VM "$2" (user: "$1"; "$3")";
                       system("su -c \47"$3" VBoxManage -q startvm "$2"\47 "$1)}'
              echo "\nAll thawed. Deleting $RVF."
              rm $RVF
              ;;
esac

No comments:

Post a Comment

Popular Posts