[Bootcd-user] Re: Re: bootcdmkinitrd and scsi (Thomas Krennwallner)

azajac@vif.com azajac@vif.com
Sat, 1 Nov 2003 14:32:19 -0500


Hello.

I got it to work!

I took a look at the initrd's /sbin/init.  Since this is called and has to
finish before the cdrom filesystem (real root) can be mounted, I thought
that it would be interesting.  The last thing that it does is cd to /mnt and
pivot_root.

So I used that.

/cdrom is mounted to the discovered root filesystem (see bootcdmkinitrd
included) and I modified the initrd /sbin/init to mount /cdrom instead of
mounting /mnt.

Now it seems to work as desired...

I could not modify /sbin/init from the bootcdmkinitrd script since I am not that
good a programmer.(not at all)  I did it by hand and called

mkcramfs initrd /initrd.img

PS.  I do not reboot after running boocdmkinitrd since this should leave my
system unbootable (because no /cdrom is mounted when booting from hard disk...) 
I remove the initrd=/... from lilo.conf and then run lilo first!!!!



So here is the /sbin/init from within the initrd:

#!/bin/sh
#
# $Id: init,v 1.35 2003/09/08 12:33:27 herbert Exp $

mount_device() {
        unset flags fstype
        set -f
        set +f $cmdline
        for i; do
                case "$i" in
                rootflags=*)
                        flags=${i#rootflags=}
                        ;;
                rootfstype=*)
                        fstype=${i#rootfstype=}
                        ;;
                esac
        done
        if [ -n "$fstype" ]; then
                mount -nrt "$fstype" ${flags:+-o "$flags"} $device /mnt
                return
        fi
        IFS=,
        set -f
        set +f -- $FSTYPES auto
        unset IFS
        for i; do
                mount -nrt "$i" ${flags:+-o "$flags"} $device /mnt &&
                        break
        done
}

try_name() {
        [ -f /sys/block/$1/dev ] || return 1
        read dev < /sys/block/$1/dev
        case $dev in
        *:*)
                minor=${dev#*:}
                major=${dev%:*}
                ;;
        *)
                minor=$((0x${dev#??}))
                major=$((0x${dev%??}))
                ;;
        esac
        if ! [ $2 ]; then
                return
        fi

        [ -f /sys/block/$1/range ] || return 1
        read range < /sys/block/$1/range
        [ $2 -lt $range ] || return 1
        minor=$(($minor + $2))
}

get_sysfs_device() {
        case $ROOT in
        /dev/*)
                ;;
        *)
                return
                ;;
        esac

        IFS=/
        set -f
        set +f ${ROOT#/dev/}
        IFS=.
        root=$*
        unset IFS
        try_name "$root" && return

        part=${root##*[!0-9]}
        root=${root%$part}
        if [ -z "$root" ]; then
                return
        fi
        try_name "$root" $part && return

        case $root in
        *[0-9]p)
                ;;
        *)
                return 0
                ;;
        esac
        try_name "${root%p}" $part
        return 0
}

get_device() {
        major=$(($rootdev >> 8))
        minor=$(($rootdev & 255))
        if [ $rootdev -eq 0 ] || [ $major -eq 58 ] || [ $major -eq 254 ]; then
                if [ -b "$ROOT" ]; then
                        device=$ROOT
                        return
                fi
                if mount -nt sysfs sysfs sys > /dev/null 2>&1; then
                        get_sysfs_device
                        umount -n sysfs
                fi
        fi
        mknod dev2/root2 b $major $minor
        device=/dev2/root2
}

mount_root() {
        mount -nt proc proc proc
        mount -nt tmpfs tmpfs dev2
        mount -nt devfs devfs devfs
        get_device
        mount_device
        umount -n devfs
        umount -n dev2
        umount -n proc
}

get_cmdline() {
        init=/sbin/init
        root=
        ide_options=
        for i in $(cat proc/cmdline); do
                case $i in
                init=*)
                        init=${i#init=}
                        ;;
                root=*)
                        root=${i#root=}
                        ;;
                ide*= | hd[!=]*=)
                        ide_options="$ide_options $i"
                        ;;
                esac
        done
        case $root in
        /dev/*)
                ROOT=$root
                ;;
        esac
}

call() {
        . "$@"
}

export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

. /linuxrc.conf

echo "initrd-tools: $VERSION"

read root < tmp/root
umount -n tmp
mount -nt proc proc proc
echo $root > proc/sys/kernel/real-root-dev

get_cmdline

[ -c /dev/.devfsd ] && DEVFS=yes

mount -nt devfs devfs devfs
if [ -n "$ide_options" ]; then
        echo modprobe -k ide-mod "options=\"$ide_options\""
        modprobe -k ide-mod options="$ide_options"
fi
call /loadmodules

if [ $DELAY -gt 0 ]; then
        echo "Waiting for $DELAY seconds, press ENTER to obtain a shell."

        trap "timeout=yes" USR1
        timeout=
        { sleep $DELAY; kill -USR1 $$ 2> /dev/null; }&
        pid=$!
        read line
        trap "" USR1
        kill $pid
        wait

        [ $timeout ] || exec sh
fi

call /script
umount -n devfs

umount -n proc

for i in /scripts/*; do
        [ -f "$i" ] || continue
        case "$i" in
        *.sh)
                (. $i)
                ;;
        *)
                $i
                ;;
        esac
done

cd /
mount -nt proc proc proc
rootdev=$(cat proc/sys/kernel/real-root-dev)
cmdline=$(cat /proc/cmdline)
umount -n proc
if [ $rootdev != 256 ]; then
        mount_root
#################  HERE ARE THE MODIFICATIONS!
        cd /cdrom
        [ $DEVFS ] && mount -nt devfs devfs dev
        pivot_root . initrd
fi
if ! [ -x ${init#/} ]; then
        init=/sbin/init
fi
if type chroot > /dev/null 2>&1; then
        exec chroot . $init "$@" < dev/console > dev/console 2>&1
fi
exec $init "$@" < dev/console > dev/console 2>&1






and here is bootcdmkinitrd:






#!/bin/sh
# /usr/sbin/bootcdmkinitrd

set -u

KERN=$(uname -r)
INITRD=/boot/initrd.img-$KERN
ETCMKI=/etc/mkinitrd
devices=""
s=""

# Warning

echo "Warning: this script assumes the following:"
echo "- the running kernel is the one that will be used on bootcd"
echo "- initrd is used"
echo "- lilo is used"
echo "Warning: this script will do the following:"
echo "- /etc/mkinitrd/ will be changed."
echo "- mkinitrd will be called. This will change $INITRD."
echo "- lilo will be called."
while :; do
  echo -n "OK to continue ? (y|n)"
  read A
  [ "$A" = "n" ] && exit
  [ "$A" = "y" ] && break
done

# Checks

if [ ! "$(grep "^[[:blank:]]*initrd=" /etc/lilo.conf)" ]; then
  echo "/etc/lilo.conf has no line initrd=. This means that you" >&2
  echo "are not using lilo, or that you are not using initrd." >&2
  echo "This skript only works with lilo and initrd." >&2
  exit 1
fi

if [ ! "$(grep "^[[:blank:]]*initrd=/initrd.img[[:blank:]]*$" /etc/lilo.conf)"
]; then
  echo "Your /etc/lilo.conf has no line with initrd=/initrd.img. Because" >&2
  echo "this script can only support standard configurations, please edit" >&2
  echo "lilo.conf run lilo and reboot to test your configuration. Then " >&2
  echo "run this script again." >&2
  exit 1
fi

if [ ! "$(/bin/ls -l /initrd.img | grep -e "-> $INITRD$")" ]; then
  echo "/initrd.img must be a link to $INITRD." >&2
  exit 1
fi

if [ ! -d $ETCMKI ]; then
  echo "ERROR: No mkinitrd config dir $ETCMKI." >&2
  echo "       Is initrd-tools.deb installed ?" >&2
fi

if [ ! -f $INITRD ]; then
  echo "$INITRD does not exist." >&2
  exit 1
fi



# Start

[ -f /etc/mkinitrd.tgz ] && mv /etc/mkinitrd.tgz /etc/mkinitrd.tgz.old
(cd /etc; tar czf mkinitrd.tgz mkinitrd)

F=/etc/mkinitrd/exe
touch $F
cp $F $F.tmp
cat $F.tmp | grep -v "^/sbin/discover\>" >$F
echo "/sbin/discover" >>$F
rm $F.tmp

F=/etc/mkinitrd/modules
touch $F
cp $F $F.tmp
cat $F.tmp | grep -v "^isofs\>" >$F
echo "isofs" >>$F
rm $F.tmp

F=/etc/mkinitrd/files
touch $F
cp $F $F.tmp
cat $F.tmp | grep -v "^/usr/share/discover/.*\.lst\>" >$F
ls /usr/share/discover/*.lst >>$F
ls /dev/scd* >>$F
rm $F.tmp

F1=/etc/mkinitrd/scripts/50bootcddiscover
cat <<end1 >$F1
#!/bin/sh
F2=\$INITRDDIR/scripts/bootcd
mkdir \$INITRDDIR/cdrom
cat <<end2 >\$F2
/bin/echo "running /scripts/bootcd" >&2
mount -nt proc proc /proc
MODULES=\\\$(discover --disable-all --enable=pci --module scsi)
for M in \\\$MODULES; do
  modprobe \\\$M
done
devices=\\\$(discover --device cdrom)
for s in \\\$devices
    do
    mount -n \\\$s /cdrom
    if test -f /cdrom/bootmount/version
    then echo found root at \\\$s
#  Leave /cdrom mounted and leave...
         umount -n /proc
         exit
    fi
    umount -n /cdrom
    done
umount -n /proc
end2
chmod 755 \$F2
end1
chmod 755 $F1

mkinitrd -k -o /initrd.img
lilo

# Warning

echo "Please reboot now, before using bootcdwrite"