#680293 update-rc.d: manual: `update-rc.d remove name` works when `/etc/init.d/name` exists

#680293#5
Date:
2012-07-04 20:17:10 UTC
From:
To:
Dear Debian folks,


the manual of `update-rc.d` contains the following paragraph.

        $ man update-rc.d
        […]
        When invoked with the remove option, update-rc.d removes any
        links in the /etc/rcrunlevel.d directories to the
        script /etc/init.d/name. The script must have been deleted
        already.  If the script is still present then update-rc.d aborts
        with an error message.
        […]

It looks like `update-rc.d remove name` still works though when the
script in `/etc/init.d/name` is not removed beforehand.

        $ sudo update-rc.d pulseaudio remove
        update-rc.d: using dependency based boot sequencing
        $ ls -l /etc/init.d/pulseaudio
        -rwxr-xr-x 1 root root 2227  1. Okt 2011  /etc/init.d/pulseaudio
        $ ls -l /etc/rc*.d/*audio
        ls: Zugriff auf /etc/rc*.d/*audio nicht möglich: Datei oder Verzeichnis nicht gefunden
        $ sudo service pulseaudio stop
        PulseAudio configured for per-user sessions ... (warning).

Does the manual need updating?

I guess the bug has been present for a longer time, so please update the
version information accordingly.

Two more or less related notes.

1. The printing of `update-rc.d: using dependency based boot sequencing`
is unexpected.

2. To disable an init.d script, is it better to just remove the
executable flag of `/etc/init.d/name` with the latest changes in
2.88dsf-28?


Thanks,

Paul

#680293#10
Date:
2012-07-04 20:33:33 UTC
From:
To:
This is my understanding.  It should only remove the links if you use
"-f remove" to force removal.

No, I think the manual is correct and update-rc.d is not behaving as
documented.  Mind you, I've not seen this before.  But I can also
reproduce it:

% ls /etc/init.d/cups
/etc/init.d/cups
% ls /etc/rc*.d/*cups
/etc/rc1.d/K01cups  /etc/rc2.d/S04cups  /etc/rc3.d/S04cups  /etc/rc4.d/S04cups  /etc/rc5.d/S04cups
% sudo update-rc.d cups remove
update-rc.d: using dependency based boot sequencing
% ls /etc/rc*.d/*cups
zsh: no matches found: /etc/rc*.d/*cups
% sudo update-rc.d cups defaults
update-rc.d: using dependency based boot sequencing
% ls /etc/rc*.d/*cups
/etc/rc1.d/K01cups  /etc/rc2.d/S04cups  /etc/rc3.d/S04cups  /etc/rc4.d/S04cups  /etc/rc5.d/S04cups

I'm fairly sure this didn't happen until recently.  But there were only
two changes to update-rc.d in 2012, and both were trivial changes which
didn't affect this.  This will need investigating in more detail.

It's always done this when using insserv AFAIK.  If you hadn't
converted to using dependency based boot until 2.88dsf-28, this might
be new though.

I think we should remove it in wheezy+1 though, or even wheezy if it's
not going to cause too much confusion--should people who have been
converted to dependency based boot be reminded of the fact every time
update-rc.d is run?

You can do that, certainly.  Or just use "update-rc.d service disable":

% sudo update-rc.d cups disable
update-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `cups' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (1 2 3 4 5) of script `cups' overwrites defaults (1).
% ls /etc/rc*.d/*cups
/etc/rc1.d/K01cups  /etc/rc2.d/K01cups  /etc/rc3.d/K01cups  /etc/rc4.d/K01cups  /etc/rc5.d/K01cups

% sudo update-rc.d cups enable
update-rc.d: using dependency based boot sequencing
% ls /etc/rc*.d/*cups
/etc/rc1.d/K01cups  /etc/rc2.d/S04cups  /etc/rc3.d/S04cups  /etc/rc4.d/S04cups  /etc/rc5.d/S04cups

This converts the start links to stop links, and enable reverses this.


Regards,
Roger

#680293#15
Date:
2012-07-04 21:00:53 UTC
From:
To:
Am Mittwoch, den 04.07.2012, 21:33 +0100 schrieb Roger Leigh:

I wonder though, what is the disadvantage of leaving `/etc/init.d/name`
behind and `-f` has to be used to do so?

I tried it on a system with sysv-rc 2.88dsf-22.1 which has *not* been
converted to dependency based boot yet. There it behaved as described in
the manual.

        $ ls -l /etc/init.d/pulseaudio
        -rwxr-xr-x 1 root root 2249 Mai 18 20:54 /etc/init.d/pulseaudio
        $ sudo update-rc.d pulseaudio remove
        update-rc.d: /etc/init.d/pulseaudio exists during rc.d purge (use -f to force)

I used `update-rc.d` the first time, but the output looked strange to
me.

I guess the other maintainers and developers should answer that.

Thank you for the explanation. Although skimming through the manual
pages, I did not find how these links are used. Links starting with »S«
are executed with the `start` argument and links starting with »K« with
the `stop` argument?


Thanks,

Paul

#680293#20
Date:
2012-07-04 22:01:25 UTC
From:
To:
I'm not entirely certain of the historical reasons, but it's likely a
safety feature to prevent accidental removal of links, since you could
make your system unbootable if you removed a critical link.

As above, I think it's not so much about leaving the init script behind,
as it is about preventing removing needed links inadvertently.

Thanks, that's useful to know.

Yes.  This is classic System V init behaviour.  When you enter a runlevel,
you run all the S links with "start".  When you leave a runlevel, you
run all the "K" links with "stop"; actually the ways the scripts are run
when you switch runlevels isn't quite that straightforward, but that's
almost essentially what happens.


Regards,
Roger

#680293#33
Date:
2018-07-15 01:34:56 UTC
From:
To:
On Wed, 04 Jul 2012 23:00:53 +0200 Paul Menzel <pm.debian@googlemail.com> wrote:
of the same name. For example, the packages "ntp" and "ntpsec" both
provide a service called "ntp". (I am the maintainer of ntpsec.) A user
hit this in bug #901439:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=901439

Consider this series of steps:
1) apt install ntp
2) apt install ntpsec
3) apt purge ntp

Step 1 creates /etc/init.d/ntp and the symlinks. Step 2 results in the
ntp package being removed, and ntpsec's /etc/init.d/ntp installed
instead. Step 3 results in ntp's postrm script, by way of the standard
dh_installinit snippet, calling `update-rc.d ntp remove`.

Expected results:
/etc/rc*.d/*ntp symlinks are left alone.

Actual results:
/etc/rc*.d/*ntp symlinks are deleted.


Purging ntp after installing ntpsec seems to be fairly common with
users. Accordingly, I'm raising the severity of this bug to important. I
would mark it serious, but I can't currently point to an explicit policy
item being violated nor am I the maintainer of this package (nor a
release manager).

The same thing happens, for the exact same reasons, if you start with
ntpsec, install ntp, then purge ntpsec.

#680293#40
Date:
2018-07-20 04:47:32 UTC
From:
To:
My current intention is to rename the service from ntp.service to
ntpsec.service. Accordingly, I'm undoing my severity change here.

#680293#47
Date:
2019-01-11 12:37:04 UTC
From:
To:
[2018-07-19 23:47] Richard Laager <rlaager@wiktel.com>

For what it worth, you may be interested virtual facilities
(/etc/insserv.conf). We could introduce new virtual dependency $ntp,
provided by either ntp or ntpsec package.

#680293#52
Date:
2019-01-11 12:37:07 UTC
From:
To:
control: tags -1 +patch

[2012-07-04 22:17] Paul Menzel <pm.debian@googlemail.com>
patch, that adjust behaviour of update-rc.d to match manpage.


From 46c7069cf9253399540cb0a75c51e164293e8689 Mon Sep 17 00:00:00 2001
From: Dmitry Bogatov <KAction@debian.org>
Date: Thu, 10 Jan 2019 15:57:35 +0000
Subject: [PATCH] update-rc.d: refuse to remove links to present script

Fix behaviour of update-rc.d to match manual page: throw error on
attemps to remove links to script, that is not removed.
(Closes: #680293)
---
 script/update-rc.d | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/script/update-rc.d b/script/update-rc.d
index 71fb1a6..870af0e 100755
--- a/script/update-rc.d
+++ b/script/update-rc.d
@@ -193,7 +193,7 @@ sub create_sequence {
     $sysv_insserv->{remove} = sub {
         my ($scriptname) = @_;
         if ( -f "/etc/init.d/$scriptname" ) {
-            return system($insserv, @opts, "-r", $scriptname) >> 8;
+            error("/etc/init.d$scriptname exists, refusing `remove' action.");
         } else {
             # insserv removes all dangling symlinks, no need to tell it
             # what to look for.

#680293#59
Date:
2019-01-11 15:14:04 UTC
From:
To:
My initial desire to use "ntp" as the service name was for
backwards-compatibility with system administrators, not other services'
dependencies, so a virtual dependency wouldn't matter.

Somewhat related, there is an existing $time virtual service:
https://wiki.debian.org/LSBInitScripts

Note that ntpsec (like ntp) is not providing a $time implementation. The
$time service should depend on an ntpwait service, not simply ntpd,
because $time is defined as when the clock is _set_.

If you wish to discuss that further, we should move off this bug, either
to private email or to a new bug on ntpsec.

#680293#64
Date:
2025-05-15 22:22:43 UTC
From:
To:
If this bug is ever fixed, please make sure that '-f' still allows the
symlinks to be removed.

Currently the only way to restore the symlinks to the defaults specified
by the initscript are 'remove' followed by 'defaults' because the
'defaults' operation, inexplicably to me, won't set the defaults unless
there are no symlinks at all.

#339460 is marked as WONTFIX and #731905 doesn't seem to think this
situtation ('defaults' not doing anything useful for an
already-installed script) is a problem so presumably the behaviour of
'defaults' isn't ever going to change, so let's at least make sure
'remove -f' remains to let users and maintscripts do a forcible revert
to defaults when required.

Thanks!

#680293#69
Date:
2025-05-16 12:43:55 UTC
From:
To:
As I understand it, the reason for this is that maintainer scripts do
`update-rc.d scriptname defaults`, and that should preserve sysadmin
removals of symlinks (because the syadmin doesn't want something to
run).

The *current* convention (which bends the rules about preserving
sysadmin changes but in a way that kinda works for people) is that if
you remove just `S` symlinks but leave the `K` symlinks you can prevent
something from starting, but if you remove *all* the symlinks then
`defaults` will reinstall them.