Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I'm a little confused regarding how jobs start on Upstart events. To illustrate my misunderstanding, I have four Upstart jobs that look like the following:

Job 1:

start on local-filesystems

task

script
    echo "job 1 ran" >> /tmp/job1
end script

Job 2:

start on (local-filesystems and net-device-added)

task

script
    echo "job 2 ran" >> /tmp/job2
end script

Job 3:

start on (local-filesystems and bluetooth-device-added)

task

script
    echo "job 3 ran" >> /tmp/job3
end script

Job 4:

start on local-filesystems or (local-filesystems and net-device-added) or (local-filesystems and bluetooth-device-added)

task

script
    echo "job 4 ran" >> /tmp/job4
end script

I expect the following file contents after a reboot:

/tmp/job1:

job 1 ran

/tmp/job2

job 2 ran

/tmp/job3

job 3 ran

/tmp/job4

job 4 ran
job 4 ran
job 4 ran

I expect Job 4 to have ran three times because it can be started by three separate sets of events, all of which occur as proven by the other jobs. But my expectations are incorrect; the files actually contain the following:

/tmp/job1:

job 1 ran

/tmp/job2

job 2 ran

/tmp/job3

job 3 ran

/tmp/job4

job 4 ran

Why is job4 only being run once, even though all three sets of events are occurring? Is there any way to achieve the behavior of running this job whenever any of the signals occur, regardless of how many times the job actually runs? If it helps, I edited it to print out the $UPSTART_EVENTS variable to see what events are causing job 4, and it's local-filesystems.

To summarize: I would like job 4 to run on the local-filesystems event, AND on the net-device-added event (as long as local_filesystems has occurred as well), AND on the bluetooth-device-added event (as long as local_filesystems has occurred). How do I make that happen?

Thank you!

share|improve this question
add comment

3 Answers

The obvious, although inelegant solution is to create 3 different upstart jobs. You'd just use the jobs 1-3 you created above. I looked into this some in a VM and that's the best I could come up with. I someone has a more elegant solution I'd love to see it.

share|improve this answer
    
Yeah I know... I'm really hoping that's not the solution, haha. There has to be a way to do this! I mean seriously... what's the point of being able to trigger from all these different events if the job only runs once? –  Kyle Nov 24 '12 at 17:44
add comment

The answer is quite simple, you can't respond to multiple events if the job is already running on behalf of any of those conditions. Upstart doesn't record and replay events. If your job is running due to event A, and event A starts, event B occurs, which said job could also respond to. There is no queue that will save event B and replay it to every job that was previously running to evaluate said event again. After all, this is init, and the goal of init scripts is usually to run once.

The bootchart will readily show what signals are emitted concurrently.

You can verify this yourself by configuring your job to respond to an event, make it do something simple like sleep 30s, then while the job is running, emit another (initctl emit foo) event. Once the job has finished running the first time it will not run again.

"To summarize: I would like job 4 to run on the local-filesystems event, AND on the net-device-added event (as long as local_filesystems has occurred as well), AND on the bluetooth-device-added event (as long as local_filesystems has occurred). How do I make that happen?"

http://upstart.ubuntu.com/cookbook/#starting-a-job

It actually spells this sort of conditional execution out quite clearly. That doesn't mean however it will run more than once. You may wish to reconsider solving this problem in this manner to begin with.

share|improve this answer
add comment

start on Only changes the job's goal to start from stop. If the job is already in start, the job is not latched and does nothing with the events in start on.

If you wanted it to run multiple times anyway, you can add this:

instance $UPSTART_EVENTS

With that upstart will run an instance of the job for each event pair that is matched in start on.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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