#! /bin/sh

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

mount -tproc proc /proc
mount -tsysfs sysfs /sys > /dev/null 2>&1
mount -ttmpfs tmpfs /dev/shm

for o in $(cat /proc/cmdline); do
    case $o in
    initrd=trace)
	set -x
	;;
    sysrq=yes|sysrq=1)
	echo 1 > /proc/sys/kernel/sysrq
	;;
    esac
done

die() {
    umount /proc
    umount /sys
    umount /dev/shm
    exit $1
}

# Fallback root device number
rootdevn=2304

for o in $(cat /proc/cmdline); do
    case $o in
    root=*)
	set -- $(IFS== ; echo $o)
	rootdev=$2
	rootdev_cmdline=1
	;;
    esac
done
if [ -z "$rootdev" ]; then
    rootdev=/dev/md0
else
    # lilo strips off the /dev/prefix from device names!
    case $rootdev in
	/dev/*)
	    ;;
	[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
	    rootdev=0$rootdev ;;
	[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
	    ;;
	*:*)
	    ;;
	*)
	    rootdev=/dev/$rootdev
	    ;;
    esac
fi

mkdevn () 
{ 
    local major=$1 minor=$2;
    expr '(' $minor % 256 ')' + '(' $major '*' 256 ')' + '(' '(' $minor / 256 ')' '*' 256 '*' 4096 ')'
}

devmajor () 
{ 
    local devn=$1;
    expr '(' $devn / 256 ')' % 4096
}

block_driver () 
{ 
    local devn block major driver;
    case "$1" in 
        /dev/*)
            devn=$(devnumber $1 2> /dev/null)
        ;;
        *:*)
            set -- $(IFS=: ; echo $1);
            devn=$(mkdevn $1 $2)
        ;;
        [0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
            devn=$((0x$1))
        ;;
    esac;
    [ -z "$devn" ] && return 1;
    while read major driver; do
        [ "$major" = Block ] && block=1;
        [ -z "$driver" -o -z "$block" ] && continue;
        if [ $(devmajor $devn) = $major ]; then
            echo $driver;
            return 0;
        fi;
    done </proc/devices;
    return 1
}


echo "Starting udev"
echo "/sbin/udev" > /proc/sys/kernel/hotplug
echo "Creating devices"
UDEVSTART_ON_BOOT=1
export UDEVSTART_ON_BOOT
/sbin/udevstart

# check for SCSI parameters in /proc/cmdline
devflags=0
for p in $(cat /proc/cmdline) ; do
  case $p in
    scsi_mod.*)
	extra_scsi_params="$extra_scsi_params ${p#scsi_mod.}"
	;;
    scsi_reportlun2=1)
	echo "scsi_reportlun2 compat: Use scsi_mod.default_dev_flags=0x20000 instead"
	devflags=$((131072+$devflags))
	;;
    scsi_noreportlun=1)
	echo "scsi_noreportlun compat: Use scsi_mod.default_dev_flags=0x40000 instead"
	devflags=$((262144+$devflags))
	;;
    scsi_sparselun=1)
	echo "scsi_sparselun compat: Use scsi_mod.default_dev_flags=0x40 instead"
	devflags=$((64+$devflags))
	;;
    scsi_largelun=1)
	echo "scsi_largelun compat: Use scsi_mod.default_dev_flags=0x200 instead"
	devflags=$((512+$devflags))
	;;
    llun_blklst=*)
	echo "llun_blklst is not supported any more"
	echo "use scsi_mod.dev_flags=VENDOR:MODEL:0x240[,V:M:0x240[,...]]"
	;;
    max_ghost_devices=*)
	echo "max_ghost_devices is not needed any more"
	;;
    max_sparseluns=*)
	echo "max_sparseluns not supported any more"
	echo "use scsi_mod.max_luns or enable the new REPORT_LUNS scsi"
	echo "scanning methods; try scsi_mod.default_dev_flags=0x20000"
	;;
    max_luns=*|max_report_luns=*|inq_timeout=*|dev_flags=*|default_dev_flags=*)
	echo "scsi_mod compat: Please use prefix: scsi_mod.$p"
	extra_scsi_params="$extra_scsi_params $p"
      ;;
  esac
done
if [ $devflags != 0 ]; then 
    extra_scsi_params="default_dev_flags=$devflags $extra_scsi_params"
fi

echo "Loading kernel/drivers/scsi/scsi_mod.ko $extra_scsi_params"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/scsi_mod.ko $extra_scsi_params

echo "Loading kernel/drivers/scsi/sd_mod.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/sd_mod.ko

echo "Loading kernel/drivers/scsi/3w-xxxx.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/3w-xxxx.ko

echo "Loading kernel/drivers/scsi/aic7xxx/aic79xx.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/aic7xxx/aic79xx.ko

echo "Loading kernel/drivers/scsi/libata.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/libata.ko

echo "Loading kernel/drivers/scsi/sata_sil.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/scsi/sata_sil.ko

echo "Loading kernel/fs/reiserfs/reiserfs.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/fs/reiserfs/reiserfs.ko

echo "Loading kernel/drivers/md/raid1.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/md/raid1.ko

echo "Loading kernel/drivers/md/dm-mod.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/md/dm-mod.ko


echo "Loading kernel/drivers/md/dm-mirror.ko"
insmod /lib/modules/2.6.5-7.151-default/kernel/drivers/md/dm-mirror.ko



echo "done."

echo "** Starting EVMS..."
evms_activate
echo "done."

udev_discover_root() {
	local root
	local i

	echo > /.udevdb.lock
	case "$rootdev" in
	/dev/*)	root=${rootdev#/dev/} ;;
	esac
	if [ -n "$root" ]; then
	    echo -n "Waiting for device /dev/$root to appear: "
	    i=0
	    while [ $i -lt 5 ]; do
		if [ -e /dev/$root ]; then
		    path=$(udevinfo -q path -n $root)
		    if [ $? -eq 0 ]; then
		        echo " ok"
			break
		    else
		        path=
		    fi
		else
		    if [ /dev/.udev.tdb -nt /.udevdb.lock ]; then
			echo > /.udevdb.lock
			i=0
		    fi
		fi
		sleep 1
		i=$(expr $i + 1)
		echo -n "."
	    done
	    if [ -n "$path" ]; then
	        dev=/sys$path/dev
		if [ -f $dev ]; then
		    local major minor devn
		    IFS=":" read major minor < $dev
		    devn=$(mkdevn $major $minor)
		    echo "rootfs: $entry major=$major minor=$minor" \
			 "devn=$devn"
		    echo $devn > /proc/sys/kernel/real-root-dev
		    return 0
		fi
	    fi
	    return 1
	fi
}

if ! udev_discover_root ; then
    echo "not found -- device nodes:"
    cd /dev
    for dev in *; do
	if [ -e "$dev" ]; then
	    echo -n "$dev "
	fi
    done
    echo
    echo "No root device found; exiting to /bin/sh"
    cd /
    /bin/sh
fi

basename() {
	local IFS=/

	set -- $1
	eval echo \${$#}
}

sysfs_set_root_dir() {
	local entry name dir=$1 search=$2

	for entry in $dir/*; do
	  [ -L $entry ] && continue
	  [ -d $entry ] || continue

	  name=$(basename $entry)
	  if [ -f $entry/dev -a $name = $search ]; then
		local major minor devn
		IFS=: read major minor < $entry/dev
		devn=$(mkdevn $major $minor)
		echo "rootfs: $entry major=$major minor=$minor" \
		     "devn=$devn"
		echo $devn > /proc/sys/kernel/real-root-dev
		return 0
	  else
	    sysfs_set_root_dir $entry $search \
		&& return 0
	  fi
	done
	return 1
}

sysfs_set_root() {
	local root=$1

	sysfs_set_root_dir /sys/block $root
}

discover_root() {
	local root
	case $rootdev in
	/dev/*)	root=$(expr substr $rootdev 6 99) ;;
	*)	
	esac
	if [ -n "$root" ]; then
	    while :; do
		idx=$(expr index $root /)
		[ $idx = 0 ] && break
		root=$(expr substr $root 1 $(expr $idx - 1)
		   )!$(expr substr $root   $(expr $idx + 1) 99)
	    done
	    sysfs_set_root $root
	fi
}

if ! discover_root ; then
    if [ -n "$rootdev" ]; then
	echo $rootdev > /proc/sys/kernel/real-root-dev
    elif [ -n "$rootdevn" ]; then
	echo $rootdevn > /proc/sys/kernel/real-root-dev
    else
	: # let the kernel do its internal root device scan
	  # (we don't get here.)
    fi
fi

die 0

