init: support mutually exclusive jobs

Reported by keesj on 2009-03-04
4
Affects Status Importance Assigned to Milestone
upstart
Wishlist
Unassigned

Bug Description

When two services are mutually exclusive it should not be possible to
have booth services running at the same time

We have a scenario where we have two services that are mutually exclusive.
We call them service_a and service_b. The Service a and b are defined to stop
when the other service is started(in service_a we have stop on starting_b and vice
versa).

This simple approach works as we intended. When ever we start service_b and service_a was running service_a will FIRST be stopped:

# initctl start service_a
starting service_a
started service_a
# initctl start service_b
stopping service_a
stopped service_a
starting service_b
started service_b
# initctl start service_a
stopping service_b
stopped service_b
starting service_a
started service_a

We get into trouble when we define a third service(service_c) that depends on service_b.
What we do is that we add an extra stop condition in service a (stop on starting service_c) and also add in service_b we add the extra condition (start on starting service_c)

When we start service_c we expect that FIRST service_a gets stopped and only after service_b gets started Just like in the previous example however this does not happen and we don't understand why

How to reproduce:
put service_a service_b and service_b in your directory

#issue the following command and see service_a is started
initctl start service_a
#issue the following command and see that starting service_b stops service_a
initctl start service_b
#issue the following command to have service_a running
initctl start service_a

#not start service_c and see things go wrong: first service_b is started
and only after that service_a is stopped
# initctl start service_c
starting service_b
stopping service_a
started service_b
stopped service_a
starting service_c
started service_c

keesj (keesj) wrote :
keesj (keesj) wrote :
keesj (keesj) wrote :
keesj (keesj) wrote :

Adding an event log

Jan 1 00:00:52 upstart: service_c goal changed from stop to start
Jan 1 00:00:52 upstart: service_c state changed from waiting to starting
Jan 1 00:00:52 upstart: event_new: Pending starting event
Jan 1 00:00:52 upstart: Handling starting event
Jan 1 00:00:52 upstart: job_register: Registered instance /com/ubuntu/Upstart/jobs/service_5fb/_
Jan 1 00:00:52 upstart: event_pending_handle_jobs: New instance service_b
Jan 1 00:00:52 upstart: service_b goal changed from stop to start
Jan 1 00:00:52 upstart: service_b state changed from waiting to starting
Jan 1 00:00:52 upstart: event_new: Pending starting event
Jan 1 00:00:52 upstart: service_a goal changed from start to stop
Jan 1 00:00:52 upstart: service_a state changed from running to stopping
Jan 1 00:00:52 upstart: event_new: Pending stopping event
Jan 1 00:00:52 upstart: Handling starting event
Jan 1 00:00:52 upstart: event_finished: Finished starting event
Jan 1 00:00:52 upstart: service_b state changed from starting to pre-start
Jan 1 00:00:52 upstart: service_b pre-start process (339)
Jan 1 00:00:52 upstart: Handling stopping event
Jan 1 00:00:52 upstart: event_finished: Finished stopping event
Jan 1 00:00:52 upstart: service_a state changed from stopping to killed
Jan 1 00:00:52 upstart: service_a state changed from killed to post-stop
Jan 1 00:00:53 upstart: service_a post-stop process (342)
Jan 1 00:01:02 upstart: service_b pre-start process (339) exited normally
Jan 1 00:01:02 upstart: service_b state changed from pre-start to spawned
Jan 1 00:01:02 upstart: service_b state changed from spawned to post-start
Jan 1 00:01:02 upstart: service_b state changed from post-start to running
Jan 1 00:01:02 upstart: event_new: Pending started event
Jan 1 00:01:02 upstart: Handling started event
Jan 1 00:01:02 upstart: event_finished: Finished started event
Jan 1 00:01:03 upstart: service_a post-stop process (342) exited normally
Jan 1 00:01:03 upstart: service_a state changed from post-stop to waiting
Jan 1 00:01:03 upstart: event_new: Pending stopped event
Jan 1 00:01:03 upstart: job_change_state: Destroyed inactive instance service_a
Jan 1 00:01:03 upstart: event_finished: Finished starting event
Jan 1 00:01:03 upstart: service_c state changed from starting to pre-start
Jan 1 00:01:03 upstart: service_c pre-start process (345)
Jan 1 00:01:03 upstart: Handling stopped event
Jan 1 00:01:03 upstart: event_finished: Finished stopped event
Jan 1 00:01:13 upstart: service_c pre-start process (345) exited normally
Jan 1 00:01:13 upstart: service_c state changed from pre-start to spawned
Jan 1 00:01:13 upstart: service_c state changed from spawned to post-start
Jan 1 00:01:13 upstart: service_c state changed from post-start to running
Jan 1 00:01:13 upstart: event_new: Pending started event
Jan 1 00:01:13 upstart: Handling started event
Jan 1 00:01:13 upstart: event_finished: Finished started event

As discussed on IRC, Upstart is behaving as designed here - it's just that the design doesn't support what you're trying to do.

We should allow mutually exclusive jobs though, for example:

  while not gdm

summary: - inconsitent dependency handling
+ init: support mutually exclusive jobs
Changed in upstart:
importance: Undecided → Wishlist
status: New → Triaged
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers