Last week I was challenged on this. I got a phonecall from a nice girl, who had some VMs running with some sort of automation. She was using the Virtualbox hypervisor, but was administrating (or scripting) her VMs with libvirt. She wanted to run a script within her VMs whenever they resumed from paused status.
As the OS is unaware it has been paused, I figured the simplest way to accomplish this, was to let a daemon run in the guest, repeatedly checking against a time source outside of the VM, to identify situations where it had been paused.
PauseMonitorI wrote a tiny program for this, and called it "PauseMonitor". It is Linux only, choose whatever license you like for it, and use it as you wish.
Configuration is done in the /etc/pausemonitor.conf file. Here is an example:
accepted_diff = 3 delay_between_checks = 5 ntp_server_ip = "x.x.x.x" on_resume_command = "echo I have been paused! > ~/pausemonitor.txt"
The accepted_diff variable is there to adjust for any delays you might have talking to your ntp server. (If you have a local ntp server, this is a good time to use it.) The higher the number, the more time difference will be accepted without taking action. Values are in full seconds.
The delay_between_checks variable tells the program how often it should get a time code from the ntp server. If you have a local ntp server, use a low number. The load on the guest is minimal. The on_resume_command, the actual action being taken after resuming from paused status, is run using the C library function system(), so it runs any script or command you can fit in there. Perhaps you want to adjust your time here, using another ntp utility. Adjusting the time on the guest will not affect the program.
The binary program file is done as a daemon. That means it exits immediately to the command prompt leaving itself running in memory. Stop it by killing it ("killall pausemonitor").
The program does some basic logging to syslog, mostly for errors.
I have not made up any initialization scripts for running this program automatically on boot, I am sure you can figure something out...
The codeThis is the code for the program as described above. Compile it with libconfig linked in.
If you are like me, and you like stuff small, then hardcode the configuration in the code, and leave out libconfig. Drop the syslog logging, and you can end up with this much simpler code: