I wrote a script that suspends all my VirtualBox machines, and put a line in /etc/rc.local.shutdown, but it doesn't seem to work,

su - XX -c /XX

When I'm booting the next time, VirtualBox tells me the machine was Aborted, so the script wasn't executed. (Launching that script manually works for me)

P.S I already enabled shutdown.target


The problem seems more complicated than I thought, in my .bashrc, if it's running on tty3, it executes startx, so when systemd decide to shutdown/reboot, it whould kill VBoxSVC process and other stuff when X Session dies.

I also tried to hack the source code of xfsm-shutdown-helper, make a fake systemctl that execute my script first, none of the above works.

  • Out of curiosity, how many VMs are you shutting down in tandem? .. Unrelated to your question, but I believe I've found an issue in VirtualBox 4.2.6 where shutting down too many at once (5 to 10) (all are linked-clones from a shared VM) leads to corrupted cloned VMs. – adamrmcd Dec 31 '12 at 5:43
  • @adamrmcd I'm shutting down one-by-one... – daisy Dec 31 '12 at 6:12
  • Do you want to suspend the VMs rather than shutting them down? In a classic (SysV?) init-based system, you should be able to do that from inittab / by modifying the scripts for the runlevel used for shutdown... (read the init man page, it differs between unixes, possibly between Linux distributions as well) – Gert van den Berg Dec 31 '12 at 6:16
  • You might also want to echo something to a logfile from the script, to be sure that it actually didn't run, rather than just failed as a result of something else... – Gert van den Berg Dec 31 '12 at 6:20
  • 1
    If ti supports SysV style init scripts, you would add a script like /etc/init.d/stopvms that stop the VMs when passed a "stop" parameter. You then create links (symbolic or hard) to that script as say /etc/rc5.d/K01stopvms and /etc/rc3.s/K01stopvms . (the scripts in the directories are run in order (K* when leaving a runlevel, S* when entering a runlevel)) (You should also be able to do it as "start" scripts in runlevels 0 (shutdowns) and 6 (reboots)) – Gert van den Berg Dec 31 '12 at 6:46

If I understand you correctly, you want to suspend your VB machines before your bash session on tty3 terminates, or before your Xserver terminates.

I believe systemd is unaware of your running Xsession, because you start it from your .bashrc, so it will be difficult to tell systemd to suspend your VBs before it terminates your shell or your Xsession. You will have to find a place in the shutdown sequence which is "early enough", which might be difficult to find and semantically questionable, because it would mix "user stuff" with "system stuff"

The solutions may somewhat depend on how systemd terminates your processes, but the following should at least point in a good direction:

Before the shell terminates

suspendVB() {
        echo "suspending VBs"
        # put real code here

trap suspendVB EXIT

If you make this the rcfile of your bash (or add it to .bashrc), then the code in suspendVB() will be executed before the shell terminates. You can test this by running

bash --rcfile xxx

where the file xxx contains the code from above. This starts another shell inside your current shell, just for testing. When you then run a simple exit, you will see:

martin@beaureve:~$ exit
suspending VBs
/home/martin >

and you are back in your original (login) shell.

You may have to find out how systemd actually terminates your login shells, and you may have to replace EXIT by some other signal(s). Lookup the trap command to find out more.

Note that When systemd kills your processes with "-9" (SIGKILL) then you will not be able to trap the termination, i.e. you're out of luck.

Before the Xsession terminates

Alternatively you may try a similar thing with your Xsession. This is essential in cases where systemd terminates your Xsession before it terminates your shells. You may want to insert a trap in one of the X startup files (e.g. .xinitrc) - lookup the man pages for startx and xinit to find out more.

If your startx file looks something like mine, then the xserver is started in foreground and you can alternatively simply place your suspend commands after the line where X is actually started (and not use traps at all):

xinit "$client" $clientargs -- "$server" $display $serverargs
echo " --- suspending VBs ---"

I put in the line saying "suspending VBs" and when I run startx -- vt8 I get a fullblows (kde) session on vt8 and only when I logout, the line "suspending VBs" appears on the screen.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.