[Pkg-sysvinit-devel] Bug#387894: sysv-rc: progress bar

Jean-Damien Durand Jean-Damien.Durand at tele2.fr
Sun Sep 17 10:25:55 UTC 2006


Package: sysv-rc
Version: 2.86.ds1-20
Severity: normal

abour progress bar, here are few fixes and suggestions.

- in debug mode, probably the call to usplash_write should just be echoed
- the count of number of scripts executed is approximate v.s. what happens
  in reality (check if file exist, check of previous runlevel, etc.)
- the computation of what fraction of the bar to fill is not guaranteed to
  reach 0 or 100, because of rouding issues (100/3, then multiplied again)

Please find attached a patch for all these issues, where I factorized the call to kill
and start script in order to avoid code duplication. I let you check and/or reject it, no pb!
Tested with splashutils, not tested with bootsplash.

Cheers, JD.

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.17-beyond3
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)

sysv-rc depends on no packages.

Versions of packages sysv-rc recommends:
ii  lsb-base                      3.1-15     Linux Standard Base 3.1 init scrip

-- no debconf information
-------------- next part --------------
--- /etc/init.d/rc.old	2006-09-08 18:38:56.000000000 +0200
+++ /etc/init.d/rc	2006-09-17 12:11:33.000000000 +0200
@@ -77,13 +77,125 @@
 startup_progress() {
     $@
     if [ "$SPLASH" = true ] ; then
-        step=$(($step + $step_change))
-        progress=$(($step * $progress_size / $num_steps + $first_step))
-        usplash_write "PROGRESS $progress" || true
+	step=$(($step + $step_change))
+	progress=$(($step * $progress_size / $num_steps + $first_step))
+	$debug usplash_write "PROGRESS $progress" || true
+	# If this is was the last step, reset step_change
+	[ "$last_step_change" = "1" ] && step_change=0
     fi
 }
 
 #
+# kill scripts - if 1st argument is "countonly" then nothing is executed
+#
+run_kill_scripts() {
+	if [ "$last_step_change" = "1" ]; then
+	    local_step_change=0
+	else
+	    local_step_change=1
+	fi
+	[ "$1" = "countonly" ] && nkill=0
+	if [ "$previous" != N ]
+	then
+		# Run all scripts with the same level in parallel
+		CURLEVEL=""
+		for s in /etc/rc$runlevel.d/K*
+		do
+			level=$(echo $s | sed 's/.*\/K\([0-9][0-9]\).*/\1/')
+			if [ "$level" = "$CURLEVEL" ]
+			then
+				continue
+			fi
+			CURLEVEL=$level
+			SCRIPTS=""
+			for i in /etc/rc$runlevel.d/K$level*
+			do
+				# Check if the script is there.
+				[ ! -f $i ] && continue
+
+				#
+				# Find stop script in previous runlevel but
+				# no start script there.
+				#
+				suffix=${i#/etc/rc$runlevel.d/K[0-9][0-9]}
+				previous_stop=/etc/rc$previous.d/K[0-9][0-9]$suffix
+				previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
+				#
+				# If there is a stop script in the previous level
+				# and _no_ start script there, we don't
+				# have to re-stop the service.
+				#
+				[ -f $previous_stop ] && [ ! -f $previous_start ] && continue
+
+				# Stop the service.
+				SCRIPTS="$SCRIPTS $i"
+				[ "$1" = "countonly" ] && nkill=$(($nkill + $local_step_change))
+				case "${s##/etc/rc$runlevel.d/S??}" in
+				    gdm|xdm|kdm|reboot|halt)
+					local_step_change=0
+					last_step_change=1
+					;;
+				esac
+			done
+			[ "$1" != "countonly" ] && startup stop $SCRIPTS
+		done
+	fi
+}
+
+#
+# Start scripts - if 1st argument is "countonly" then nothing is executed
+#
+run_start_scripts() {
+	if [ "$last_step_change" = "1" ]; then
+	    local_step_change=0
+	else
+	    local_step_change=1
+	fi
+	[ "$1" = "countonly" ] && nstart=0
+	CURLEVEL=""
+	for s in /etc/rc$runlevel.d/S*
+	do
+		level=$(echo $s | sed 's/.*\/S\([0-9][0-9]\).*/\1/')
+		if [ "$level" = "$CURLEVEL" ]
+		then
+			continue
+		fi
+		CURLEVEL=$level
+		SCRIPTS=""
+		for i in /etc/rc$runlevel.d/S$level*
+		do
+			[ ! -f $i ] && continue
+
+			if [ "$previous" != N ]
+			then
+				#
+				# Find start script in previous runlevel and
+				# stop script in this runlevel.
+				#
+				suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]}
+				stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix
+				previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
+				#
+				# If there is a start script in the previous level
+				# and _no_ stop script in this level, we don't
+				# have to re-start the service.
+				#
+				[ -f $previous_start ] && [ ! -f $stop ] && continue
+			fi
+			SCRIPTS="$SCRIPTS $i"
+			[ "$1" = "countonly" ] && nstart=$(($nstart + $local_step_change))
+			case "${s##/etc/rc$runlevel.d/S??}" in
+			    gdm|xdm|kdm|reboot|halt)
+				local_step_change=0
+				last_step_change=1
+				;;
+			esac
+		done
+		[ "$1" != "countonly" ] && startup $ACTION $SCRIPTS
+	done
+}
+
+#
 # Start script or program.
 #
 case "$CONCURRENCY" in
@@ -201,122 +313,48 @@
 	progress_size=$(((100 - $PROGRESS_STATE) / 3))
 
 	case "$runlevel" in
-		0|6)
-			ACTION=stop
-			# Count down from 0 to -100 and use the entire bar
-			first_step=0
-			progress_size=100
-			step_change=-1
-			;;
-	        S)
-		        ACTION=start
-			# Begin where the initramfs left off and use 2/3
-			# of the remaining space
-			first_step=$PROGRESS_STATE
-			progress_size=$(($progress_size * 2))
-			step_change=1
-			;;
-		*)
-			ACTION=start
-			# Begin where rcS left off and use the final 1/3 of
-			# the space (by leaving progress_size unchanged)
-			first_step=$(($progress_size * 2 + $PROGRESS_STATE))
-			step_change=1
+    	0|6)
+		ACTION=stop
+		# Count down from 0 to -100 and use the entire bar
+		first_step=0
+		progress_size=100
+		step_change=-1
+		;;
+	S)
+		ACTION=start
+		# Begin where the initramfs left off and use 2/3
+		# of the remaining space
+		first_step=$PROGRESS_STATE
+		progress_size=$(($progress_size * 2))
+		step_change=1
+		;;
+	*)
+		ACTION=start
+		# Begin where rcS left off and use the final 1/3 of
+		# the space (by leaving progress_size unchanged)
+		first_step=$(($progress_size * 2 + $PROGRESS_STATE))
+		progress_size=$((100 - $first_step))
+		step_change=1
 			;;
 	esac
 
-        if [ "$SPLASH" = true ] ; then
-	    # Count the number of scripts we need to run (for usplash
-	    # progress bar)
-	    num_steps=0
-            for s in /etc/rc$runlevel.d/[SK]*; do
-                case "${s##/etc/rc$runlevel.d/S??}" in
-                 gdm|xdm|kdm|reboot|halt)
-                    break
-                    ;;
-                esac
-                num_steps=$(($num_steps + 1))
-            done
-            step=0
-        fi
+	# Initalize the last_step_change value
+	last_step_change=0
+	# Count the number of scripts we need to run (for usplash
+	# progress bar)
+	num_steps=0
+	run_kill_scripts countonly
+	run_start_scripts countonly
+	num_steps=$(($nkill+ $nstart))
+	step=0
+	last_step_change=0
 
 	# First, run the KILL scripts.
-	if [ "$previous" != N ]
-	then
-		# Run all scripts with the same level in parallel
-		CURLEVEL=""
-		for s in /etc/rc$runlevel.d/K*
-		do
-			level=$(echo $s | sed 's/.*\/K\([0-9][0-9]\).*/\1/')
-			if [ "$level" = "$CURLEVEL" ]
-			then
-				continue
-			fi
-			CURLEVEL=$level
-			SCRIPTS=""
-			for i in /etc/rc$runlevel.d/K$level*
-			do
-				# Check if the script is there.
-				[ ! -f $i ] && continue
-
-				#
-				# Find stop script in previous runlevel but
-				# no start script there.
-				#
-				suffix=${i#/etc/rc$runlevel.d/K[0-9][0-9]}
-				previous_stop=/etc/rc$previous.d/K[0-9][0-9]$suffix
-				previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
-				#
-				# If there is a stop script in the previous level
-				# and _no_ start script there, we don't
-				# have to re-stop the service.
-				#
-				[ -f $previous_stop ] && [ ! -f $previous_start ] && continue
-
-				# Stop the service.
-				SCRIPTS="$SCRIPTS $i"
-			done
-			startup stop $SCRIPTS
-		done
-	fi
+	run_kill_scripts
 
 	# Now run the START scripts for this runlevel.
 	# Run all scripts with the same level in parallel
-	CURLEVEL=""
-	step=0
-	for s in /etc/rc$runlevel.d/S*
-	do
-		level=$(echo $s | sed 's/.*\/S\([0-9][0-9]\).*/\1/')
-		if [ "$level" = "$CURLEVEL" ]
-		then
-			continue
-		fi
-		CURLEVEL=$level
-		SCRIPTS=""
-		for i in /etc/rc$runlevel.d/S$level*
-		do
-			[ ! -f $i ] && continue
-
-			if [ "$previous" != N ]
-			then
-				#
-				# Find start script in previous runlevel and
-				# stop script in this runlevel.
-				#
-				suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]}
-				stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix
-				previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix
-				#
-				# If there is a start script in the previous level
-				# and _no_ stop script in this level, we don't
-				# have to re-start the service.
-				#
-				[ -f $previous_start ] && [ ! -f $stop ] && continue
-			fi
-			SCRIPTS="$SCRIPTS $i"
-		done
-		startup $ACTION $SCRIPTS
-	done
+	run_start_scripts
 fi
 
 if [ S = "$runlevel" ]


More information about the Pkg-sysvinit-devel mailing list