Saturday, 18 May 2013

Boot-related updates in raring: forwarding upstart support to Debian

Hi folks,

Now that Debian jessie is open for development, and a few packages
(lsb/insserv/sysvinit/debhelper) have been updated in saucy, at long last
there is an implementation of upstart support in Debian that's compatible
with Ubuntu.

This means that it's now possible to forward our patches for upstart job
support to Debian! When doing merges this cycle on packages that ship
upstart jobs, I would encourage you to look at whether these are in a state
to be forwarded upstream.

Before forwarding upstart jobs, there are a few things to be aware of. The
tl;dr version of this for those who just want to start fixing packages and
forwarding patches can be found at
<https://wiki.ubuntu.com/UpstartCompatibleInitScripts>.

- The new, converged upstart support drops the "upstart-job" virtual
package, which never worked as intended. Instead, as per Debian Policy
9.11.1, packages will now ship both an init script and an upstart job
instead of installing a /lib/init/upstart-job symlink in /etc/init.d.

- This means that the warning messages from /lib/init/upstart-job about not
calling "/etc/init.d/$foo" are now no longer warnings: it is an *error* to
call /etc/init.d/$foo for a service that has an upstart job. In saucy,
the invoke-rc.d and service scripts will both correctly map to either
upstart or sysvinit as appropriate. Admins should take care to use the
"service" interface (supported since the current upstart was introduced in
Ubuntu 9.10), and packages should continue to use 'invoke-rc.d'. Packages
built without using debhelper should manually add a versioned dependency
on 'sysv-rc (>= 2.88dsf-24)' for proper invoke-rc.d support.

- Also per Debian policy, and because of the previous point, init scripts
for packages that also have upstart jobs need to *do nothing* when running
under upstart:

"SysV init scripts for which an equivalent upstart job is available must
query the output of the command `initctl version' for the string
`upstart' and avoid running in favor of the native upstart job, using a
test such as this:
if [ "$1" = start ] && which initctl >/dev/null && initctl version | grep -q upstart
then
exit 1
fi
"

If your init script uses the /lib/lsb/init-functions shell library from
lsb-base, there is a new function, init_is_upstart, which you can use to
do this more simply:

if init_is_upstart; then
exit 1
fi

Init scripts should exit non-zero when called with arguments of 'start',
'restart', or 'force-reload'. When called with an argument of 'stop', it
is recommended to 'exit 0' instead.

Use of 'init_is_upstart' requires a versioned dependency on
'lsb-base (>= 4.1+Debian3)', which you will need to add manually to your
package.

- Since the new init script will be a no-op, packages which normally restart
in the postinst (instead of stopping in the prerm and starting in the
postinst) *MUST* handle stopping the service in their preinst when
upgrading from a pre-upstart-capable version. See the Debian udev package
for an example of this.

And that's it. Your assistance in reducing this delta with Debian is
appreciated. Currently in Ubuntu, we have 301 upstart jobs across 186
packages; my goal is that, by the end of June, patches will be in the Debian
BTS for any of these packages that are available in Debian.

At a later date, I will also be revisiting the question of enabling
insserv/startpar by default in Ubuntu for the remaining sysvinit scripts.
This will further reduce our delta with Debian, improve boot speed for any
systems using significant numbers of non-upstarted packages, and ensure we
avoid further bugs like bug #858122 as a result of incompatibilities with
insserv.

Cheers,
--
Steve Langasek Give me a lever long enough and a Free OS
Debian Developer to set it on, and I can move the world.
Ubuntu Developer http://www.debian.org/
[email protected] [email protected]