[Pkg-sysvinit-devel] Bug#734901: initscripts: More Proper Detection of "fastboot" Kernel Parameter necessary

Sebastian.Steinhuber sebastian.steinhuber at googlemail.com
Fri Jan 10 17:28:30 UTC 2014


Package: initscripts
Version: 2.88dsf-45
Severity: normal

Dear maintainers,

during boot, Debian forces checking of hard disks/partitions, what is IMHO an
important thing to do. Since fsck during boot is not performed due to the
"i915.fastboot=1" kernel parameter, it seems adequate to set a higher
importance
to the issue, feel free to change that, but not running fsck might cause
serious
data loss.

For reference, my fstab entry for / is:
UUID=c501653f-ad06-43b5-90e1-8e8ff8e6f903 / ext4 user_xattr 0 1

but

$ LC_ALL=C LANG=C grep -i -w -s "fastboot" /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-3.10.26-dq67sw+ [...] i915.fastboot=1 [...]

returns "0" and tells checkfs.sh and checkroot.sh to skip the fs checks,
claiming "Fast boot enabled, so skipping file system check.":

$ grep -m1 "fastboot" /etc/init.d/checkfs.sh /etc/init.d/checkroot.sh
/etc/init.d/checkfs.sh: if [ -f /fastboot ] || grep -s -w -i "fastboot"
/proc/cmdline
/etc/init.d/checkroot.sh: if [ -f /fastboot ] || grep -s -w -i "fastboot"
/proc/cmdline

However, obviously  "i915.fastboot=1" != "fastboot".
Regarding this excerpt from man grep:
      -w, --word-regexp
              Select  only  those  lines  containing  matches  that form whole
              words.  The test is that the matching substring must  either  be
              at  the  beginning  of  the  line,  or  preceded  by  a non-word
              constituent character.  Similarly, it must be either at the  end
              of  the  line  or  followed by a non-word constituent character.
              Word-constituent  characters  are  letters,  digits,   and   the
              underscore.
it seems to me that grep treats the [.=] characters as word constituent
characters. Grep may be broken in some way (?), it does not work.

LC_ALL=C LANG=C grep -i -s '\<fastboot\>' /proc/cmdline does not work either,
same behaviour; some strange unicode error (grep 2.15-2 and 2.12-2 affected),
or are [.=] characters part of the "letters" set? FYI, grep on an ubuntu 13.10
behaves the same regaring these characters.

As a workaround I have changed the line containing the grep command:

 -      if [ -f /fastboot ] || grep -s -w -i "fastboot" /proc/cmdline
 +      if [ -f /fastboot ] || grep -s -i " fastboot" /proc/cmdline

which does the trick in this case. IMHO it should be save to assume the
preceeding space charakter for "fastboot" as a kernel parameter.
Maybe I did miss something, but I hope this could be helpful.


Best,
        Sebastian



