Bug#832945: update-rc.d defaults does not respect disabled state of a sysv init script

Felipe Sateler fsateler at debian.org
Sat Jul 30 21:31:43 BST 2016


On 30 July 2016 at 14:47, Michael Biebl <biebl at debian.org> wrote:
> Am 30.07.2016 um 19:52 schrieb Felipe Sateler:
>> On 29 July 2016 at 17:05, Michael Biebl <biebl at debian.org> wrote:
>>> Am 29.07.2016 um 22:44 schrieb Michael Biebl:
>>>> Package: init-system-helpers
>>>> Version: 1.41
>>>> Severity: serious
>>>>
>>>> Running
>>>> update-rc.d foo disable
>>>> update-rc.d foo defaults
>>>> will create start symlinks although this should not happen for a
>>>> disabled service.
>>>
>>> This happens when insserv is not installed, so is another regression in
>>> our fallback code.
>>
>> Insserv does not create new links if there are already-existing links
>> for that runlevel. So I think the fix (untested) would be:
>>
>> diff --git a/script/update-rc.d b/script/update-rc.d
>> index cbf4339..a01ed5e 100755
>> --- a/script/update-rc.d
>> +++ b/script/update-rc.d
>> @@ -116,15 +116,15 @@ sub make_sysv_links {
>>      my ($lsb_start_ref, $lsb_stop_ref) =
>> parse_def_start_stop("/etc/init.d/$scriptname");
>>      foreach my $lvl (@$lsb_start_ref) {
>>          make_path("/etc/rc$lvl.d");
>> +        continue if glob("/etc/rc$lvl.d/[KS]??$scriptname");
>>          my $l = "/etc/rc$lvl.d/S01$scriptname";
>> -        unlink($l);
>>          symlink("../init.d/$scriptname", $l);
>>      }
>>
>>      foreach my $lvl (@$lsb_stop_ref) {
>>          make_path("/etc/rc$lvl.d");
>> +        continue if glob("/etc/rc$lvl.d/[KS]??$scriptname");
>>          my $l = "/etc/rc$lvl.d/K01$scriptname";
>> -        unlink($l);
>>          symlink("../init.d/$scriptname", $l);
>>      }
>>  }
>>
>>
>
> I think what insserv does, is to compare the LSB header to what symlinks
>  exist on the disk. If there is a difference, it does nothing at all.

Ah, you are correct. Indeed, services moving from runlevel S to
runlevels 2-5 need an explicit remove or they will not be moved.

> Your patch behaves slightly different from what I can see.
> It does the check per runlevel and not as a whole.

The check should be like this then:

diff --git a/script/update-rc.d b/script/update-rc.d
index cbf4339..650eadd 100755
--- a/script/update-rc.d
+++ b/script/update-rc.d
@@ -112,19 +112,20 @@ sub make_sysv_links {
     if ("remove" eq $action) { unlink($_) for
         glob("/etc/rc?.d/[SK][0-9][0-9]$scriptname"); return; }

+    # if the service already has any links, do not touch them
+    return if glob("/etc/rc?.d/[SK][0-9][0-9]$scriptname");
+
     # for "defaults", parse Default-{Start,Stop} and create these links
     my ($lsb_start_ref, $lsb_stop_ref) =
parse_def_start_stop("/etc/init.d/$scriptname");
     foreach my $lvl (@$lsb_start_ref) {
         make_path("/etc/rc$lvl.d");
         my $l = "/etc/rc$lvl.d/S01$scriptname";
-        unlink($l);
         symlink("../init.d/$scriptname", $l);
     }

     foreach my $lvl (@$lsb_stop_ref) {
         make_path("/etc/rc$lvl.d");
         my $l = "/etc/rc$lvl.d/K01$scriptname";
-        unlink($l);
         symlink("../init.d/$scriptname", $l);
     }
 }


-- 

Saludos,
Felipe Sateler




More information about the Pkg-systemd-maintainers mailing list