/lib/init/upstart-job should not start/restart a job which is disabled.

Bug #974147 reported by James Hunt
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
upstart (Ubuntu)
Fix Released
Medium
James Hunt

Bug Description

Package maintainer scripts often call:

    invoke-rc.d $service restart

... to ensure that if a service is running, it gets restarted after upgrade. invoke-rc.d is a SysV tool and the premise here is that calling /etc/init.d/$service will be a NOP if the service in question has not been enabled (for example /etc/default/$service might contain 'DISABLED=1' or similar).

However, with Upstart, this premise isn't correct. For an Upstart job, calling 'invoke-rc.d $service restart' calls /lib/init/upstart-job which then calls "stop $service; start $service". The problem here is that if the service was disabled using the 'manual' stanza, *it will still be started*.

This happens since what 'manual' does is to clear the 'start on' condition such that if an admin
disables a job using 'manual', it won't start on boot but it *will* start if forced with 'start'.
So, given the following, foo *will* start:

sudo stop foo
echo manual|sudo tee -a /etc/init/foo.override
sudo invoke-rc.d foo restart
      \-> /lib/init/upstart-job
            \-> start foo

To counter this, we could add a '--honour-manual' option to 'start' and make /lib/init/upstart-job
specify this option such that 'invoke-rc.d <name> restart' would only start a job if it had not
been explicitly disabled.

In fact, there is a simpler method: have /lib/init/upstart-job check to see if the job has a
'start on' condition. Crucially, note that the command below will *not* show a 'start on'
condition if the job was disabled using the 'manual' stanza:

    initctl show-config -e "$JOB"|grep 'start on'

Then:

- if the job is running and has a 'start on', stop then start it (existing behaviour).
- if the job is not running and has a 'start on', start it (existing behaviour).
- if the job is running and does not have a 'start on', stop then start it
  (since it was forcibly started).
- if the job is not running and does not have a 'start on', do nothing.

The last scenario being the key one.

Related branches

James Hunt (jamesodhunt)
Changed in upstart (Ubuntu):
assignee: nobody → James Hunt (jamesodhunt)
status: New → In Progress
importance: Undecided → Medium
Revision history for this message
Steve Langasek (vorlon) wrote :

+1 for having upstart-job check for a start condition before starting a job. Please make sure that when asked to *stop* a job, however, that it correctly stops any service that had been started manually; and that if the service is running and it's asked to restart, that the job will be restarted even if not configured to start automatically.

As an aside, for upstart in Ubuntu this logic will have to be put in invoke-rc.d since /lib/init/upstart-job will not be used there.

Changed in upstart (Ubuntu):
assignee: James Hunt (jamesodhunt) → nobody
status: In Progress → New
Revision history for this message
Steve Langasek (vorlon) wrote :

Sorry, I mean for upstart in *Debian* :)

James Hunt (jamesodhunt)
Changed in upstart (Ubuntu):
assignee: nobody → James Hunt (jamesodhunt)
status: New → In Progress
Revision history for this message
James Hunt (jamesodhunt) wrote :

Hi Steve,

The changes already will stop a job that was started manually (since we fall through the 'if' tests and invoke "$COMMAND "$JOB", where $COMMAND is 'stop').

I've tweaked the logic for restart such that for disabled jobs the behaviour is now:

- if the job is running, 'upstart-job start' will just exit
  (since nothing to do).

- if the job is not running, 'upstart-job start' will just exit
  (since job is disabled).

- if the job is running, 'upstart-job stop' will stop the job
  (since job was forced into start state).

- if the job is not running, 'upstart-job stop' will just exit
  (since nothing to do).

- if the job is running, 'upstart-job restart' will restart the job
  (since job was forced into start state and admins will expect this behaviour).

- if the job is not running, 'upstart-job restart' will just exit
  (since job is disabled).

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package upstart - 1.5-0ubuntu5

---------------
upstart (1.5-0ubuntu5) precise; urgency=low

  * debian/upstart-job: Add in handling for disabled jobs:
    - Do not restart a job if disabled, unless job was forcibly started.
    - Do stop a disabled job that was forcibly started.
    Resolves issue where 'invoke-rc.d restart' erroneously started disabled
    jobs on package upgrade (LP: #974147)
 -- James Hunt <email address hidden> Tue, 10 Apr 2012 09:19:03 +0100

Changed in upstart (Ubuntu):
status: In Progress → Fix Released
Revision history for this message
Loïc Minier (lool) wrote :

Thanks!

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.