Hibernate host OS with running VirtualBox

For this page, we assume that the host OS is PCLinuxOS and the guest OS is any OS running on VirtualBox. When there is a virtual machine is running hibernating the host os, either manually or automatically because of low battery in laptops, may cause the hibernation process to hang. To avoid this situation, we have to make sure all the running virtual machines are saved before hibernating the host OS.

Here are the steps to achieve this.

Setup
1. Create a script with below lines of code to save running virtual machines under all logged in users. Let us call it saveRunningVBoxes.sh. THIS SCRIPT WILL NOT LET THE HIBERNATION PROCEED FURTHER UNTIL ALL THE VIRTUAL BOXES ARE SAVED. IF THE MACHINE STAYS IN LOCK SCREEN LONGER THAN EXPECTED, PLEASE SAVE THE RUNNING VIRTUAL BOXES MANUALLY WHICH WILL ALLOW THIS SCRIPT TO PROCEED FURTHER.
 * 1) !/bin/bash
 * 2) output from this script are saved in /var/log/vm-suspend.log
 * 1) output from this script are saved in /var/log/vm-suspend.log

echo `date` executing $0 $* >> /var/log/vm-suspend.log

export EVENT=$1


 * 1) This file will execute with following parameters and events
 * 2) hibernate hibernate - when the system hibernates
 * 3) thaw hibernate - when the system comes back from hibernation
 * 4) suspend suspend - when the system suspends to RAM or sleeps
 * 5) resume suspend - when the system comes back from suspension

if [ "$EVENT" == "hibernate" ] then echo hibernating VMs... >> /var/log/vm-suspend.log
 * 1) below condition checks if the execution is because of hibernation initiation

export vboxcount=`ps -ef | grep -i virtualbox | grep -v grep | wc -l` while [ $vboxcount -gt 0 ] do    echo found running VMs... >> /var/log/vm-suspend.log
 * 1) below 2 lines make sure all the virtual box instances are saved before proceeding.
 * 2) if this script fails to save all the running virtual boxes, the system will stay in the lock screen and we can manually save the virtual boxes and the script will automatically continue further

for usr in `users` do
 * 1) loops through all the logged in users

for vm in `su - $usr -c "VBoxManage list runningvms" | cut -d " " -f 2`; do echo saving $usr $vm >> /var/log/vm-suspend.log; su - $usr -c "VBoxManage controlvm $vm savestate";echo saved $usr $vm >> /var/log/vm-suspend.log; done done export vboxcount=`ps -ef | grep -i virtualbox | grep startvm | wc -l` done fi echo `date` executed $0 $* >> /var/log/vm-suspend.log 2. As root user save the script saveRunningVBoxes.sh under directory /etc/pm/sleep.d/ and set execute permission by executing below command as root
 * 1) loops through all running virtual box instances and saves the state

chmod +x /etc/pm/sleep.d/saveRunningVBoxes.sh

Verification
Now lets test the script.

3. Run the script as root without any virtual box running and check the log file /var/log/vm-suspend.log

4. Run the scirpt as root with virtual box running and check the log file /var/log/vm-suspend.log

5. Hibernate the machine with virtual box running and check the log file /var/log/vm-suspend.log after recovering from hibernation

6. Suspend/sleep the machine with virtual box running and check the log file /var/log/vm-suspend.log after recovering from suspension