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

Bug#501969: details and possible patch



On Sat, 25 Oct 2008, Kieran Maclean wrote:

> 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.

full ack
first workaround is documented in release notes,
maybe second should also be.

> 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.

in principle good idea, but don't know if it worth.
squeeze might not release with lilo?


> 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
>  }

well,
instead of exporting it might be a good idea.
in this case to create an udev rule that 
creates a device symlink to the real.

echo "SUBSYSTEM==\"block\", SYSFS{dev}==\"$maj:$min\", SYMLINK+=\"root\"" > /etc/udev/rules.d/05-lilo.rules

even trough it would be the first *real* hardcoding of
the udev dep..

> 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

no you can't assume to have awk, ls and printf at your disposition.
people use initramfs without BUSYBOX

>  			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

thanks for tackling that issue
and sorry for late reply.

-- 
maks



Reply to: