[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH] Simple parallellized boot sequence (and a plea for LSB complience)



Recently, I have been investigating how to speed up the boot process
in Debian, and during this work, I found a simple way to change
/etc/init.d/rc to run all init.d scripts with the same sequence number
in parallell.  Patch included below.  For this change to work as it
should, we need to make sure init.d-scripts are ordered according to
dependency, so scripts needed by other scripts get a earlier sequence
number.  And to make it possible to generate such ordering, we need to
know the dependencies of a given init.d script.

The simple and standard-complient way to make these assumtions come
true is to insert LSB 2.1 compilent init.d headers in all our init.d
scripts.  They are documented in
<URL:http://refspecs.freestandards.org/LSB_2.1.0/LSB-generic/LSB-generic/initscrcomconv.html>
and look like this:

  ### BEGIN INIT INFO
  # Provides: boot_facility_1 [ boot_facility_2 ...]
  # Required-Start: boot_facility_1 [ boot_facility_2 ...]
  # Required-Stop: boot_facility_1 [ boot_facility_2 ...]
  # Should-Start: boot_facility_1 [ boot_facility_2 ...]
  # Should-Stop: boot_facility_1 [ boot_facility_2 ...]
  # Default-Start: run_level_1 [ run_level_2 ...]
  # Default-Stop: run_level_1 [ run_level_2 ...]
  # Short-Description: short_description
  # Description: multiline_description
  ### END INIT INFO

The important headers here are provides, required-* and should-*.
Please add LSB compilant headers into your init.d scripts.

If these headers are present in all init.d scripts, it is possible to
make sure the order of init.d scripts fulfill the requiremets.  There
is even a tool available to do this for us.  I found insserv in suse,
and patched it to do what I wanted for the SysV rc#.d directories.
Package available from
<URL:http://developer.skolelinux.no/~pere/debian/insserv_1.00.8-0.0.pere.1_i386.deb>.

During my investigation, I came across an old paper on the boot system
in debian, which contain lots of useful info.  Check out
<URL:http://alioth.debian.org/docman/view.php/30730/38/debconf2-initscripts-bkg.pdf>.

I promised you a patch.  Here it is, without the indentation change
(diff -uw) to make it easier to see the real change in the script.

Any comments on this approach?  I had a look at initng, but it does
not seem to use the LSB headers, and I would rather keep using the
normal init.d scripts instead of duplicating the code for initng.

--- /etc/init.d/rc	2004-09-10 17:00:48.000000000 +0200
+++ /tmp/rc-parallell	2005-08-22 00:52:34.000000000 +0200
@@ -59,17 +59,35 @@
 	# First, run the KILL scripts.
 	if [ $previous != N ]
 	then
-		for i in /etc/rc$runlevel.d/K[0-9][0-9]*
+		# Run all scripts with the same level in parallell
+		for level in `ls /etc/rc$runlevel.d | \
+			      grep '^K[0-9][0-9]' | \
+			      cut -c2,3 | sort -u` ; do
+			pids=""
+			for i in /etc/rc$runlevel.d/K$level*
 		do
 			# Check if the script is there.
 			[ ! -f $i ] && continue
 
 			# Stop the service.
-			startup $i stop
+				startup $i stop &
+				pids="$pids $!"
+			done
+			# Wait for all pids.  Does not matter which
+			# pid return first, as we need to wait for all
+			# of them
+			for pid in $pids ; do
+				wait $pid
+			done
 		done
 	fi
 	# Now run the START scripts for this runlevel.
-	for i in /etc/rc$runlevel.d/S*
+
+	# Run all scripts with the same level in parallell
+	for level in `ls /etc/rc$runlevel.d | grep '^S[0-9][0-9]' | \
+		      cut -c2,3 | sort -u` ; do
+		pids=""
+		for i in /etc/rc$runlevel.d/S$level*
 	do
 		[ ! -f $i ] && continue
 
@@ -91,12 +109,20 @@
 		fi
 		case "$runlevel" in
 			0|6)
-				startup $i stop
+					startup $i stop &
 				;;
 			*)
-				startup $i start
+					startup $i start &
 				;;
 		esac
+			pids="$pids $!"
+		done
+		# Wait for all pids.  Does not matter which
+		# pid return first, as we need to wait for all
+		# of them
+		for pid in $pids ; do
+			wait $pid
+		done
 	done
   fi
 # eof /etc/init.d/rc



Reply to: