[Pkg-sysvinit-commits] r1561 - in sysvinit/trunk/debian: . sysv-rc/man8 sysv-rc/sbin
Petter Reinholdtsen
pere at alioth.debian.org
Wed Jul 29 12:01:41 UTC 2009
Author: pere
Date: 2009-07-29 12:01:30 +0000 (Wed, 29 Jul 2009)
New Revision: 1561
Added:
sysvinit/trunk/debian/sysv-rc.postinst
sysvinit/trunk/debian/sysv-rc/man8/update-bootsystem-insserv.8
sysvinit/trunk/debian/sysv-rc/sbin/update-bootsystem-insserv
Modified:
sysvinit/trunk/debian/changelog
sysvinit/trunk/debian/control
sysvinit/trunk/debian/rules
sysvinit/trunk/debian/sysv-rc.postrm
sysvinit/trunk/debian/sysv-rc/sbin/update-rc.d
Log:
Migrate the code to enable dependency based boot sequencing from
insserv to sysv-rc. Make sysv-rc replace and conflict with
insserv (<= 1.12.0-10) for this. Migration is now a one-way
process. Now update-bootsystem-insserv is only called once
(Closes: #538934). The change make it possible to remove both
sysv-rc and insserv (Closes: #538959).
Modified: sysvinit/trunk/debian/changelog
===================================================================
--- sysvinit/trunk/debian/changelog 2009-07-28 15:18:19 UTC (rev 1560)
+++ sysvinit/trunk/debian/changelog 2009-07-29 12:01:30 UTC (rev 1561)
@@ -9,6 +9,12 @@
rcS.d/, no longer valid with dependency based boot sequencing.
* Make sysv-rc depend on initscripts (>= 2.86.ds1-63) to make sure we
get scripts working with makefile style concurrent booting.
+ * Migrate the code to enable dependency based boot sequencing from
+ insserv to sysv-rc. Make sysv-rc replace and conflict with
+ insserv (<= 1.12.0-10) for this. Migration is now a one-way
+ process. Now update-bootsystem-insserv is only called once
+ (Closes: #538934). The change make it possible to remove both
+ sysv-rc and insserv (Closes: #538959).
-- Petter Reinholdtsen <pere at debian.org> Tue, 28 Jul 2009 16:03:06 +0200
Modified: sysvinit/trunk/debian/control
===================================================================
--- sysvinit/trunk/debian/control 2009-07-28 15:18:19 UTC (rev 1560)
+++ sysvinit/trunk/debian/control 2009-07-29 12:01:30 UTC (rev 1561)
@@ -39,8 +39,8 @@
Package: sysv-rc
Architecture: all
Recommends: lsb-base (>= 3.0-6)
-Conflicts: file-rc
-Replaces: file-rc
+Conflicts: file-rc, insserv (<= 1.12.0-10)
+Replaces: file-rc, insserv (<= 1.12.0-10)
Suggests: sysv-rc-conf, bum
Depends: initscripts (>= 2.86.ds1-63), sysvinit-utils (>= 2.86.ds1-62), insserv (>= 1.12.0-10)
Description: System-V-like runlevel change mechanism
Modified: sysvinit/trunk/debian/rules
===================================================================
--- sysvinit/trunk/debian/rules 2009-07-28 15:18:19 UTC (rev 1560)
+++ sysvinit/trunk/debian/rules 2009-07-29 12:01:30 UTC (rev 1561)
@@ -272,6 +272,7 @@
install -d -o root -g root -m 755 $(tmp)/etc
install -d -o root -g root -m 755 $(tmp)/usr/share
install -d -o root -g root -m 755 $(tmp)$(doc)/sysv-rc
+ install -d -o root -g root -m 755 $(tmp)/var/lib/insserv
install -o root -g root -m 644 debian/sysv-rc/doc/* $(tmp)$(doc)/sysv-rc
sed -ne '/sysvinit (2.84-3)/q' -e p < debian/changelog \
> $(tmp)$(doc)/sysv-rc/changelog.Debian
@@ -302,6 +303,7 @@
$(tmp)/usr/share/man/es/man8
install -o root -g root -m 755 debian/sysv-rc/sbin/invoke-rc.d $(tmp)/usr/sbin
install -o root -g root -m 755 debian/sysv-rc/sbin/update-rc.d $(tmp)/usr/sbin
+ install -o root -g root -m 755 debian/sysv-rc/sbin/update-bootsystem-insserv $(tmp)/usr/sbin
gzip -9f $(tmp)/usr/share/man/man*/*.[0-9] \
$(tmp)/usr/share/man/??/man*/*.[0-9] \
$(tmp)/usr/share/man/??.*/man*/*.[0-9]
Added: sysvinit/trunk/debian/sysv-rc/man8/update-bootsystem-insserv.8
===================================================================
--- sysvinit/trunk/debian/sysv-rc/man8/update-bootsystem-insserv.8 (rev 0)
+++ sysvinit/trunk/debian/sysv-rc/man8/update-bootsystem-insserv.8 2009-07-29 12:01:30 UTC (rev 1561)
@@ -0,0 +1,23 @@
+.\" Copyright 2005 Petter Reinholdtsen
+.\" May be distributed under the GNU General Public License
+.TH "update-bootsystem-insserv" "8" "29 July 2009" "Petter Reinholdtsen" ""
+.SH "NAME"
+update\-bootsystem\-insserv \- reorder boot system based on dependency
+information in the init.d scripts
+.SH "SYNOPSIS"
+.B update\-bootsystem\-insserv
+.SH "DESCRIPTION"
+.B update\-bootsystem\-insserv
+can be used to change the sysv\-rc boot order based on dependency
+information available in LSB init.d format in the init.d scripts or
+in override files in /usr/share/insserv/overrides/* and
+/etc/insserv/overrides/*.
+.SH "FILES"
+/etc/insserv.conf
+/etc/insserv/overrides/*
+/usr/share/insserv/overrides/*
+/var/lib/insserv/using-insserv
+.SH "SEE ALSO"
+update\-rc.d(8), insserv(8)
+.SH "AUTHOR"
+Petter Reinholdtsen, <pere at hungry.com>
Added: sysvinit/trunk/debian/sysv-rc/sbin/update-bootsystem-insserv
===================================================================
--- sysvinit/trunk/debian/sysv-rc/sbin/update-bootsystem-insserv (rev 0)
+++ sysvinit/trunk/debian/sysv-rc/sbin/update-bootsystem-insserv 2009-07-29 12:01:30 UTC (rev 1561)
@@ -0,0 +1,196 @@
+#!/bin/sh
+#
+# Author: Petter Reinholdtsen
+# Date: 2005-09-03
+#
+# Update the boot order based on init.d script dependency info
+
+set -e
+
+now=`date +%Y%m%dT%H%M`
+logdir=/var/lib/insserv
+backupfile="$logdir/bootscripts-$now.tar.gz"
+listfile="$logdir/bootscripts-$now-after.list"
+logfile="$logdir/run-$now.log"
+flagfile="$logdir/using-insserv"
+
+# Make sure insserv is in path
+PATH=/sbin:$PATH
+
+convert_rc_s_to_k() {
+ runlevel=$1
+ for link in $(cd $target/etc/rc$runlevel.d; ls S* || true); do
+ set `echo $link|sed "s%S\(..\)\(.*\)%\1 \2%"`
+ seq=$1
+ service=$2
+ mv $target/etc/rc$runlevel.d/$link $target/etc/rc$runlevel.d/K$seq$service
+ done
+}
+
+# Recreate sysv boot sequence by calling the postinst for all packages
+# with init.d scripts, to get them to call update-rc.d again.
+regenerate_sysv_sequence() {
+ packages="$(dpkg -S $(find /etc/init.d -type f -perm /+x) 2>/dev/null | cut -d: -f1 | sort -u)"
+
+ for p in $packages ; do
+ # Make sure it is installed
+ if dpkg --get-selections $p | grep -qw install ; then
+ # Only fix packages with init.d scripts
+ if dpkg -L $p | grep -q /etc/init.d/ ; then
+ brokenpackages="$brokenpackages $p"
+ fi
+ fi
+ done
+
+ # Remove the old sequence
+ find /etc/rc[S0123456].d -type l -print0 | xargs -0 rm
+
+ # As the sysv-rc update-rc.d script do not check dependencies, it
+ # is enough to run through these scripts once.
+ for p in $brokenpackages ; do
+ if [ -x /var/lib/dpkg/info/$p.postinst ] ; then
+ echo "info: running package $p postinst"
+ DEBCONF_FRONTEND=noninteractive \
+ /var/lib/dpkg/info/$p.postinst configure < /dev/null || true
+ else
+ echo "error: package $p got init.d script but no postinst"
+ fi
+ done
+
+ # Using postinst directly might mess up the terminal. Try to recover
+ reset || true
+}
+
+deactivate_inserv() {
+ if [ ! -f $flagfile ] ; then
+ echo "error: The boot system is not currently converted to insserv."
+ echo "error: Flag file $flagfile is missing."
+ echo "error: Unable to remove the use of insserv."
+ exit 1
+ fi
+
+ # Check if there has been changes, or if it is safe to restore
+ # from backup
+
+ # Pick the last list of symlinks.
+ for file in $logdir/bootscripts-*-after.list ; do
+ listfile=$file
+ done
+ ls /etc/init.d /etc/rc*.d > "$logdir/current.list"
+
+ # If the rc.d scripts order look like it did when we converted, it
+ # is safe to restore.
+ if [ -f $listfile ] && cmp $logdir/current.list $listfile ; then
+ rm "$logdir/current.list"
+ echo "info: Restoring using backed up copy of init.d/ and rc*.d/."
+ for backup in $logdir/bootscripts-*.tar.gz ; do
+ backupfile=$backup
+ done
+ if [ -f "$backupfile" ] ; then
+ (cd /etc; rm -rf init.d rc*.d; tar zxf $backupfile)
+ echo "info: successfully restored backup of init.d scripts"
+ rm $flagfile
+ else
+ echo "error: Unable to locate backup file"
+ exit 1
+ fi
+ else
+ rm "$logdir/current.list"
+ echo "error: Unable to restore the boot sequence. Invalid backup."
+ echo "error: Trying to recover by reconfiguring all packages with init.d scripts."
+ regenerate_sysv_sequence
+ rm -f $flagfile
+ fi
+
+ # Remove files generated by insserv
+ rm -f /etc/init.d/.depend.boot
+ rm -f /etc/init.d/.depend.start
+ rm -f /etc/init.d/.depend.stop
+}
+
+is_unsafe_to_activate() {
+ # Refuse to convert when there are obsolete init.d scripts left
+ # behind, as these tend to confuse the boot sequence.
+ echo "info: Checking if it is safe to convert to dependency based boot."
+ retval=1
+ for package in $(dpkg -S $(find /etc/init.d -type f -perm /+x) \
+ 2>/dev/null | cut -d: -f1 | sort -u); do
+ obsolete_initscripts=$(dpkg-query -W -f='${Conffiles}\n' $package | \
+ grep 'obsolete$' | grep -o '/etc/init.d/[^ ]\+') || :
+ if [ "$obsolete_initscripts" ]; then
+ for initscript in $obsolete_initscripts; do
+ if [ -e "$initscript" ]; then
+ echo "error: Obsolete conffile $initscript left behind by package $package"
+ retval=0
+ fi
+ done
+ fi
+ done
+
+ insserv -nv > $logfile 2>&1 || true
+ if egrep -q 'There is a loop between|already provided!|provides system facility' $logfile ; then
+ echo "error: Problems running insserv:"
+ egrep 'There is a loop between|loop involving service|already provided!|provides system facility' $logfile | sed 's/^/ /'
+ rm $logfile
+ retval=0
+ fi
+ return $retval
+}
+
+activate_insserv() {
+ if is_unsafe_to_activate ; then
+ cat <<EOF
+info: Please check out this manually.
+info: Refusing to convert boot sequence until this is fixed
+info: See http://wiki.debian.org/LSBInitScripts/DependencyBasedBoot
+info: for more information on how to solve these issues. Most likely,
+info: it is a bug in the binary package with the init.d script in
+info: question, and not with insserv.
+EOF
+ exit 1
+ fi
+
+ echo "info: Backing up existing boot scripts in $backupfile"
+ (cd /etc; tar zcf $backupfile init.d rc*.d)
+
+ echo "info: Reordering boot system, log to $logfile"
+ (
+ echo "info: Converting rc0.d/S* and rc6.d/S* to K*."
+ convert_rc_s_to_k 0
+ convert_rc_s_to_k 6
+ echo "info: running insserv"
+ insserv -v
+ ) > $logfile 2>&1
+
+ echo "info: Recording new boot sequence in $listfile"
+ ls /etc/init.d /etc/rc*.d > $listfile
+
+ echo "info: Use '$0 restore' to restore the old boot sequence."
+ touch $flagfile
+}
+
+case "$1" in
+ enable|'')
+ activate_insserv
+ ;;
+ disable|restore)
+ echo "Disabling dependency based boot sequencing is not supported!"
+ # deactivate_inserv
+ exit 1
+ ;;
+ check)
+ if is_unsafe_to_activate ; then
+ echo "warning: It is not safe to convert to dependency based boot."
+ exit 1
+ else
+ echo "info: It is safe to convert to dependency based boot."
+ exit 0
+ fi
+ ;;
+ *)
+ echo "error: Unknown argument '$1'"
+ exit 1
+ ;;
+esac
+
+exit 0
Modified: sysvinit/trunk/debian/sysv-rc/sbin/update-rc.d
===================================================================
--- sysvinit/trunk/debian/sysv-rc/sbin/update-rc.d 2009-07-28 15:18:19 UTC (rev 1560)
+++ sysvinit/trunk/debian/sysv-rc/sbin/update-rc.d 2009-07-29 12:01:30 UTC (rev 1561)
@@ -27,6 +27,12 @@
exit (1);
}
+# Dependency based boot sequencing is active
+if ( -f "/var/lib/insserv/using-insserv" ) {
+ info("using dependency based boot sequencing");
+ exit insserv_updatercd(@ARGV);
+}
+
# Check out options.
my $force;
@@ -73,6 +79,19 @@
exit (0);
+sub info {
+ print STDOUT "update-rc.d: @_\n";
+}
+
+sub warning {
+ print STDERR "update-rc.d: warning: @_\n";
+}
+
+sub error {
+ print STDERR "update-rc.d: error: @_\n";
+ exit (1);
+}
+
# Check if there are links in /etc/rc[0-9S].d/
# Remove if the first argument is "remove" and the links
# point to $bn.
@@ -80,7 +99,7 @@
sub is_link () {
my ($op, $fn, $bn) = @_;
if (! -l $fn) {
- print STDERR "update-rc.d: warning: $fn is not a symbolic link\n";
+ warning "$fn is not a symbolic link\n";
return 0;
} else {
my $linkdst = readlink ($fn);
@@ -88,7 +107,7 @@
die ("update-rc.d: error reading symbolic link: $!\n");
}
if (($linkdst ne "../init.d/$bn") && ($linkdst ne "$initd/$bn")) {
- print STDERR "update-rc.d: warning: $fn is not a link to ../init.d/$bn or $initd/$bn\n";
+ warning "$fn is not a link to ../init.d/$bn or $initd/$bn\n";
return 0;
}
}
@@ -153,7 +172,7 @@
} else {
for my $key (split(/\|/, lc($lsbheaders))) {
if (!exists $lsbinfo{$key}) {
- print STDERR "update-rc.d: warning: $initdscript missing LSB keyword '$key'\n";
+ warning "$initdscript missing LSB keyword '$key'\n";
}
}
}
@@ -316,3 +335,146 @@
1;
}
+
+## Dependency based
+sub insserv_updatercd {
+ my @args = @_;
+ my @opts;
+ my $scriptname;
+ my $action;
+ my $notreally = 0;
+
+ while($#args >= 0 && ($_ = $args[0]) =~ /^-/) {
+ shift @args;
+ if (/^-n$/) { push(@opts, $_); $notreally++; next }
+ if (/^-f$/) { push(@opts, $_); next }
+ if (/^-h|--help$/) { &usage; }
+ usage("unknown option");
+ }
+
+ usage("not enough arguments") if ($#args < 1);
+
+ $scriptname = shift @args;
+ $action = shift @args;
+ if ("remove" eq $action) {
+ if ( -f "/etc/init.d/$scriptname" ) {
+ exec "insserv", @opts, "-r", $scriptname;
+ } else {
+ # insserv removes all dangling symlinks, no need to tell it
+ # what to look for.
+ exec "insserv", @opts;
+ }
+ } elsif ("defaults" eq $action || "start" eq $action ||
+ "stop" eq $action) {
+ # All start/stop/defaults arguments are discarded so emit a
+ # message if arguments have been given. When update-rc.d is
+ # used in package maintainer scripts output is almost always
+ # redirected to /dev/null thanks to dh_installinit, so this
+ # should not be too noisy.
+ if ($#args >= 0) {
+ info("\`$action @args' overridden by LSB info of $scriptname");
+ }
+ if ( -f "/etc/init.d/$scriptname" ) {
+ exec "insserv", @opts, $scriptname;
+ } else {
+ error("initscript does not exist: /etc/init.d/$scriptname");
+ }
+ } elsif ("disable" eq $action || "enable" eq $action) {
+ insserv_toggle($action, $scriptname, @args);
+ # Call insserv to resequence modified links
+ exec "insserv", @opts, $scriptname;
+ } else {
+ usage();
+ }
+}
+
+sub parse_def_start {
+ my $script = shift;
+ my (%lsb, @def_start_lvls);
+
+ open my $fh, '<', $script or error("unable to read $script");
+ while (<$fh>) {
+ chomp;
+ if (m/^### BEGIN INIT INFO$/) {
+ $lsb{'begin'}++;
+ }
+ elsif (m/^### END INIT INFO$/) {
+ $lsb{'end'}++;
+ last;
+ }
+ elsif ($lsb{'begin'} and not $lsb{'end'}) {
+ if (m/^# Default-Start:\s*(\S?.*)$/) {
+ @def_start_lvls = split(' ', $1);
+ }
+ }
+ }
+ close($fh);
+
+ return @def_start_lvls;
+}
+
+sub insserv_toggle {
+ my ($act, $name) = (shift, shift);
+ my ($lsb_header, @runlevels, @symlinks);
+
+ # Prefer insserv override file if it exists.
+ if (-s "/etc/insserv/overrides/$name") {
+ $lsb_header = "/etc/insserv/overrides/$name";
+ } elsif (-s "/etc/init.d/$name") {
+ $lsb_header = "/etc/init.d/$name";
+ } elsif (-s "/usr/share/insserv/overrides/$name") {
+ # These overrides take effect only when no LSB info is
+ # in /etc/init.d/$name
+ $lsb_header = "/usr/share/insserv/overrides/$name";
+ } else {
+ error("cannot find an initscript for $name");
+ }
+
+ # Extra arguments to disable|enable action are runlevels. If none
+ # given parse LSB info for Default-Start value.
+ if ($#_ >= 0) {
+ @runlevels = @_;
+ } else {
+ @runlevels = parse_def_start($lsb_header);
+ if ($#runlevels < 0) {
+ error("$name Default-Start contains no runlevels, aborting.");
+ }
+ }
+
+ # Find symlinks in rc.d directories. Refuse to modify links in runlevels
+ # not used for normal system start sequence.
+ for my $lvl (@runlevels) {
+ if ($lvl !~ /^[S2345]$/) {
+ warning("$act action will have no effect on runlevel $lvl");
+ next;
+ }
+ push(@symlinks, $_) for glob("/etc/rc$lvl.d/[SK][0-9][0-9]$name");
+ }
+
+ if (!@symlinks) {
+ error("no runlevel symlinks to modify, aborting!");
+ }
+
+ # Toggle S/K bit of script symlink.
+ for my $cur_lnk (@symlinks) {
+ my $sk;
+ my @new_lnk = split(//, $cur_lnk);
+
+ if ("disable" eq $act) {
+ $sk = rindex($cur_lnk, '/S') + 1;
+ next if $sk < 1;
+ $new_lnk[$sk] = 'K';
+ } else {
+ $sk = rindex($cur_lnk, '/K') + 1;
+ next if $sk < 1;
+ $new_lnk[$sk] = 'S';
+ }
+
+ if ($notreally) {
+ printf("rename(%s, %s)\n", $cur_lnk, join('', @new_lnk));
+ next;
+ }
+
+ rename($cur_lnk, join('', @new_lnk)) or error($!);
+ }
+}
Added: sysvinit/trunk/debian/sysv-rc.postinst
===================================================================
--- sysvinit/trunk/debian/sysv-rc.postinst (rev 0)
+++ sysvinit/trunk/debian/sysv-rc.postinst 2009-07-29 12:01:30 UTC (rev 1561)
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+set -e
+
+# Based on code from dash postinst
+check_divert() {
+ package=insserv
+ div=$(dpkg-divert --list $2)
+ distrib=${4:-$2.distrib}
+ case "$1" in
+ true)
+ if [ -z "$div" ]; then
+ dpkg-divert --package $package --divert $distrib --add $2
+ cp -dp $2 $distrib
+ ln -sf $3 $2
+ fi
+ ;;
+ false)
+ if [ -n "$div" ] && [ -z "${div%%*by $package}" ]; then
+ mv $distrib $2
+ dpkg-divert --remove $2
+ fi
+ ;;
+ status) # Return true if the divert is in effect
+ if [ -n "$div" ] && [ -z "${div%%*by $package}" ]; then
+ :
+ else
+ false
+ fi
+ esac
+}
+
+# Remove divert if it exist. It was dropped in insserv 1.12.0-11 and
+# sysvinit 2.87dsf-3, 2009-07-29.
+check_divert false /usr/sbin/update-rc.d \
+ /usr/sbin/update-rc.d-insserv
+
+case "$1" in
+ configure)
+ if [ -f /var/lib/insserv/using-insserv ] ; then
+ enabled=true
+ else
+ if update-bootsystem-insserv ; then
+ echo "success: Boot system now have dependency based sequencing"
+ : # All OK
+ else
+ echo "error: Unable to enable dependency based boot system."
+ fi
+ fi
+ ;;
+ *)
+ ;;
+esac
+
+#DEBHELPER#
Modified: sysvinit/trunk/debian/sysv-rc.postrm
===================================================================
--- sysvinit/trunk/debian/sysv-rc.postrm 2009-07-28 15:18:19 UTC (rev 1560)
+++ sysvinit/trunk/debian/sysv-rc.postrm 2009-07-29 12:01:30 UTC (rev 1561)
@@ -15,4 +15,13 @@
ln -sf /usr/share/sysvinit/update-rc.d /usr/sbin/update-rc.d
ln -sf /usr/share/sysvinit/update-rc.d /usr/sbin/invoke-rc.d
+# Remove files generated by insserv
+rm -f /etc/init.d/.depend.boot
+rm -f /etc/init.d/.depend.start
+rm -f /etc/init.d/.depend.stop
+
+# Remove the flag file indicating dependency based boot sequencing, to
+# make sure we convert / update if migrating back from file-rc.
+rm /var/lib/insserv/using-insserv
+
exit 0
More information about the Pkg-sysvinit-commits
mailing list