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: