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



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to