How do I configure upstart to run a script on shutdown when the process takes longer than 10secs?

I am running ubuntu 11.10 in a virtual machine (VirtualBox) to learn more about development in linux. I am using a git repository to save my work and have written a script to bundle my work up and save it to the shared folder for use while the virtual machine is not running.

I would like to automatically run this script before shutdown so that my work is always available if the vm is off (currently I have to manually run the script).

I don't know if upstart is the best way to accomplish this, but this is the config that I wrote as a test:

description     "test script to run at shutdown"

start on runlevel [056]

task

script
touch /media/sf_LinuxEducation/start
sleep 15
touch /media/sf_LinuxEducation/start-long
end script

pre-start script
touch /media/sf_LinuxEducation/pre-start
sleep 15
touch /media/sf_LinuxEducation/pre-start-long
end script

post-start script
touch /media/sf_LinuxEducation/post-start
sleep 15
touch /media/sf_LinuxEducation/post-start-long
end script

pre-stop script
touch /media/sf_LinuxEducation/pre-stop
sleep 15
touch /media/sf_LinuxEducation/pre-stop-long
end script

post-stop script
touch /media/sf_LinuxEducation/post-stop
sleep 15
touch /media/sf_LinuxEducation/post-stop-long
end script

The result is that only one touch is accomplished (the first touch in pre-start). What do I need to change to see one of the touches after the sleep to work? Or Is there an easier way to get this accomplished?

Thanks in advance.


Solution 1:

The Upstart Intro, Cookbook and Best Practices has a great number of code snippets to use in creating upstart tasks and jobs.

The shutdown process section of the cookbook says that /etc/init/rc.conf will be run and call /etc/init.d/rc. In turn this will eventually call /etc/init.d/sendsigs. So if you start on starting rc then your task will be executed before rc (and the sigterms that would normally have the process shut down).

file: /etc/init/test.conf

description "test script to run at shutdown"

start on starting rc
task
exec /etc/init/test.sh

file: /etc/init/test.sh

touch /media/sf_LinuxEducation/start
sleep 15
touch /media/sf_LinuxEducation/start-long

Solution 2:

I think this cannot be done via upstart, as the /etc/init.d/sendsigs script, which is invoked by upstart when halting/restarting, kills all processes (killall5 -9) within 10 seconds, and even if that does not succeed, it goes for unmounting everything and shutdown.

The best way would be to use the rusty /etc/init.d style scripts.

Example: /etc/init.d/shutdown_job

#! /bin/sh
### BEGIN INIT INFO
# Provides:          shutdown_job
# Required-Start:    
# Required-Stop:     sendsigs
# Default-Start:
# Default-Stop:      0 6
# Short-Description: bla
# Description: 
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin

. /lib/lsb/init-functions

do_stop () {
    date > /root/s.log
    sleep 20
    date >> /root/s.log
}

case "$1" in
  start)
    # No-op
    ;;
  restart|reload|force-reload)
    echo "Error: argument '$1' not supported" >&2
    exit 3
    ;;
  stop)
    do_stop
    ;;
  *)
    echo "Usage: $0 start|stop" >&2
    exit 3
    ;;
esac

:

Then activate the script

sudo update-rc.d shutdown_job start 19 0 6 .

This will put the script before the sendsigs script on runlevels 0 a 6 (shutdown, reboot). This sample script will record the date, then sleep for 20 secs, then record the date again to /root/s.log.)

More info:

  • man update-rc.d
  • http://www.debian.org/doc/debian-policy/ch-opersys.html#s-sysvinit