-- System Information:
Debian Release: jessie/sid
  APT prefers unstable
  APT policy: (501, 'unstable'), (501, 'testing'), (501, 'stable'), (500, 'proposed-updates'), (500, 'experimental'), (200, 'testing'), (200, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.10.26-dq67sw+ (SMP w/4 CPU cores)
Locale: LANG=de_DE.utf8, LC_CTYPE=de_DE.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages initscripts depends on:
ii  coreutils       8.21-1
ii  debianutils     4.4
ii  libc6           2.17-97
ii  lsb-base        4.1+Debian12
ii  mount           2.20.1-5.5
ii  sysv-rc         2.88dsf-45
ii  sysvinit-utils  2.88dsf-45

Versions of packages initscripts recommends:
ii  e2fsprogs  1.42.9-2
ii  psmisc     22.20-1

initscripts suggests no packages.

-- Configuration Files:
/etc/default/rcS changed:

/etc/default/tmpfs changed:
RAMTMP=yes

/etc/init.d/checkfs.sh changed:
PATH=/sbin:/bin:/usr/bin
FSCK_LOGFILE=/var/log/fsck/checkfs
[ "$FSCKFIX" ] || FSCKFIX=no
.. /lib/init/vars.sh
.. /lib/lsb/init-functions
.. /lib/init/swap-functions.sh
do_start () {
	# Trap SIGINT so that we can handle user interupt of fsck.
	trap "" INT
	# See if we're on AC Power.  If not, we're not gonna run our
	# check.  If on_ac_power (in /usr/) is unavailable, behave as
	# before and check all file systems needing it.
	BAT=""
	fscheck="yes"
	if [ -f /fastboot ] || grep -s -i " fastboot" /proc/cmdline
	then
		[ "$fscheck" = yes ] && log_warning_msg "Fast boot enabled, so skipping file system check."
		fscheck=no
	fi
	#
	# Check the rest of the file systems.
	#
	if [ "$fscheck" = yes ] && [ ! "$BAT" ] && [ "$FSCKTYPES" != "none" ]
	then
		# Execute swapon command again, in case there are lvm
		# or md swap partitions.  fsck can suck RAM.
		swaponagain 'lvm and md'
		if [ -f /forcefsck ] || grep -s -w -i "forcefsck" /proc/cmdline
		then
			force="-f"
		else
			force=""
		fi
		if [ "$FSCKFIX" = yes ]
		then
			fix="-y"
		else
			fix="-a"
		fi
		spinner="-C"
		case "$TERM" in
		  dumb|network|unknown|"")
			spinner=""
			;;
		esac
		[ "$(uname -m)" = s390x ] && spinner=""  # This should go away
		FSCKTYPES_OPT=""
		[ "$FSCKTYPES" ] && FSCKTYPES_OPT="-t $FSCKTYPES"
		handle_failed_fsck() {
			log_failure_msg "File system check failed. 
A log is being saved in ${FSCK_LOGFILE} if that location is writable. 
Please repair the file system manually."
			log_warning_msg "A maintenance shell will now be started. 
CONTROL-D will terminate this shell and resume system boot."
			# Start a single user shell on the console
			if ! sulogin $CONSOLE
			then
				log_failure_msg "Attempt to start maintenance shell failed. 
Continuing with system boot in 5 seconds."
				sleep 5
			fi
		}
		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 [ "$FSCKCODE" -eq 32 ]
			then
				log_action_end_msg 1 "code $FSCKCODE"
				log_warning_msg "File system check was interrupted by user"
			elif [ "$FSCKCODE" -gt 1 ]
			then
				log_action_end_msg 1 "code $FSCKCODE"
				handle_failed_fsck
			else
				log_action_end_msg 0
			fi
		else
			if [ "$FSCKTYPES" ]
			then
				log_action_msg "Will now check all file systems of types $FSCKTYPES"
			else
				log_action_msg "Will now check all file systems"
			fi
			logsave -s $FSCK_LOGFILE fsck $spinner -V -R -A $fix $force $FSCKTYPES_OPT
			FSCKCODE=$?
			if [ "$FSCKCODE" -eq 32 ]
			then
				log_warning_msg "File system check was interrupted by user"
			elif [ "$FSCKCODE" -gt 1 ]
			then
				handle_failed_fsck
			else
				log_success_msg "Done checking file systems. 
A log is being saved in ${FSCK_LOGFILE} if that location is writable."
			fi
		fi
	fi
	rm -f /fastboot /forcefsck 2>/dev/null
}
case "$1" in
  start|"")
	do_start
	;;
  restart|reload|force-reload)
	echo "Error: argument '$1' not supported" >&2
	exit 3
	;;
  stop)
	# No-op
	;;
  *)
	echo "Usage: checkfs.sh [start|stop]" >&2
	exit 3
	;;
esac
:

/etc/init.d/checkroot.sh changed:
PATH=/sbin:/bin:/usr/bin
FSCK_LOGFILE=/var/log/fsck/checkroot
[ "$FSCKFIX" ] || FSCKFIX=no
[ "$SULOGIN" ] || SULOGIN=no
.. /lib/init/vars.sh
.. /lib/lsb/init-functions
.. /lib/init/mount-functions.sh
do_start () {
	# Trap SIGINT so that we can handle user interrupt of fsck.
	trap "" INT
	#
	# Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to
	# be spawned from this script *before anything else* with a timeout,
	# like sysv does.
	#
	[ "$SULOGIN" = yes ] && sulogin -t 30 $CONSOLE
	KERNEL="$(uname -s)"
	MACHINE="$(uname -m)"
	read_fstab
	#
	# Activate the swap device(s) in /etc/fstab. This needs to be done
	# before fsck, since fsck can be quite memory-hungry.
	#
	ENABLE_SWAP=no
	case "$KERNEL" in
	  Linux)
	  	if [ "$NOSWAP" = yes ]
		then
			[ "$VERBOSE" = no ] || log_warning_msg "Not activating swap as requested via bootoption noswap."
			ENABLE_SWAP=no
		else
			if [ "$swap_on_lv" = yes ]
			then
				[ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on logical volume."
			elif [ "$swap_on_file" = yes ]
			then
				[ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on swapfile."
			else
				ENABLE_SWAP=yes
			fi
		fi
		;;
	  *)
		ENABLE_SWAP=yes
		;;
	esac
	if [ "$ENABLE_SWAP" = yes ]
	then
		if [ "$VERBOSE" = no ]
		then
			log_action_begin_msg "Activating swap"
			swapon -a -e >/dev/null 2>&1
			log_action_end_msg $?
		else
			log_daemon_msg "Activating swap"
			swapon -a -v
			log_end_msg $?
		fi
	fi
	#
	# Does the root device in /etc/fstab match with the actual device ?
	# If not we try to use the /dev/root alias device, and if that
	# fails we create a temporary node in /run.
	#
	if [ "$rootcheck" = yes ]
	then
		ddev="$(mountpoint -qx $rootdev)"
		rdev="$(mountpoint -d /)"
		if [ "$ddev" != "$rdev" ] && [ "$ddev" != "4:0" ]
		then
			if [ "$(mountpoint -qx /dev/root)" = "4:0" ]
			then
				rootdev=/dev/root
			else
				if \
					rm -f /run/rootdev \
					&& mknod -m 600 /run/rootdev b ${rdev%:*} ${rdev#*:} \
					&& [ -e /run/rootdev ]
				then
					rootdev=/run/rootdev
				else
					rootfatal=yes
				fi
			fi
		fi
	fi
	#
	# Bother, said Pooh.
	#
	if [ "$rootfatal" = yes ]
	then
		log_failure_msg "The device node $rootdev for the root filesystem is missing or incorrect 
or there is no entry for the root filesystem listed in /etc/fstab. 
The system is also unable to create a temporary node in /run. 
This means you have to fix the problem manually."
		log_warning_msg "A maintenance shell will now be started. 
CONTROL-D will terminate this shell and restart the system."
		# Start a single user shell on the console
		if ! sulogin $CONSOLE
		then
			log_failure_msg "Attempt to start maintenance shell failed. 
Will restart in 5 seconds."
			sleep 5
		fi
		[ "$VERBOSE" = no ] || log_action_msg "Will now restart"
		reboot -f
	fi
	# See if we're on AC Power.  If not, we're not gonna run our
	# check.  If on_ac_power (in /usr/) is unavailable, behave as
	# before and check all file systems needing it.
	#
	# See if we want to check the root file system.
	#
	FSCKCODE=0
	if [ -f /fastboot ] || grep -s -i " fastboot" /proc/cmdline
	then
		[ "$rootcheck" = yes ] && log_warning_msg "Fast boot enabled, so skipping root file system check."
		rootcheck=no
	fi
	if which findmnt >/dev/null 2>&1
	then
		if [ "$(findmnt -f -n -o FSTYPE /)" = "btrfs" ]
		then
			[ "$rootcheck" = yes ] && log_warning_msg "btrfs root detected, so skipping root file system check."
			rootcheck=no
		fi
	fi
	if [ "$rootcheck" = yes ]
	then
		#
		# Ensure that root is quiescent and read-only before fsck'ing.
		#
		# mount -n -o remount,ro / would be the correct syntax but
		# mount can get confused when there is a "bind" mount defined
		# in fstab that bind-mounts "/" somewhere else.
		#
		# So we use mount -n -o remount,ro $rootdev / but that can
		# fail on older kernels on sparc64/alpha architectures due
		# to a bug in sys_mount().
		#
		# As a compromise we try both.
		#
		if \
			! mount    -n -o remount,ro              $rootdev /              \
			&& ! mount -n -o remount,ro -t dummytype $rootdev /  2>/dev/null \
			&& ! mount -n -o remount,ro                       /  2>/dev/null
		then
			log_failure_msg "Cannot check root file system because it is not mounted read-only."
			rootcheck=no
		fi
	fi
	#
	# The actual checking is done here.
	#
	if [ "$rootcheck" = yes ]
	then
		if [ -f /forcefsck ] || grep -s -w -i "forcefsck" /proc/cmdline
		then
			force="-f"
		else
			force=""
		fi
		if [ "$FSCKFIX" = yes ]
		then
			fix="-y"
		else
			fix="-a"
		fi
		spinner="-C"
		case "$TERM" in
		  dumb|network|unknown|"")
			spinner="" ;;
		esac
		# This Linux/s390x special case should go away.
		if [ "${KERNEL}:${MACHINE}" = Linux:s390x ]
		then
			spinner=""
		fi
		
		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 [ "$FSCKCODE" = 0 ]
			then
				log_action_end_msg 0
			else
				log_action_end_msg 1 "code $FSCKCODE"
			fi
		else
			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
		fi
	fi
	#
	# If there was a failure, drop into single-user mode.
	#
	# NOTE: "failure" is defined as exiting with a return code of
	# 4 or larger. A return code of 1 indicates that file system
	# errors were corrected but that the boot may proceed. A return
	# code of 2 or 3 indicates that the system should immediately reboot.
	#
	if [ "$FSCKCODE" -eq 32 ]
	then
		log_warning_msg "File system check was interrupted by user"
	elif [ "$FSCKCODE" -gt 3 ]
	then
		# Surprise! Re-directing from a HERE document (as in "cat << EOF")
		# does not work because the root is currently read-only.
		log_failure_msg "An automatic file system check (fsck) of the root filesystem failed. 
A manual fsck must be performed, then the system restarted. 
The fsck should be performed in maintenance mode with the 
root filesystem mounted in read-only mode."
		log_warning_msg "The root filesystem is currently mounted in read-only mode. 
A maintenance shell will now be started. 
After performing system maintenance, press CONTROL-D 
to terminate the maintenance shell and restart the system."
		# Start a single user shell on the console
		if ! sulogin $CONSOLE
		then
			log_failure_msg "Attempt to start maintenance shell failed. 
Will restart in 5 seconds."
			sleep 5
		fi
		[ "$VERBOSE" = no ] || log_action_msg "Will now restart"
		reboot -f
	elif [ "$FSCKCODE" -gt 1 ]
	then
		log_failure_msg "The file system check corrected errors on the root partition 
but requested that the system be restarted."
		log_warning_msg "The system will be restarted in 5 seconds."
		sleep 5
		[ "$VERBOSE" = no ] || log_action_msg "Will now restart"
		reboot -f
	fi
	#
	# Remount root to final mode (rw or ro).
	#
	# See the comments above at the previous "mount -o remount"
	# for an explanation why we try this twice.
	#
	if ! mount -n -o remount,$rootopts,$rootmode $fstabroot / 2>/dev/null
	then
		mount -n -o remount,$rootopts,$rootmode /
	fi
	# If possible, migrate /etc/mtab to be a symlink to
	# /proc/mounts.  Note that not all systems e.g. Hurd currently
	# support this.
	if [ "$rootmode" != "ro" ]; then
		mtab_migrate
	fi
	if selinux_enabled && [ -x /sbin/restorecon ] && [ -r /etc/mtab ]
	then
		restorecon /etc/mtab
	fi
	#
	# Remove /run/rootdev if we created it.
	#
	rm -f /run/rootdev
	# Update mount options for mounts created in early boot
	# S01mountkernfs.sh
	/etc/init.d/mountkernfs.sh reload
	# S03mountdevsubfs.sh
	/etc/init.d/mountdevsubfs.sh reload
}
do_status () {
	# If / is read-write or swap is enabled, this script have done
	# its job.
	rootrw=false
	swapon=false
	if [ -f /etc/mtab ] ; then
	    if grep " / " /etc/mtab |grep -q rw ; then
		rootrw=true
	    fi
	fi
	if [ -f /proc/swaps ] ; then
	    if [ "$(cat /proc/swaps |grep -v ^Filename)" ] ; then
		swapon=true
	    fi
	fi
	if [ true = "$rootrw" ] || [ true = "$swapon" ] ; then
		return 0
	else
		return 4
	fi
}
case "$1" in
  start|"")
	do_start
	;;
  restart|reload|force-reload)
	echo "Error: argument '$1' not supported" >&2
	exit 3
	;;
  stop)
	# No-op
	;;
  status)
	do_status
	exit $?
	;;
  *)
	echo "Usage: checkroot.sh [start|stop]" >&2
	exit 3
	;;
esac
:


-- no debconf information



More information about the Pkg-sysvinit-devel mailing list