Debian Bug report logs - #588085
package-provided code should never call init scripts directly

version graph

Package: debian-policy; Maintainer for debian-policy is Debian Policy List <debian-policy@lists.debian.org>; Source for debian-policy is src:debian-policy.

Reported by: Raphael Geissert <geissert@debian.org>

Date: Sun, 4 Jul 2010 19:15:01 UTC

Severity: wishlist

Found in version 3.9.0

Reply or subscribe to this bug.

Toggle useless messages

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to debian-bugs-dist@lists.debian.org, Debian Policy List <debian-policy@lists.debian.org>:
Bug#588085; Package debian-policy. (Sun, 04 Jul 2010 19:15:04 GMT) Full text and rfc822 format available.

Message #3 received at submit@bugs.debian.org (full text, mbox):

From: Raphael Geissert <geissert@debian.org>
To: submit@bugs.debian.org
Subject: debian-policy: require that package-provided code never calls init scripts directly without the user's direction
Date: Sun, 4 Jul 2010 14:11:17 -0500
[Message part 1 (text/plain, inline)]
Package: debian-policy
Version: 3.9.0
Severity: wishlist

Hi,

With the risk of making this request too broad, I think there's no good reason 
why any code (i.e. not just scripts) provided by a package (whether it comes 
from upstream or was added by the maintainer) should ever call an init script 
directly, except for the case where the users request the code to do it on 
their behalf.

== Analysis of current situation ==

Currently known violations:

[1] lists the following packages:

+ sendmail-base: real violation of current 9.3.3.2
+ docbookwiki: it calls 'mysql status,' but IMO the whole logic is wrong (not 
to mention that the output of the init script is not redirected to /dev/null 
and would cause errors on the query sent to mysql.)
+ nvidia-glx-legacy-71xx-dev: it starts 'nvidia-glx' on 'configure.'
+ nvidia-glx-legacy-96xx-dev: it starts 'nvidia-glx' on 'purge,' 'remove,' and 
'configure.'

[2], which is at the moment limited to /etc scripts, lists:

+ initscripts: the stop-bootlogd* scripts just call the bootlogd script with 
the 'stop' action, /etc/network/if-up.d/mountnfs could be said to fit in a).
+ ifupdown: just another implementation detail, 'ifupdown stop' calls 
'ifupdown-clean start' to cleanup.
+ lpr: more or less fine, because it first checks if the daemon is already 
running (but doesn't use pid files.)
+ xtradius: its cron.daily script calls 'radiusd restart' which does start the 
daemon if it wasn't running already.
+ resolvconf: it restarts bind/bind9, stops 'nscd' directly via s-s-d but 
later starts it via the init script.

One example from logrotate.d that has affected me in the past: tor.
There's also apache2's logrotate config file, but the init script doesn't 
(re)start the server if it wasn't already running.

== Counter argument ==

If a service is manually started by the user, while it is disabled for the 
given runlevel, using invoke-rc.d prevents the service from being restarted 
when, for example, rotating the logs.

If want to support manually starting services that are disabled in the current 
runlevel, and I think we should, then the current invoke-rc.d implementation 
is not enough. What we usually want is a "do if started" policy, i.e. a state-
based policy.
This very kind of policy could be used for maintainer scripts to finally fix the 
bugs where the services are started during a package upgrade even if they were 
not running before the upgrade started.

A possible way to implement this state-based policy without relying on the 
underlying boot system would be to require packages and users to never call 
init script directly and to make service(8) the interface to init scripts for 
the user. service(8) and invoke-rc.d(8) would then work together to keep a 
state cache, which would be used by invoke-rc.d.

What do the others think?

Related discussion:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=445203#17
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=445203#30

[1] http://lintian.debian.org/tags/maintainer-script-calls-init-script-
directly.html
[2] http://lintian.debian.org/tags/script-calls-init-script-directly.html

Cheers,
-- 
Raphael Geissert - Debian Developer
www.debian.org - get.debian.net
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Debian Policy List <debian-policy@lists.debian.org>:
Bug#588085; Package debian-policy. (Sun, 04 Jul 2010 19:27:09 GMT) Full text and rfc822 format available.

Acknowledgement sent to Julien Cristau <jcristau@debian.org>:
Extra info received and forwarded to list. Copy sent to Debian Policy List <debian-policy@lists.debian.org>. (Sun, 04 Jul 2010 19:27:09 GMT) Full text and rfc822 format available.

Message #8 received at 588085@bugs.debian.org (full text, mbox):

From: Julien Cristau <jcristau@debian.org>
To: Raphael Geissert <geissert@debian.org>, 588085@bugs.debian.org
Subject: Re: Bug#588085: debian-policy: require that package-provided code never calls init scripts directly without the user's direction
Date: Sun, 4 Jul 2010 20:23:45 +0100
[Message part 1 (text/plain, inline)]
On Sun, Jul  4, 2010 at 14:11:17 -0500, Raphael Geissert wrote:

> A possible way to implement this state-based policy without relying on the 
> underlying boot system would be to require packages and users to never call 
> init script directly and to make service(8) the interface to init scripts for 
> the user. service(8) and invoke-rc.d(8) would then work together to keep a 
> state cache, which would be used by invoke-rc.d.
> 
> What do the others think?
> 
I think such state should be kept by init (which knows, or should know,
which services/processes are running), not by invoke-rc.d(8) and
service(8).  And I think we should ditch sysvinit.  So I think making
these scripts even more complex is unnecessary in the long run.

Cheers,
Julien
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Debian Policy List <debian-policy@lists.debian.org>:
Bug#588085; Package debian-policy. (Sun, 04 Jul 2010 19:54:09 GMT) Full text and rfc822 format available.

Acknowledgement sent to Steve Langasek <vorlon@debian.org>:
Extra info received and forwarded to list. Copy sent to Debian Policy List <debian-policy@lists.debian.org>. (Sun, 04 Jul 2010 19:54:09 GMT) Full text and rfc822 format available.

Message #13 received at 588085@bugs.debian.org (full text, mbox):

From: Steve Langasek <vorlon@debian.org>
To: Raphael Geissert <geissert@debian.org>, 588085@bugs.debian.org
Subject: Re: Bug#588085: debian-policy: require that package-provided code never calls init scripts directly without the user's direction
Date: Sun, 4 Jul 2010 12:50:35 -0700
On Sun, Jul 04, 2010 at 02:11:17PM -0500, Raphael Geissert wrote:
> With the risk of making this request too broad, I think there's no good
> reason why any code (i.e. not just scripts) provided by a package (whether
> it comes from upstream or was added by the maintainer) should ever call an
> init script directly, except for the case where the users request the code
> to do it on their behalf.

I think this is a misstatement of the problem.  The question is not whether
packages should be allowed to *call an init script* when not under the
user's direction; it's whether a package should be allowed to start a
service that's not already running, or stop one that is running, when not
under the user's direction.

That's *entirely* different from the purpose of invoke-rc.d, which is for
setting policy for whether or not to start a service in cases we *know* this
is allowed.

> + docbookwiki: it calls 'mysql status,' but IMO the whole logic is wrong (not 
> to mention that the output of the init script is not redirected to /dev/null 
> and would cause errors on the query sent to mysql.)

Doesn't sound to me like something that needs further policy changes, then. 
Calling 'invoke-rc.d mysql status' should work fine for those purposes
anyway.

> + initscripts: the stop-bootlogd* scripts just call the bootlogd script with 
> the 'stop' action,

Nothing to be prohibited.  bootlogd is a boot-time logger; users are not
meant to have the option of leaving this running after startup.

> /etc/network/if-up.d/mountnfs could be said to fit in a).

This is probably a bug - bringing up a network interface should not cause
nfs-common and portmap to start out of runlevel just because nfs mounts are
defined in /etc/fstab.  But I'm not convinced a policy change is the right
response.

> + xtradius: its cron.daily script calls 'radiusd restart' which does start the 
> daemon if it wasn't running already.

A bug, should be fixed - but falls under "not allowed to start a daemon
that's not already running", not "needs to use invoke-rc.d".

> + resolvconf: it restarts bind/bind9, stops 'nscd' directly via s-s-d but 
> later starts it via the init script.

Sounds pretty buggy.

> == Counter argument ==

> If a service is manually started by the user, while it is disabled for the 
> given runlevel, using invoke-rc.d prevents the service from being restarted 
> when, for example, rotating the logs.

Right, that's one of several problems with tying this to invoke-rc.d.

> If want to support manually starting services that are disabled in the
> current runlevel, and I think we should, then the current invoke-rc.d
> implementation is not enough. What we usually want is a "do if started"
> policy, i.e. a state-based policy.
> This very kind of policy could be used for maintainer scripts to finally
> fix the bugs where the services are started during a package upgrade even
> if they were not running before the upgrade started.

> A possible way to implement this state-based policy without relying on the 
> underlying boot system would be to require packages and users to never call 
> init script directly and to make service(8) the interface to init scripts for 
> the user. service(8) and invoke-rc.d(8) would then work together to keep a 
> state cache, which would be used by invoke-rc.d.

> What do the others think?

I think that's unrealistic and infeasible, and that 'service' is the wrong
interface for this anyway (even though it's the right interface for users to
use when starting services manually).

-- 
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/
slangasek@ubuntu.com                                     vorlon@debian.org




Changed Bug title to 'package-provided code should never call init scripts directly' from 'debian-policy: require that package-provided code never calls init scripts directly without the user's direction' Request was from Russ Allbery <rra@debian.org> to control@bugs.debian.org. (Wed, 07 Jul 2010 15:45:04 GMT) Full text and rfc822 format available.

Information forwarded to debian-bugs-dist@lists.debian.org, Debian Policy List <debian-policy@lists.debian.org>:
Bug#588085; Package debian-policy. (Thu, 22 Jul 2010 05:57:03 GMT) Full text and rfc822 format available.

Message #18 received at 588085@bugs.debian.org (full text, mbox):

From: Raphael Geissert <geissert@debian.org>
To: 588085@bugs.debian.org
Subject: Re: Bug#588085: debian-policy: require that package-provided code never calls init scripts directly without the user's direction
Date: Thu, 22 Jul 2010 00:54:30 -0500
[Message part 1 (text/plain, inline)]
On Sunday 04 July 2010 14:23:45 Julien Cristau wrote:
> On Sun, Jul  4, 2010 at 14:11:17 -0500, Raphael Geissert wrote:
> > A possible way to implement this state-based policy without relying on
> > the underlying boot system would be to require packages and users to
> > never call init script directly and to make service(8) the interface to
> > init scripts for the user. service(8) and invoke-rc.d(8) would then work
> > together to keep a state cache, which would be used by invoke-rc.d.
> > 
> > What do the others think?
> 
> I think such state should be kept by init (which knows, or should know,
> which services/processes are running), not by invoke-rc.d(8) and
> service(8).  And I think we should ditch sysvinit.  So I think making
> these scripts even more complex is unnecessary in the long run.

While I agree this is unnecessarily more complex to achieve with the current 
and mainline system/design, even if we move to upstart or any other boot 
system, we must:
a) preserve SysV compatibility, and
b) for the sake of sanity: provide and use common interfaces that work for all 
the systems.

What seems to concern to Policy here, is that the interfaces and their 
capabilities must be defined.

Cheers,
-- 
Raphael Geissert - Debian Developer
www.debian.org - get.debian.net
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Debian Policy List <debian-policy@lists.debian.org>:
Bug#588085; Package debian-policy. (Thu, 22 Jul 2010 06:30:06 GMT) Full text and rfc822 format available.

Message #21 received at 588085@bugs.debian.org (full text, mbox):

From: Raphael Geissert <geissert@debian.org>
To: 588085@bugs.debian.org
Subject: Re: Bug#588085: debian-policy: require that package-provided code never calls init scripts directly without the user's direction
Date: Thu, 22 Jul 2010 01:26:50 -0500
[Message part 1 (text/plain, inline)]
On Sunday 04 July 2010 14:50:35 Steve Langasek wrote:
> On Sun, Jul 04, 2010 at 02:11:17PM -0500, Raphael Geissert wrote:
> > With the risk of making this request too broad, I think there's no good
> > reason why any code (i.e. not just scripts) provided by a package
> > (whether it comes from upstream or was added by the maintainer) should
> > ever call an init script directly, except for the case where the users
> > request the code to do it on their behalf.
> 
> I think this is a misstatement of the problem.  The question is not whether
> packages should be allowed to *call an init script* when not under the
> user's direction; it's whether a package should be allowed to start a
> service that's not already running, or stop one that is running, when not
> under the user's direction.
> 
> That's *entirely* different from the purpose of invoke-rc.d, which is for
> setting policy for whether or not to start a service in cases we *know*
> this is allowed.

Agreed, invoke-rc.d (as it is currently defined) is not the appropriate 
solution.

> > == Counter argument ==
> > 
> > If a service is manually started by the user, while it is disabled for
> > the given runlevel, using invoke-rc.d prevents the service from being
> > restarted when, for example, rotating the logs.
> 
> Right, that's one of several problems with tying this to invoke-rc.d.
> 
> > If want to support manually starting services that are disabled in the
> > current runlevel, and I think we should, then the current invoke-rc.d
> > implementation is not enough. What we usually want is a "do if started"
> > policy, i.e. a state-based policy.
> > This very kind of policy could be used for maintainer scripts to finally
> > fix the bugs where the services are started during a package upgrade even
> > if they were not running before the upgrade started.
> > 
> > A possible way to implement this state-based policy without relying on
> > the underlying boot system would be to require packages and users to
> > never call init script directly and to make service(8) the interface to
> > init scripts for the user. service(8) and invoke-rc.d(8) would then work
> > together to keep a state cache, which would be used by invoke-rc.d.
> > 
> > What do the others think?
> 
> I think that's unrealistic and infeasible, and that 'service' is the wrong
> interface for this anyway (even though it's the right interface for users
> to use when starting services manually).

service(8) and invoke-rc.d(8) could (should) just talk to a boot system-
provided layer that knows how to deal and take advantage of the boot system's 
features (or the lack of.)

I agree it sounds infeasible (making sure everyone and everything use the 
right interface,) but there are two things that I think need to be considered:

1) The move to different boot systems already requires some degree of 
compatibility and common interfaces between the previous and the new systems.
Take the case of service(8) as an example: since it provides a seamless 
interface to sysv init scripts and upstart jobs people are likely to start 
using it always. With service(8) you don't need to first check if there's a 
script in /etc/init.d and then look at /etc/init/*.conf
With the adoption of this interface, it is easier to hook things up.

2) What are the alternative solutions?

Cheers,
-- 
Raphael Geissert - Debian Developer
www.debian.org - get.debian.net
[signature.asc (application/pgp-signature, inline)]

Send a report that this bug log contains spam.


Debian bug tracking system administrator <owner@bugs.debian.org>. Last modified: Mon Apr 21 10:13:37 2014; Machine Name: buxtehude.debian.org

Debian Bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.