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

Bug#848906: /init: missing critical mount failure detection



Package: initramfs-tools-core
Version: 0.126
Severity: normal
Tags: patch

I experienced a failure to boot because root was set to an empty value
(which seems a rather common problem caused by grub).  However the /init
passed the mounting step without stopping (and without complaining too
much).

The next failure detection is $init inexistence in /root and it is this
one that is triggered to stop the /init and start a shell.  (In passing
please note that this detection sets $init to an empty value which is
very inconvenient since it prevents the possibility to fix the problem
in the panic shell before resuming the /init, which in my case was not
possible anyways due to missing executables in the initramfs; I suggest
not to set $init to an empty value, so that the original $init value is
available for inspection in the panic shell.)

The error actually triggered is very misleading because /init does not
detect the failure of its main purpose: mounting /root.

I join a patch to make basic checks after mounting both /root and /root/usr.
It optionally calls mountpoint that could be available (for example in
recent versions of busybox).

It also adds a check that $ROOT is not empty (which could additionaly
test for other obviously invalid values), placed right before the code
that possibly decides to skip the part that makes the root device appear
in /dev.  This is because an empty $ROOT is a frequent problem and
because the test to detect non /dev devices (like UBI) is too broad.
--- /usr/share/initramfs-tools/scripts/local	2016-04-17 21:39:22.000000000 +0200
+++ /usr/share/initramfs-tools/scripts/local.new	2016-12-18 17:05:13.419988203 +0100
@@ -55,10 +55,15 @@
 		modprobe ubi mtd=$UBIMTD
 		DEV="${dev_id}"
 		return
 	fi
 
+	# Detect (some) invalid device names
+	if [ -z "${dev_id}" ]; then
+		panic "Empty root device name deteted. Try passing root= bootarg."
+	fi
+
 	# Don't wait for a device that doesn't have a corresponding
 	# device in /dev and isn't resolvable by blkid (e.g. mtd0)
 	if [ "${dev_id#/dev}" = "${dev_id}" ] &&
 	   [ "${dev_id#*=}" = "${dev_id}" ]; then
 		DEV="${dev_id}"
@@ -136,17 +141,20 @@
 	# FIXME This has no error checking
 	modprobe ${FSTYPE}
 
 	checkfs ${ROOT} root "${FSTYPE}"
 
-	# FIXME This has no error checking
 	# Mount root
 	if [ "${FSTYPE}" != "unknown" ]; then
 		mount ${roflag} -t ${FSTYPE} ${ROOTFLAGS} ${ROOT} ${rootmnt}
 	else
 		mount ${roflag} ${ROOTFLAGS} ${ROOT} ${rootmnt}
 	fi
+	# Basic error checking
+	if [ $? != 0 ] || { command -v mountpoint >/dev/null 2>&1 && ! mountpoint ${rootmnt}; }; then
+		panic "ALERT! The root fs failed to be mounted. Dropping to a shell."
+	fi
 }
 
 local_mount_fs()
 {
 	read_fstab_entry "$1"
@@ -167,13 +175,16 @@
 
 	if [ "$MNT_PASS" != 0 ]; then
 		checkfs "$MNT_FSNAME" "$MNT_DIR" "${MNT_TYPE}"
 	fi
 
-	# FIXME This has no error checking
 	# Mount filesystem
 	mount ${roflag} -t "${MNT_TYPE}" -o "${MNT_OPTS}" "$MNT_FSNAME" "${rootmnt}${MNT_DIR}"
+	# Basic error checking
+	if [ $? != 0 ] || { command -v mountpoint >/dev/null 2>&1 && ! mountpoint ${rootmnt}; }; then
+		panic "ALERT! The '${MNT_DIR}' fs failed to be mounted. Dropping to a shell."
+	fi
 }
 
 mountroot()
 {
 	local_mount_root

Reply to: