[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