Experiment: without job-2

For ease of experimenting and for the sake of clarity, we come up with three upstart jobs, job-1, job-2 and job-3. Job-3 (KDM in the rationale) needs to start only when job-1 (mountall-net succesful for /home) has happened. In order to obtain that result, we insert job-2. Let's take a look at job-1 first:

Example 1.  job-1.conf
# job-1 - essential job to run before job-3
description     "essential job to run before job-3"

#
# Long description:
# This is an essential job that must have finished before job-3 can start.
# Only job-3 doesn't know it, and we want job-3 to stay untouched, so it
# can follow the package maintainers' config
#

start on do-run-job-1 1

author "Jurjen Bokma <j.bokma@rug.nl>"

task

script
echo "Script being run"|logger -t "job-1" 2
end script
	

1

This job only starts on a signal that we will emit 'by hand'.

2

The job payload is here.


Example 2.  job-3.conf
# job-3 - job that should wait until job-1 has run
description     "job that should wait until job-1 has run"

#
# Long description:
# This job can only start after job-1 has started
# But we do not want to alter this file...
#

start on do-run-job-3

author "Jurjen Bokma <j.bokma@rug.nl>"

task

script
echo "Script being run"|logger -t "job-3"
end script
	


Both job-1 and job-3 will probably not be started by the system, as do-run-job-1 and do-run-job-3 are not known on your regular run-off-the-mill Ubuntu. We will emit these from a script as part of the test.

Now for the test script. It starts a tail on /var/log/messages (and on /var/log/syslog for good measure). Then it starts job-3 first, and waits 90 seconds before starting job-1.

Example 3.  The testscript init-order-test
#!/bin/bash

date

# Save slice of syslog
tail -0f /var/log/syslog > syslog.tail&
PID_TAIL_SYSLOG=$!

# Save slice of messages
tail -0f /var/log/messages > messages.tail&
PID_TAIL_MESSAGES=$!

# Start job 3
initctl emit --no-wait 1 do-run-job-3 
echo "Just triggered job-3, will sleep for 90 seconds"|logger -t "init-order-test"

# Wait one and a half minute before starting job 1
sleep 90
initctl emit --no-wait 1   do-run-job-1
echo "Just triggered job-1"|logger -t "init-order-test"

# Tell syslog to write messages, and wait for it to happen
kill -HUP $(cat /var/run/rsyslogd.pid) && sleep 5 && sync

echo "Output of this run is in syslog.tail and messages.tail"

date
	

1

The --no-wait makes initctl just queue the event and return. Default behaviour is to wait for the triggered jobs to finish, which would put the script in a deadlock when job-3 depends on job-1 i a later test.


Now let's see what happens when we run init-order-test...

Example 4.  First run of init-order-test, without job-2 in place:

jurjen@host:~$ ls -1 /etc/init/job-*.conf
/etc/init/job-1.conf
/etc/init/job-3.conf
jurjen@host:~$ sudo ./init-order-test
za mrt  5 10:34:15 CET 2011
Output of this run is in syslog.tail and messages.tail
za mrt  5 10:35:50 CET 2011
jurjen@host:~$ cat messages.tail
Mar  5 10:34:15 cit-zb-39-115 init-order-test: Just triggered job-3, will sleep for 90 seconds
Mar  5 10:34:15 cit-zb-39-115 job-3: Script being run
Mar  5 10:35:45 cit-zb-39-115 init-order-test: Just triggered job-1
Mar  5 10:35:45 cit-zb-39-115 rsyslogd: [origin software="rsyslogd" swVersion="4.2.0" x-pid="2259" x-info="http://www.rsyslog.com"] rsyslogd was HUPed, type 'lightweight'.
Mar  5 10:35:45 cit-zb-39-115 job-1: Script being run


We see that job-3 runs first, and job-1 runs 90 seconds later, just as we expected.