PaiPix feedback on /usr/sbin/update-rc.d...
Dear colleagues,
We have found a very inconvenient effect of the usual debian
upgrade for a knoppix hard-disk installation. All services that are
installed will become automatically started at boot time. This results
from the fact that the links in /etc/rc0.d ... rc6.d that were erased in
the live installation will be created automatically in the package
upgrade process. I tried to look for solutions and I have found some
suggestions
PS: I have still quite a number of other patches to report but I will
wait a bit not to monopolise this email listing.
on the net that I have adapted.
In fact, the Debian people had the nice insight to force all packages to
create the sysv rc?.d links trough the update-rc.d script. If we change
this script we can control the process. However the information on the
other number on (example S20mysql) links must be kept upon disabling the
service to allow enabling it later.
This patch to update-rc.d defines the enable and disable commands.
To disable the services one has the (PaiPix) /etc/rcS.d/ directory as:
disabled.S05initrd-tools.sh disabled.S39dns-clean
disabled.S07hdparm disabled.S40hotplug
disabled.S15isapnp disabled.S40networking
disabled.S18hwclockfirst.sh disabled.S50hwclock.sh
disabled.S20module-init-tools disabled.S70xfree86-common
disabled.S24raid2 disabled.S75sudo
disabled.S25brltty README
disabled.S25mdadm-raid S00knoppix-autoconfig
See also http://aamorimsrv.fis.fc.ul.pt/
All the best,
Antonio Amorim
PS: I have still quite a number of other patches to report but I will
wait a bit not to monopolize this email listing.
--- /home/aamorim/update-rc.d.old 2005-01-10 15:17:28.000000000 +0000
+++ /usr/sbin/update-rc.d 2005-01-12 01:15:09.000000000 +0000
@@ -17,6 +17,8 @@
usage: update-rc.d [-n] [-f] <basename> remove
update-rc.d [-n] <basename> defaults [NN | sNN kNN]
update-rc.d [-n] <basename> start|stop NN runlvl [runlvl] [...] .
+ update-rc.d [-n] <basename> disable
+ update-rc.d [-n] <basename> enable
-n: not really
-f: force
EOF
@@ -54,6 +56,8 @@
$_ = $ARGV[0];
if (/^remove$/) { &checklinks ("remove"); }
elsif (/^defaults$/) { &defaults; &makelinks }
+elsif (/^enable$/) { &checklinks ("enable"); }
+elsif (/^disable$/) { &checklinks ("disable"); }
elsif (/^(start|stop)$/) { &startstop; &makelinks; }
else { &usage; }
@@ -66,7 +70,7 @@
sub is_link () {
my ($op, $fn, $bn) = @_;
if (! -l $fn) {
- print STDERR "update-rc.d: warning: $fn is not a symbolic link\n";
+# print STDERR "update-rc.d: warning: $fn is not a symbolic link\n";
return 0;
} else {
$linkdst = readlink ($fn);
@@ -86,9 +90,54 @@
print " Removing any system startup links for $initd/$bn ...\n"
if ($_[0] eq 'remove');
+ print " Disabling any system startup links for $initd/$bn ...\n"
+ if ($_[0] eq 'disable');
+ print " Enabling any system startup links for $initd/$bn ...\n"
+ if ($_[0] eq 'enable');
$found = 0;
+
+ foreach $link (listoflinks($bn)) {
+ $found = 1;
+ $islnk = &is_link ($_[0], $link, $bn);
+ next if ($_[0] eq '');
+ if ($_[0] eq 'remove') {
+ if (! $islnk && $link!~/disabled\./) {
+ print " $fn is not a link to ../init.d/$bn; not removing\n";
+ next;
+ }
+ print " $link\n";
+ next if ($notreally);
+ unlink ("$link") || die("update-rc.d: unlink: $!\n");
+ next;
+ }
+ if ($_[0] eq 'disable' && $link!~/disabled\./) {
+ $link=~/etc\/rc([0-9S]).d\/(.*)$/;
+ print " disabling $link i.e. $link => /etc/rc$1.d/disabled.$2\n";
+ next if ($notreally);
+ system("rm -f $link && touch /etc/rc$1.d/disabled.$2");
+ next;
+ }
+ if ($_[0] eq 'enable' && $link=~/disabled\./) {
+ $link=~/etc\/rc([0-9S]).d\/disabled\.(.*)$/;
+ print " enabling $etcd${i.d}$link i.e. $link => /etc/rc$1.d/$2\n";
+ print "rm -f ${i.d}${link} && ln -s /etc/init.d/$bn /etc/rc$1.d/$2\n";
+ next if ($notreally);
+ system("rm -f ${i.d}$link && ln -s ../init.d/$bn /etc/rc$1.d/$2");
+ next;
+ }
+ }
+ $found;
+}
+
+
+sub listoflinks {
+ my ($i, $package, @links);
+ $package=shift;
+ $found = 0;
+ @links=();
+
foreach $i (0..9, 'S') {
unless (chdir ("$etcd$i.d")) {
next if ($i =~ m/^[789S]$/);
@@ -96,25 +145,16 @@
}
opendir(DIR, ".");
foreach $_ (readdir(DIR)) {
- next unless (/^[SK]\d\d$bn$/);
- $fn = "$etcd$i.d/$_";
- $found = 1;
- $islnk = &is_link ($_[0], $fn, $bn);
- next if ($_[0] ne 'remove');
- if (! $islnk) {
- print " $fn is not a link to ../init.d/$bn; not removing\n";
- next;
- }
- print " $etcd$i.d/$_\n";
- next if ($notreally);
- unlink ("$etcd$i.d/$_") ||
- die("update-rc.d: unlink: $!\n");
+ next unless (/((disabled\.)?[SK]\d\d$bn)$/);
+ push (@links, "$etcd$i.d/$1");
+# print "DEBUG: added $etcd$i.d/$1\n";
}
closedir(DIR);
}
- $found;
+ return (@links);
}
+
# Process the arguments after the "defaults" keyword.
sub defaults {
@@ -198,7 +238,8 @@
next if ($links[$i] eq '');
print " $etcd$lvl.d/$links[$i]$bn -> ../init.d/$bn\n";
next if ($notreally);
- symlink("../init.d/$bn", "$etcd$lvl.d/$links[$i]$bn")
+ (-e "$etcd$lvl.d/$links[$i]$bn")
+ || symlink("../init.d/$bn", "$etcd$lvl.d/$links[$i]$bn")
|| die("update-rc.d: symlink: $!\n");
}
}
#! /usr/bin/perl
#
# update-rc.d Update the links in /etc/rc[0-9S].d/
#
# Version: @(#)update-rc.d.pl 2.02 05-Mar-1998 miquels@cistron.nl
#
$initd = "/etc/init.d";
$etcd = "/etc/rc";
$notreally = 0;
# Print usage message and die.
sub usage {
print STDERR "update-rc.d: error: @_\n" if ($#_ >= 0);
print STDERR <<EOF;
usage: update-rc.d [-n] [-f] <basename> remove
update-rc.d [-n] <basename> defaults [NN | sNN kNN]
update-rc.d [-n] <basename> start|stop NN runlvl [runlvl] [...] .
update-rc.d [-n] <basename> disable
update-rc.d [-n] <basename> enable
-n: not really
-f: force
EOF
exit (1);
}
# Check out options.
while($#ARGV >= 0 && ($_ = $ARGV[0]) =~ /^-/) {
shift @ARGV;
if (/^-n$/) { $notreally++; next }
if (/^-f$/) { $force++; next }
if (/^-h|--help$/) { &usage; }
&usage("unknown option");
}
# Action.
&usage() if ($#ARGV < 1);
$bn = shift @ARGV;
if ($ARGV[0] ne 'remove') {
if (! -f "$initd/$bn") {
print STDERR "update-rc.d: $initd/$bn: file does not exist\n";
exit (1);
}
} elsif (-f "$initd/$bn") {
if (!$force) {
printf STDERR "update-rc.d: $initd/$bn exists during rc.d purge (use -f to force)\n";
exit (1);
} else {
printf STDERR "update-rc.d: $initd/$bn exists during rc.d purge (continuing)\n";
}
}
$_ = $ARGV[0];
if (/^remove$/) { &checklinks ("remove"); }
elsif (/^defaults$/) { &defaults; &makelinks }
elsif (/^enable$/) { &checklinks ("enable"); }
elsif (/^disable$/) { &checklinks ("disable"); }
elsif (/^(start|stop)$/) { &startstop; &makelinks; }
else { &usage; }
exit (0);
# Check if there are links in /etc/rc[0-9S].d/
# Remove if the first argument is "remove" and the links
# point to $bn.
sub is_link () {
my ($op, $fn, $bn) = @_;
if (! -l $fn) {
# print STDERR "update-rc.d: warning: $fn is not a symbolic link\n";
return 0;
} else {
$linkdst = readlink ($fn);
if (! defined $linkdst) {
die ("update-rc.d: error reading symbolic link: $!\n");
}
if (($linkdst ne "../init.d/$bn") && ($linkdst ne "../init.d/$bn")) {
print STDERR "update-rc.d: warning: $fn is not a link to ../init.d/$bn\n";
return 0;
}
}
return 1;
}
sub checklinks {
my ($i, $found, $fn, $islnk);
print " Removing any system startup links for $initd/$bn ...\n"
if ($_[0] eq 'remove');
print " Disabling any system startup links for $initd/$bn ...\n"
if ($_[0] eq 'disable');
print " Enabling any system startup links for $initd/$bn ...\n"
if ($_[0] eq 'enable');
$found = 0;
foreach $link (listoflinks($bn)) {
$found = 1;
$islnk = &is_link ($_[0], $link, $bn);
next if ($_[0] eq '');
if ($_[0] eq 'remove') {
if (! $islnk && $link!~/disabled\./) {
print " $fn is not a link to ../init.d/$bn; not removing\n";
next;
}
print " $link\n";
next if ($notreally);
unlink ("$link") || die("update-rc.d: unlink: $!\n");
next;
}
if ($_[0] eq 'disable' && $link!~/disabled\./) {
$link=~/etc\/rc([0-9S]).d\/(.*)$/;
print " disabling $link i.e. $link => /etc/rc$1.d/disabled.$2\n";
next if ($notreally);
system("rm -f $link && touch /etc/rc$1.d/disabled.$2");
next;
}
if ($_[0] eq 'enable' && $link=~/disabled\./) {
$link=~/etc\/rc([0-9S]).d\/disabled\.(.*)$/;
print " enabling $etcd${i.d}$link i.e. $link => /etc/rc$1.d/$2\n";
print "rm -f ${i.d}${link} && ln -s /etc/init.d/$bn /etc/rc$1.d/$2\n";
next if ($notreally);
system("rm -f ${i.d}$link && ln -s ../init.d/$bn /etc/rc$1.d/$2");
next;
}
}
$found;
}
sub listoflinks {
my ($i, $package, @links);
$package=shift;
$found = 0;
@links=();
foreach $i (0..9, 'S') {
unless (chdir ("$etcd$i.d")) {
next if ($i =~ m/^[789S]$/);
die("update-rc.d: chdir $etcd$i.d: $!\n");
}
opendir(DIR, ".");
foreach $_ (readdir(DIR)) {
next unless (/((disabled\.)?[SK]\d\d$bn)$/);
push (@links, "$etcd$i.d/$1");
# print "DEBUG: added $etcd$i.d/$1\n";
}
closedir(DIR);
}
return (@links);
}
# Process the arguments after the "defaults" keyword.
sub defaults {
my ($start, $stop) = (20, 20);
&usage ("defaults takes only one or two codenumbers") if ($#ARGV > 2);
$start = $stop = $ARGV[1] if ($#ARGV >= 1);
$stop = $ARGV[2] if ($#ARGV >= 2);
&usage ("codenumber must be a number between 0 and 99")
if ($start !~ /^\d\d?$/ || $stop !~ /^\d\d?$/);
$start = sprintf("%02d", $start);
$stop = sprintf("%02d", $stop);
$stoplinks[0] = $stoplinks[1] = $stoplinks[6] = "K$stop";
$startlinks[2] = $startlinks[3] =
$startlinks[4] = $startlinks[5] = "S$start";
1;
}
# Process the arguments after the start or stop keyword.
sub startstop {
my($letter, $NN, $level);
while ($#ARGV >= 0) {
if ($ARGV[0] eq 'start') { $letter = 'S'; }
elsif ($ARGV[0] eq 'stop') { $letter = 'K' }
else {
&usage("expected start|stop");
}
if ($ARGV[1] !~ /^\d\d?$/) {
&usage("expected NN after $ARGV[0]");
}
$NN = sprintf("%02d", $ARGV[1]);
shift @ARGV; shift @ARGV;
$level = shift @ARGV;
do {
if ($level !~ m/^[0-9S]$/) {
&usage(
"expected runlevel [0-9S] (did you forget \".\" ?)");
}
if (! -d "$etcd$level.d") {
print STDERR
"update-rc.d: $etcd$level.d: no such directory\n";
exit(1);
}
$level = 99 if ($level eq 'S');
$startlinks[$level] = "$letter$NN" if ($letter eq 'S');
$stoplinks[$level] = "$letter$NN" if ($letter eq 'K');
} while (($level = shift @ARGV) ne '.');
&usage("action with list of runlevels not terminated by \`.'")
if ($level ne '.');
}
1;
}
# Create the links.
sub makelinks {
my($t, $i);
my @links;
if (&checklinks) {
print " System startup links for $initd/$bn already exist.\n";
exit (0);
}
print " Adding system startup for $initd/$bn ...\n";
# nice unreadable perl mess :)
for($t = 0; $t < 2; $t++) {
@links = $t ? @startlinks : @stoplinks;
for($i = 0; $i <= $#links; $i++) {
$lvl = $i;
$lvl = 'S' if ($i == 99);
next if ($links[$i] eq '');
print " $etcd$lvl.d/$links[$i]$bn -> ../init.d/$bn\n";
next if ($notreally);
(-e "$etcd$lvl.d/$links[$i]$bn")
|| symlink("../init.d/$bn", "$etcd$lvl.d/$links[$i]$bn")
|| die("update-rc.d: symlink: $!\n");
}
}
1;
}
Reply to: