[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