[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#652459: initramfs-tools: [patch] Please support mounting of /usr in the initramfs



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 rleigh@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 rleigh@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 rleigh@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 <rleigh@debian.org>  Sat, 11 May 2013 19:35:04 +0100
 
-- 
1.7.10.4


Reply to: