[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"