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

Bug#501969: details and possible patch



The issue is present on machines such as this using lilo as the bootloader.

It can also be reproduced on the same hardware by installing the etch.5
kernel onto a clean etch install.

The issue seems to be that the initramfs init script is passed the
device number for the disk by lilo as the root= argument and creates a
node in /dev (/dev/root) based on this.

It then proceeds to attempt to mount this device as /root.
Since the kernel has not yet finished detecting all devices this fails.
The kernel then finishes detecting all devices and detects the root device.

When using a clean install of lenny on the machine, the machine
successfully boots, since the race condition is avoided by the default
lilo.conf containing the argument
	append="rootdelay=10"
which delays the attempt to mount the root device.

A more preferable work around is to specify in the lilo config
	append="root=/dev/sda1"
which overrides the lilo supplied root= argument, and causes a different
path to be followed though the init script, this path detects that the
/dev/sda1 device has not yet been created by udev and waits for that to
happen, before then successfully mounting the root device and continuing
to boot.

Since this behaviour is explicitly more stable as it removes the race
condition by waiting for the device to be created, I have created a
patch to the init scripts provided by initramfs-tools which emulates the
above behaviour but supporting the lilo root=<device_number> argument type.

The patch waits for a device to be created which matches the device
number passed in by lilo when the device is created, it sets the root
device to the device it has detected to allow that to be mounted.
Further should the device not be created within the specified delay it
will create the device and allow the mount to be attempted on that.

diff -u -r ifst/usr/share/initramfs-tools/init changed/usr/share/initramfs-tools/init
--- ifst/usr/share/initramfs-tools/init	2008-08-13 14:23:44.000000000 +0100
+++ changed/usr/share/initramfs-tools/init	2008-10-25 20:47:49.000000000 +0100
@@ -169,6 +169,8 @@
 maybe_break mount
 log_begin_msg "Mounting root file system"
 . /scripts/${BOOT}
+export dev_major= 
+export dev_minor= 
 parse_numeric ${ROOT}
 maybe_break mountroot
 mountroot
diff -u -r ifst/usr/share/initramfs-tools/scripts/functions changed/usr/share/initramfs-tools/scripts/functions
--- ifst/usr/share/initramfs-tools/scripts/functions	2008-09-02 09:10:56.000000000 +0100
+++ changed/usr/share/initramfs-tools/scripts/functions	2008-10-25 20:47:49.000000000 +0100
@@ -251,8 +251,9 @@
 		return
 		;;
 	esac
-
-	mknod -m 600 /dev/root b ${major} ${minor}
+	dev_major=${major}
+	dev_minor=${minor} 
+	#mknod -m 600 /dev/root b ${major} ${minor}
 	ROOT=/dev/root
 }
 
diff -u -r ifst/usr/share/initramfs-tools/scripts/local changed/usr/share/initramfs-tools/scripts/local
--- ifst/usr/share/initramfs-tools/scripts/local	2008-08-13 14:23:44.000000000 +0100
+++ changed/usr/share/initramfs-tools/scripts/local	2008-10-25 20:47:49.000000000 +0100
@@ -52,10 +52,19 @@
 		while [ ! -e "${ROOT}" ] \
 		|| ! $(get_fstype "${ROOT}" >/dev/null); do
 			/bin/sleep 0.1
+			if [ "${ROOT}" = "/dev/root" ]; then
+				export dev_major
+				export dev_minor
+				for d in /dev/*; do
+					dev_inf=$(ls -Ll $d | awk '{if ($5 < 64) printf("%d:%d\n", $5,$6); else printf("%d:%d\n", $5,$6)}')
+					if [ "${dev_inf}" = "${dev_major}:${dev_minor}" ]; then
+						ROOT=$d
+					fi
+				done
+			fi
 			slumber=$(( ${slumber} - 1 ))
 			[ ${slumber} -gt 0 ] || break
 		done
-
 		if [ ${slumber} -gt 0 ]; then
 			log_end_msg 0
 		else
@@ -66,6 +75,12 @@
 		fi
 	fi
 
+	if [ "${ROOT}" = "/dev/root" ]; then
+		log_begin_msg "failed to detect udev generated root, creating"
+		mknod -m 600 /dev/root b ${dev_major} ${dev_minor} 
+		log_end_msg 0
+	fi
+
 	# We've given up, but we'll let the user fix matters if they can
 	while [ ! -e "${ROOT}" ]; do
 		# give hint about renamed root

Reply to: