[Pkg-sysvinit-commits] r1371 - in sysvinit/trunk/debian: . initscripts/etc/init.d initscripts/lib/init

Petter Reinholdtsen pere at alioth.debian.org
Mon Jul 6 15:27:56 UTC 2009


Author: pere
Date: 2009-07-06 15:27:55 +0000 (Mon, 06 Jul 2009)
New Revision: 1371

Added:
   sysvinit/trunk/debian/initscripts/lib/init/usplash-fsck-functions.sh
Modified:
   sysvinit/trunk/debian/changelog
   sysvinit/trunk/debian/initscripts/etc/init.d/checkfs.sh
   sysvinit/trunk/debian/initscripts/etc/init.d/checkroot.sh
Log:
Add improved progress bar during fsck when usplash is used, based
on patch from Martin Pitt and Ubuntu.  Modified Ubuntu patch to
keep the generic splash support when usplash is not used.

Modified: sysvinit/trunk/debian/changelog
===================================================================
--- sysvinit/trunk/debian/changelog	2009-07-03 12:52:56 UTC (rev 1370)
+++ sysvinit/trunk/debian/changelog	2009-07-06 15:27:55 UTC (rev 1371)
@@ -9,6 +9,9 @@
     and another (bootlogs) which can be executed later, to make it possible
     to postpone some work until after gdm/kdm/xdm is started.  Based on
     patch from Scott James Remnant and Ubuntu.
+  * Add improved progress bar during fsck when usplash is used, based
+    on patch from Martin Pitt and Ubuntu.  Modified Ubuntu patch to
+    keep the generic splash support when usplash is not used.
 
  -- Petter Reinholdtsen <pere at debian.org>  Wed, 01 Jul 2009 20:04:20 +0200
 

Modified: sysvinit/trunk/debian/initscripts/etc/init.d/checkfs.sh
===================================================================
--- sysvinit/trunk/debian/initscripts/etc/init.d/checkfs.sh	2009-07-03 12:52:56 UTC (rev 1370)
+++ sysvinit/trunk/debian/initscripts/etc/init.d/checkfs.sh	2009-07-06 15:27:55 UTC (rev 1371)
@@ -19,6 +19,7 @@
 
 . /lib/lsb/init-functions
 . /lib/init/splash-functions-base
+. /lib/init/usplash-fsck-functions.sh
 
 do_start () {
 	# See if we're on AC Power.  If not, we're not gonna run our
@@ -78,12 +79,23 @@
 				sleep 5
 			fi
 		}
-		splash_start_indefinite
 		if [ "$VERBOSE" = no ]
 		then
 			log_action_begin_msg "Checking file systems"
-			logsave -s $FSCK_LOGFILE fsck $spinner -R -A $fix $force $FSCKTYPES_OPT
-			FSCKCODE=$?
+			if usplash_running; then
+			    PROGRESS_FILE=`mktemp` || exit 1
+			    set -m
+			    logsave -s $FSCK_LOGFILE fsck -C3 -R -A $fix $force $FSCKTYPES_OPT >/dev/console 2>&1 3>$PROGRESS_FILE &
+			    set +m
+			    usplash_progress "$PROGRESS_FILE"
+			    rm -f $PROGRESS_FILE
+			else
+			    splash_start_indefinite
+			    logsave -s $FSCK_LOGFILE fsck $spinner -R -A $fix $force $FSCKTYPES_OPT
+			    FSCKCODE=$?
+			    splash_stop_indefinite
+			fi
+
 			if [ "$FSCKCODE" -gt 1 ]
 			then
 				log_action_end_msg 1 "code $FSCKCODE"
@@ -98,8 +110,10 @@
 			else
 				log_action_msg "Will now check all file systems"
 			fi
+			splash_start_indefinite
 			logsave -s $FSCK_LOGFILE fsck $spinner -V -R -A $fix $force $FSCKTYPES_OPT
 			FSCKCODE=$?
+			splash_stop_indefinite
 			if [ "$FSCKCODE" -gt 1 ]
 			then
 				handle_failed_fsck
@@ -108,7 +122,6 @@
 A log is being saved in ${FSCK_LOGFILE} if that location is writable."
 			fi
 		fi
-		splash_stop_indefinite
 	fi
 	rm -f /fastboot /forcefsck 2>/dev/null
 }

Modified: sysvinit/trunk/debian/initscripts/etc/init.d/checkroot.sh
===================================================================
--- sysvinit/trunk/debian/initscripts/etc/init.d/checkroot.sh	2009-07-03 12:52:56 UTC (rev 1370)
+++ sysvinit/trunk/debian/initscripts/etc/init.d/checkroot.sh	2009-07-06 15:27:55 UTC (rev 1371)
@@ -22,6 +22,7 @@
 . /lib/lsb/init-functions
 . /lib/init/mount-functions.sh
 . /lib/init/splash-functions-base
+. /lib/init/usplash-fsck-functions.sh
 
 do_start () {
 	#
@@ -271,12 +272,22 @@
 			spinner=""
 		fi
 		
-		splash_start_indefinite
 		if [ "$VERBOSE" = no ]
 		then
 			log_action_begin_msg "Checking root file system"
-			logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -t $roottype $rootdev
-			FSCKCODE=$?
+			if [ "$roottype" = "ext2" -o "$roottype" = "ext3" -o "$roottype" = "ext4" ] && usplash_running; then
+			    PROGRESS_FILE=`mktemp -p /lib/init/rw` || PROGRESS_FILE=/lib/init/rw/checkroot_fsck
+			    set -m
+			    logsave -s $FSCK_LOGFILE fsck -C3 $force $fix -t $roottype $rootdev >/dev/console 2>&1 3>$PROGRESS_FILE &
+			    set +m
+			    usplash_progress "$PROGRESS_FILE"
+			    rm -f $PROGRESS_FILE
+			else
+			    splash_start_indefinite
+			    logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -t $roottype $rootdev
+			    FSCKCODE=$?
+			    splash_stop_indefinite
+			fi
 			if [ "$FSCKCODE" = 0 ]
 			then
 				log_action_end_msg 0
@@ -284,12 +295,13 @@
 				log_action_end_msg 1 "code $FSCKCODE"
 			fi
 		else
+			splash_start_indefinite
 			log_daemon_msg "Will now check root file system"
 			logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t $roottype $rootdev
 			FSCKCODE=$?
 			log_end_msg $FSCKCODE
+			splash_stop_indefinite
 		fi
-		splash_stop_indefinite
 	fi
 
 	#

Added: sysvinit/trunk/debian/initscripts/lib/init/usplash-fsck-functions.sh
===================================================================
--- sysvinit/trunk/debian/initscripts/lib/init/usplash-fsck-functions.sh	                        (rev 0)
+++ sysvinit/trunk/debian/initscripts/lib/init/usplash-fsck-functions.sh	2009-07-06 15:27:55 UTC (rev 1371)
@@ -0,0 +1,178 @@
+#
+# Functions for reporting fsck progress in usplash
+#
+# (C) 2008 Canonical Ltd.
+# Author: Martin Pitt <martin.pitt at ubuntu.com>
+#
+
+# convert a "pass cur max" progress triple from fsck to a progress percentage
+# based on calc_percent() from e2fsck
+fsck_progress_to_percent() {
+    if [ $1 = 1 ]; then
+        PERCENT=$(($2 * 70 / $3))
+    elif [ $1 = 2 ]; then
+        PERCENT=$(($2 * 20 / $3 + 70))
+    elif [ $1 = 3 ]; then
+        PERCENT=$(($2 * 2 / $3 + 90))
+    elif [ $1 = 4 ]; then
+        PERCENT=$(($2 * 3 / $3 + 92))
+    elif [ $1 = 5 ]; then
+        PERCENT=$(($2 * 5 / $3 + 95))
+    else
+        PERCENT=100
+    fi
+}
+
+# read current fsck status ($PASS, $CUR, $MAX) from file descriptor 4
+# this assumes that fsck was started in the background ($!)
+get_fsck_status()
+{
+        local a b c S
+
+        unset a
+        # only consider the last line
+        while true; do
+            PASS=$a
+            CUR=$b
+            MAX=$c
+            read a b c rest <&4
+            if [ -n "$PASS" ] && [ -z "$a" ]; then
+                break;
+            fi
+
+            # if we did not read anything, check if the process is still
+            # actually running, or just waiting to be reaped
+            if [ -z "$PASS" ] && [ -z "$a" ]; then
+                S=`ps -o state --no-headers -p $!` || break
+                [ "$S" != "Z" ] || break
+                # do not spin while waiting for fsck to start up
+                sleep 0.1
+            fi
+        done
+}
+
+# Set $NAME to a human readable description of which partitions are currently
+# being checked. Set $CLEAN if this is only a routine check on clean
+# partitions which can be skipped.
+get_checked_names ()
+{
+        local DEVS DUMP LABEL
+
+        FSCKPROCS=$(ps --no-headers -C 'fsck.ext2 fsck.ext3 fsck.ext4 fsck.ext4dev' -o pid,args | grep /dev)
+        DEVS=$(echo "$FSCKPROCS" | sed 's_^.*\(/dev/[^[:space:]]*\).*$_\1_')
+        FSCKPIDS=$(echo "$FSCKPROCS" | sed 's_^[[:space:]]*\([[:digit:]]\+\).*$_\1_')
+
+        if [ -z "$DEVS" ]; then
+            unset NAME
+            return 0
+        fi
+
+        CLEAN=1
+        unset NAME
+        for DEV in $DEVS; do
+            DUMP=$(dumpe2fs -h $DEV)
+            if ! echo "$DUMP" | grep -q 'state:[[:space:]]*clean$'; then
+                unset CLEAN
+            fi
+
+            LABEL=$(vol_id --label $DEV)
+            [ -z "$NAME" ] || NAME="$NAME, "
+            if [ -n "$LABEL" ]; then
+                NAME="$NAME$LABEL ($DEV)"
+            else
+                NAME="$NAME$DEV"
+            fi
+        done
+}
+
+# Return true if usplash is active
+usplash_running() {
+    if pidof usplash ; then
+	return 0
+    else
+	return 1
+    fi
+}
+
+# Read fsck progress from file $1 and display progress in usplash.
+usplash_progress() {
+        exec 4<$1
+        unset CANCEL
+        ESCAPE=`/bin/echo -ne "\x1B"`
+        FIRST=1
+        PREVPERCENT=0
+
+        while true; do
+            sleep 0.5
+            get_fsck_status
+            [ -n "$PASS" ] || break
+
+            fsck_progress_to_percent "$PASS" "$CUR" "$MAX"
+
+            # check if fsck advanced to the next drive
+            if [ "$PREVPERCENT" -gt "$PERCENT" ]; then
+                if [ -n "$CANCEL" ]; then
+                    usplash_write "STATUS skip                                                        "
+                else
+                    usplash_write "STATUS                                                             "
+                fi
+                FIRST=1
+            fi
+            PREVPERCENT=$PERCENT
+
+            # lazy initialization of output and progress report on the first
+            # progress line that we receive; this avoids starting the output
+            # for clean or non-ext[234] partitions
+            if [ -n "$FIRST" ]; then
+                usplash_write "TIMEOUT 0"
+
+                # show which device is being checked
+                get_checked_names
+                [ -n "$NAME" ] || break
+
+                usplash_write "VERBOSE on"
+                if [ "$CLEAN" ]; then
+                    usplash_write "TEXT Routine check of drives: $NAME..."
+                    usplash_write "TEXT Press ESC to skip"
+                else
+                    usplash_write "TEXT Unclean shutdown, checking drives:"
+                    usplash_write "TEXT $NAME..."
+                fi
+
+                unset FIRST
+            fi
+
+            usplash_write "STATUS $PERCENT% (stage $PASS/5, $CUR/$MAX)                       "
+            echo "Checking drive $NAME: $PERCENT% (stage $PASS/5, $CUR/$MAX)" >/dev/console
+
+            # ESC interrupts check for clean drives
+            if [ -n "$CLEAN" ]; then
+                if FAIL_NO_USPLASH=1 usplash_write "INPUTCHAR"; then
+                    read ch < /dev/.initramfs/usplash_outfifo
+                    if [ "$ch" = "$ESCAPE" ]; then
+                        kill $FSCKPIDS
+                        CANCEL=1
+                        continue # there might be more drives, so do not break
+                    fi
+                fi
+            fi
+        done
+
+        if [ -n "$CANCEL" ]; then
+            usplash_write "STATUS skip                                                        "
+        else
+            usplash_write "STATUS                                                             "
+        fi
+        usplash_write "VERBOSE default"
+        usplash_write "TEXT Drive checks finished."
+        usplash_write "TIMEOUT 15"
+        wait %1 # to collect fsck's exit code
+        EXITCODE=$?
+        [ -n "$CANCEL" ] && FSCKCODE=0 || FSCKCODE=$EXITCODE
+        if [ "$FSCKCODE" -gt 1 ]; then
+            # non-correctable failure which requires sulogin: quit usplash and
+            # restore stdin/out/err
+            usplash_write "QUIT"
+            exec </dev/console >/dev/console 2>/dev/console
+        fi
+}




More information about the Pkg-sysvinit-commits mailing list