Tuesday 18 November 2008

Ubuntu, VirtualBox and suspend

Hey, I know, long time no write, well, long time no time left...

and allways running around requires me to suspend my laptop a lot, mainly when suspending it with VirtualBox running. Well after resuming the suspend VirtualBox froze most of the times. Killing the program and restarting it did not work, removing the module was impossible, so the only fix was the reboot. Well until smarter thought came ofcourse.

Create an pm script (in Ubuntu go to /etc/pm/sleep.d/) create a newfile named 90virtualbox with the following contents:


#!/bin/sh

USR_RNNG=$(ps aux |grep VirtualBox |grep -v grep |cut -f1 -d' ')
if [ "x$USR_RNNG" != "x" ]; then
if [ $(id -u) -eq 0 ]; then
su $USR_RNNG -c $0
else
for VMS in $(VBoxManage list runningvms |egrep "^[0-9]"); do
VBoxManage controlvm $VMS savestate
done
fi
fi
exit 0

Dont forget to make the script executable (chmod +x 90virtualbox).

Well that works for me, now before doing ACPI suspend the virtualbox machines are suspended nicely and afterwards you have to start them again, but they are up in a heartbeat (well 5 seconds in my case).

You can do that either by running VirtualBox gui and starting them or running:
VBoxManage start UUID|name_of_virtual_machine

Happy virtualizing...

3 comments:

yestertech said...

thanks for the starting point - I modified it to scan for multiple users on a mandriva install:

cat /etc/pm/sleep.d/90vbox

#!/bin/sh
#
# 90vbox: scan for active virtual machines and pause them to avoid seizing on host suspend

for USR in $(ps aux |grep VirtualBox |grep -v grep |cut -f1 -d' '| uniq); do
case "$1" in
hibernate|suspend)
for VMS in $(su - $USR -c "VBoxManage list runningvms |egrep \"{*}\" |cut -f1 -d' '"); do
su - $USR -c "VBoxManage controlvm $VMS pause"
done
;;
thaw|resume)
for VMS in $(su - $USR -c "VBoxManage list runningvms |egrep \"{*}\" |cut -f1 -d' '"); do
su - $USR -c "VBoxManage controlvm $VMS resume"
done
;;
*) exit $NA
;;
esac
done

sorry about the formatting - don't know how to override

David Morton said...

I left the overall structure the same, but I had to change the egrep statement, as I had a virtual box named "Windows 7" that was not being matched by the egrep in the for statement. Other than that, thanks a bundle. It was taking me an hour for resume at some points.

crayor said...

I also like this script and tried to improve it a bit as it was not working with multiple virtual machine guests running at the same time (multiple paused/running). It only worked for one for me.
Further improvement would be to resume those virtual machine guests on "thaw" (that is, returning from hibernation) which were running at the time when hibernation was started so that they will be running again automatically.

#!/bin/sh
#
# 90virtualbox: scan for active virtual machines and pause them to avoid seizing on host suspend
set -x
for USR in "$(ps aux |grep VirtualBox |grep -v grep |cut -f1 -d' '| uniq)"; do
case "$1" in
suspend)
su - jr -c 'VBoxManage list runningvms | egrep ^\"*\" | cut -d"\"" -f2 | sed s/\"//g | xargs -I VMS -d"\n" VBoxManage controlvm VMS pause'
;;

hibernate)
su - jr -c 'VBoxManage list runningvms | egrep ^\"*\" | cut -d"\"" -f2 | sed s/\"//g | xargs -I VMS -d"\n" VBoxManage controlvm VMS savestate'
;;

thaw|resume)
su - jr -c 'VBoxManage list runningvms | egrep ^\"*\" | cut -d"\"" -f2 | sed s/\"//g | xargs -I VMS -d"\n" VBoxManage controlvm VMS resume'
;;

*) exit $NA
;;
esac
done

Cheers,
Crayor