On Sun, May 12, 2013 at 12:31:38AM +0100, Roger Leigh wrote: > On Sat, May 11, 2013 at 08:02:36PM +0100, Roger Leigh wrote: > > With all the patches applied, /usr will be automatically mounted if > > it is present in the /etc/fstab on the rootfs. This works for both > > local and nfs. I've not tested LVM, but standard UUIDs work fine. > > You can also mount /etc so that this can be independently mounted; > > obviously this can't use the fstab, so it's done using an equivalent > > set of command-line options as for the rootfs. This is a separate > > patch so it can be easily dropped. > > Additional patch attached to canonicalise mount device names. This > isn't just cosmetic--mount requires the device names to match when > we try to mount all filesystems in fstab during boot (which we already > fixed up for the tmpfs mounts). This does it for all local device > paths.
Additional patches to run fsck in the initramfs prior to mounting filesystems. It's not possible to do this during normal startup in checkroot due to e2fsck special casing fsck of mounted, read-only root, but not any other mounted fs such as /usr. -- .''`. Roger Leigh : :' : Debian GNU/Linux http://people.debian.org/~rleigh/ `. `' Printing on GNU/Linux? http://gutenprint.sourceforge.net/ `- GPG Public Key: 0x25BFB848 Please GPG sign your mail.
>From d54671242be20223a914aab293bb36066a132ba8 Mon Sep 17 00:00:00 2001 From: Roger Leigh <Roger Leigh rle...@debian.org> Date: Sun, 12 May 2013 17:05:51 +0100 Subject: [PATCH 14/16] debian: Document device name canonicalisation --- debian/changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/debian/changelog b/debian/changelog index df01f9d..44c79f6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -25,6 +25,10 @@ initramfs-tools (0.112+usrmount1) UNRELEASED; urgency=low - The local and nfs bottom scripts are run on demand if used; this does not interfere with alternative boot scripts being used, which will run first + - Canonicalise device names to match util-linux mount behaviour; + this ensures that "mount -a" in mountall does not try to mount + /usr a second time (which it will attempt if the mounted device + does not match the canonical device name). * Mount /usr if present in the /etc/fstab on the mounted rootfs (Closes: #652459) * Mount /etc if specified on the kernel command-line -- 1.7.10.4
>From d65980e6c39632a8f702976a429ab0e18c3ef872 Mon Sep 17 00:00:00 2001 From: Roger Leigh <Roger Leigh rle...@debian.org> Date: Sun, 12 May 2013 17:05:09 +0100 Subject: [PATCH 15/16] Add support for running fsck - Add empty /etc/fstab and symlink /etc/mtab to /proc/mounts; not essential, but quell a number of fsck warnings - Copy fsck and needed fsck helpers, plus logsave - Add checkfs function, based on the initscripts checkroot script - local mount functions will call checkfs prior to mounting the filesystem --- hooks/fsck | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ init | 15 +++++++++ mkinitramfs | 4 +++ scripts/functions | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ scripts/local | 6 ++++ 5 files changed, 214 insertions(+) create mode 100755 hooks/fsck diff --git a/hooks/fsck b/hooks/fsck new file mode 100755 index 0000000..cd91fa9 --- /dev/null +++ b/hooks/fsck @@ -0,0 +1,92 @@ +#!/bin/sh + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +fstab_files() +{ + echo /etc/fstab + if [ -d /etc/fstab.d ]; then + ls -1 /etc/fstab.d | grep '\.fstab$' | sed -e 's;^;/etc/fstab.d/;' + fi +} + +# Find a specific fstab entry +# $1=mountpoint +# $2=fstype (optional) +_read_fstab_entry () { + # Not found by default. + echo "MNT_FSNAME=" + echo "MNT_DIR=" + echo "MNT_TYPE=" + + fstab_files | while read file; do + if [ -f "$file" ]; then + while read MNT_FSNAME MNT_DIR MNT_TYPE MNT_OPTS MNT_FREQ MNT_PASS MNT_JUNK; do + case "$MNT_FSNAME" in + ""|\#*) + continue; + ;; + esac + if [ "$MNT_DIR" = "$1" ]; then + if [ -n "$2" ]; then + [ "$MNT_TYPE" = "$2" ] || continue; + fi + echo "MNT_FSNAME=$MNT_FSNAME" + echo "MNT_DIR=$MNT_DIR" + echo "MNT_TYPE=$MNT_TYPE" + break 2 + fi + MNT_DIR="" + done < "$file" + fi + done +} + +# Find a specific fstab entry and print its type (if found) +# $1=mountpoint +get_fstype () { + eval "$(_read_fstab_entry "$1")" + + # Not found by default. + if [ "$1" = "$MNT_DIR" ]; then + echo "$MNT_TYPE" + fi +} + +get_fstypes() { + get_fstype / + get_fstype /etc + get_fstype /usr +} + +case $1 in +prereqs) + prereqs + exit 0 + ;; +esac + +if [ ! -x /sbin/fsck ]; then + exit 0 +fi + +. /usr/share/initramfs-tools/hook-functions + + +copy_exec /sbin/fsck +copy_exec /sbin/logsave +for type in $(get_fstypes | sort | uniq); do + prog="/sbin/fsck.${type}" + if [ -h "$prog" ]; then + link=$(readlink -f "$prog") + copy_exec "$link" + ln -s "$link" "${DESTDIR}/$prog" + else + copy_exec "$link" + fi +done diff --git a/init b/init index 8057f79..9ee8d52 100755 --- a/init +++ b/init @@ -58,6 +58,9 @@ export panic= export blacklist= export resume= export resume_offset= +export fastboot=n +export forcefsck=n +export fsckfix=n # Bring in the main config . /conf/initramfs.conf @@ -178,6 +181,15 @@ for x in $(cat /proc/cmdline); do BOOTIF=*) BOOTIF=${x#BOOTIF=} ;; + fastboot) + fastboot=y + ;; + forcefsck) + forcefsck=y + ;; + fsckfix) + fsckfix=y + ;; esac done @@ -336,6 +348,9 @@ unset quiet unset readonly unset resume unset resume_offset +unset fastboot +unset forcefsck +unset fsckfix # Move virtual filesystems over to the real filesystem mount -n -o move /sys ${rootmnt}/sys diff --git a/mkinitramfs b/mkinitramfs index d9a54e2..66111a7 100755 --- a/mkinitramfs +++ b/mkinitramfs @@ -274,6 +274,10 @@ if ! command -v ldd >/dev/null 2>&1 ; then exit 1 fi +# fstab and mtab +touch "${DESTDIR}/etc/fstab" +ln -s /proc/mounts "${DESTDIR}/etc/mtab" + # module-init-tools copy_exec /sbin/modprobe /sbin copy_exec /sbin/rmmod /sbin diff --git a/scripts/functions b/scripts/functions index eeec778..dea9e89 100644 --- a/scripts/functions +++ b/scripts/functions @@ -497,6 +497,103 @@ resolve_device() { echo "$DEV" } +# Check a file system. +# $1=device +# $2=mountpoint (for diagnostics only) +checkfs() +{ + DEV="$1" + NAME="$2" + if [ "$NAME" = "/" ] ; then + NAME="root" + fi + FSCK_LOGFILE=/run/initramfs/fsck + + TYPE=$(get_fstype "$1") + + FSCKCODE=0 + if [ "$fastboot" = "y" ] ; then + log_warning_msg "Fast boot enabled, so skipping $NAME file system check." + return + fi + + if [ "$forcefsck" = "y" ] + then + force="-f" + else + force="" + fi + + if [ "$fsckfix" = yes ] + then + fix="-y" + else + fix="-a" + fi + + # spinner="-C" -- only if on an interactive terminal + spinner="" + + if [ "$VERBOSE" = no ] + then + log_begin_msg "Will now check $NAME file system" + logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t $TYPE $DEV + FSCKCODE=$? + log_end_msg + else + log_begin_msg "Checking $NAME file system" + logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -t $TYPE $DEV + FSCKCODE=$? + log_end_msg + fi + + # + # If there was a failure, drop into a shell. + # + # 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 fs is currently read-only. + log_failure_msg "An automatic file system check (fsck) of the $NAME filesystem failed. +A manual fsck must be performed, then the system restarted. +The fsck should be performed in maintenance mode with the +$NAME filesystem mounted in read-only mode." + log_warning_msg "The $NAME 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 + if [ "${verbose}" = "y" ] ; then + log_begin_msg "Will now restart" + fi + reboot + elif [ "$FSCKCODE" -gt 1 ] + then + log_failure_msg "The file system check corrected errors on the $NAME partition +but requested that the system be restarted." + log_warning_msg "The system will be restarted in 5 seconds." + sleep 5 + if [ "${verbose}" = "y" ] ; then + log_begin_msg "Will now restart" + fi + reboot + fi +} + # Mount a file system. We parse the information from the fstab. This # should be overridden by any boot script which can mount arbitrary # filesystems such as /usr. This default implementation delegates to diff --git a/scripts/local b/scripts/local index 55464a2..1b365ed 100644 --- a/scripts/local +++ b/scripts/local @@ -131,6 +131,8 @@ local_mount_root() # FIXME This has no error checking modprobe ${FSTYPE} + checkfs ${ROOT} root + # FIXME This has no error checking # Mount root if [ "${FSTYPE}" != "unknown" ]; then @@ -164,6 +166,8 @@ local_mount_etc() # FIXME This has no error checking modprobe ${FSTYPE} + checkfs ${ETC} /etc + # FIXME This has no error checking # Mount etc if [ "${FSTYPE}" != "unknown" ]; then @@ -193,6 +197,8 @@ local_mount_fs() # FIXME This has no error checking modprobe "${MNT_TYPE}" + checkfs "$MNT_FSNAME" "$MNT_DIR" + # FIXME This has no error checking # Mount filesystem mount ${roflag} -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}" -- 1.7.10.4
>From 68e0ada070d2f403e9979056e077b3d951254afa Mon Sep 17 00:00:00 2001 From: Roger Leigh <Roger Leigh rle...@debian.org> Date: Sun, 12 May 2013 18:20:23 +0100 Subject: [PATCH 16/16] debian: Document fsck and close #708000 --- debian/changelog | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 44c79f6..2585428 100644 --- a/debian/changelog +++ b/debian/changelog @@ -28,10 +28,18 @@ initramfs-tools (0.112+usrmount1) UNRELEASED; urgency=low - Canonicalise device names to match util-linux mount behaviour; this ensures that "mount -a" in mountall does not try to mount /usr a second time (which it will attempt if the mounted device - does not match the canonical device name). + does not match the canonical device name) * Mount /usr if present in the /etc/fstab on the mounted rootfs (Closes: #652459) * Mount /etc if specified on the kernel command-line + * Check filesystems prior to mounting (Closes: #708000): + - Add empty /etc/fstab and symlink /etc/mtab to /proc/mounts; + not essential, but quell a number of fsck warnings + - Copy fsck and needed fsck helpers, plus logsave + - Add checkfs function, based on the initscripts checkroot + script + - local mount functions will call checkfs prior to mounting + the filesystem -- Roger Leigh <rle...@debian.org> Sat, 11 May 2013 19:35:04 +0100 -- 1.7.10.4