Dear bug 555296 subscribers,
Recently, I ran into this bug, where a host system cannot resume from
hibernate-to-disk when a VirtualBox VM was running while VT-X is
enabled. It's fairly common [0].
So, I decided to patch it. This patch allows the system to successfully
suspend while VMs are running. It's been deployed on my machine for
around a week now (10 - 20 successfull suspend-resume cycles, without
needing to restart).
On to the details. The patch:
- Iterates through each user on the system.
- Saves the state of each user's running VMs, safely stopping them.
- The system then continues hibernating, safely.
Shortcomings of this script folks might want to address include:
- Not disablable through configuration settings (not really sure what
config file to use).
Enabling this script in Squeeze involves linking it to:
/etc/pm/sleep.d/01_virtualbox-vm-control
I hope this helps somebody,
Nick
#! /bin/sh
### BEGIN INIT INFO
# Provides: Suspends all local virtual machines.
# Required-Start: $local_fs $remote_fs
# Required-Stop:
# Default-Start:
# Default-Stop: S 0 1 6
### END INIT INFO
# inspired by: http://ubuntuforums.org/showthread.php?t=405038
N=/etc/init.d/virtualbox_vm_control
set -e
users=`who | cut -f1 -d " " | sort -u`
vmCount="pgrep -c VirtualBox"
runningVms="vboxmanage list runningvms | tail -n +5 - | sed -e 's/{.*$//1' -e
's/\\\"//g'"
perUserVms="su \$user -c \"$runningVms\""
wait_for() {
# usage: wait_for seconds
I=0
while [ `eval $perUserVms` ] && [ $I -lt $1 ]
do
sleep 1
I=$(($I + 1))
echo -n "."
done
}
case "$1" in
stop|hibernate)
for user in $users
do
echo "Stopping Virtualbox VMs for ${user}:"
if [ -z `eval $perUserVms` ]
then
echo " No running VMs."
else
# nicely ask the VMs to stop.
echo -n " Telling VMs to save state..."
for vm in `eval $perUserVms`
do
su $user -c "vboxmanage controlvm ${vm} savestate >
/dev/null" &
done
echo " done."
echo -n " Waiting for VMs to die..."
wait_for 60
if [ -z `eval $perUserVms` ]
then
echo " done."
else
# the VMs didn't stop.
echo " NOT DONE."
echo -n " Killing VMs..."
killall VirtualBox &> /dev/null
wait_for 10
# the VMs still didn't stop. slaughter them.
if [ -n `eval $perUserVms` ]
then
killall -s 9 VirtualBox &> /dev/null
wait_for 5
fi
echo " done."
fi
fi
done
# and sleep for a few seconds to let the disks flush.
sleep 5
;;
start|reload|restart|force-reload)
;;
*)
echo "Usage: $N stop" >&2
exit 1
;;
esac
exit 0
--
GPG: 0x4C682009 | 084E D805 31D8 5391 1D27 0DE1 9780 FD4D 4C68 2009