#!/bin/bash

# mkinitrd
#
# Written by Erik Troan <ewt@redhat.com>
#
# Contributors:
#	Elliot Lee <sopwith@cuc.edu>
#	Miguel de Icaza <miguel@nuclecu.unam.mx>
#	Christian 'Dr. Disk' Hechelmann <drdisk@ds9.au.s.shuttle.de>
#	Michael K. Johnson <johnsonm@redhat.com>
#	Pierre Habraken <Pierre.Habraken@ujf-grenoble.fr>
#	Jakub Jelinek <jakub@redhat.com>
#	Carlo Arenas Belon (carenas@chasqui.lared.net.pe>
#	Keith Owens <kaos@ocs.com.au>
#	Bernhard Rosenkraenzer <bero@redhat.com>
#	Matt Wilson <msw@redhat.com>
#       Trond Eivind Glomsrd <teg@redhat.com>
#       Jeremy Katz <katzj@redhat.com>
#       Preston Brown <pbrown@redhat.com>
#	Bill Nottingham <notting@redhat.com>
#       Guillaume Cottenceau <gc@mandrakesoft.com>
#	Pixel <pixel@mandrakesoft.com>
#	Luca Berra <bluca@vodka.it>

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

VERSION=3.5.18-mdk

compress=1
target=""
kernel=""
force=""
verbose=""
MODULES=""
img_vers=""
builtins=""
initrdfs="ext2"
pivot=1
modulefile=/etc/modules.conf
tmpdir=
rc=0
kernel25=""

splash_dir=/usr/share/bootsplash/
splash=auto
theme=Mandrake

DEFAULT_DSDT_FILE="/boot/dsdt.aml"
dsdt_file=""

IMAGESIZE=100
NB_INODES=100
POSTSCSIMODS="sd_mod"
fstab="/etc/fstab"
IGNOREMODS="$IGNOREMODS ppa imm ide-scsi $initrdfs usb-storage"

[[ -f /etc/sysconfig/bootsplash ]] && source /etc/sysconfig/bootsplash
[[ -n $SPLASH ]] && splash=$SPLASH
[[ -n $THEME ]] && theme=$THEME
[[ $splash == no ]] && splash=

usage () {
    echo "usage: `basename $0` [--version] [-v] [-f] [--preload <module>]" >&2
    echo "       [--omit-scsi-modules] [--omit-raid-modules] [--omit-lvm-modules]" >&2
    echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]" >&2
    echo "       [--builtin=<module>] [--initrdfs=<fs>] [--nopivot] [--tmpdir=<tmpdir>]" >&2
    echo "       [--splash={auto,resolution}] [--dsdt[=<dsdt.aml>]]" >&2
    echo "       [--lvm-version=<1|2>] <initrd-image> <kernel-version>" >&2
    echo "" >&2
    echo "       (ex: `basename $0` /boot/initrd-$(uname -r).img $(uname -r))" >&2
    exit 1
}

check_kernel_25() {
	local -i major minor

	major=$(expr "$1" : '\([^.]\+\)\..*')
	minor=$(expr "$1" : '[^.]\+\.\([^.]\+\)\..*')

	if [ $major -ge 3 -o $major -eq 2 -a $minor -ge 5 ]; then
		kernel25=yes
		modulefile=/etc/modprobe.conf
		modulemap="s@pdc-ultra@sata_promise@"
		IGNORE="$IGNORE ataraid"
	fi
}

moduledep() {
    if [ ! -f "/lib/modules/$kernel/modules.dep" ]; then
	echo "No dep file found for kernel $kernel" >&2
	exit 1
    fi

    [ -n "$verbose" ] && echo "Looking for deps of module $1"
    deps=$(awk 'BEGIN { searched=ARGV[2]; ARGV[2]=""; rc=1 } \
                function modname(filename) { match(filename, /\/([^\/]+)\.k?o/, ret); return ret[1] } \
                function show() { if (orig == searched) { print dep; orig=""; rc=0; exit } } \
                /^\/lib/ { show(); \
                           orig=modname($1); \
        	    	   dep=""; \
		           for (i=2; i<=NF; i++) { dep=sprintf("%s %s", dep, modname($i)) } } \
                /^	/ { dep=sprintf("%s %s", dep, modname($1));  } \
                END      { show(); exit(rc) }' /lib/modules/$kernel/modules.dep $1)
    [ -n "$verbose" -a -n "$deps" ] && echo -e "\t$deps"
}

findmodule() {
    skiperrors=""

    if [ $1 == "--skiperrors" ]; then
	skiperrors=--skiperrors
	shift
    fi

    local modName=$1

    if [ -n "$modulemap" ]; then
	local modMap=`echo $modName | sed -e $modulemap`
	if [ "${modMap}" != "${modName}" ]; then
		[ -n "$verbose" ] && echo "replacing $modName with $modMap"
		modName=$modMap
	fi
    fi

    if [ "$modName" = "off" -o "$modName" = "null" ]; then
	return
    fi

    if [ "$modName" != "${modName#-}" ]; then
	skiperrors=--skiperrors
	modName=${modName#-}
    fi

    if echo $builtins | egrep -q '(^| )'$modName'( |$)' ; then
	[ -n "$verbose" ] && echo "module $modName assumed to be built in"
	return
    fi

    for i in $IGNOREMODS; do
 	[ "$i" = "$modName" ] && return
    done

    moduledep $modName
    for i in $deps; do
	findmodule $i
    done

    # support generation of initrd suitable for a raid system on a non raid system
    case $modname in
	linear|multipath|raid[015]*) startraid=1;;
    esac

    for modExt in o.gz o ko.gz ko ; do
	fmPath=`(cd /lib/modules/$kernel; find . -type f -name $modName.$modExt | grep -v "^./build")`
	[ -n "$fmPath" ] && break
    done

    if [ -z "$fmPath" ]; then
	if [ -n "$skiperrors" ]; then
	    return 1
	fi

	echo "No module $modName found for kernel $kernel, aborting." >&2
	exit 1
    fi

    # only need to add each module once
    zfmPath=${fmPath%.gz}
    if ! echo $MODULES | grep -q "$zfmPath" 2>/dev/null ; then
	MODULES="$MODULES $zfmPath"
    fi
}

is_good_fs() {
    local parttype= tmpname=
    local dir=$1
    [[ -d $dir ]] || return 1
    [[ -w $dir ]] || return 1
    [[ $dir == */ ]] && dir=${dir%/}
    parttype=$(awk "{if (\$2 == \""$dir"\") print \$3 }" /proc/mounts)

    while tmpname=${dir%/*} && [[ -z $parttype ]];do
	[[ -z $tmpname ]] && tmpname=/
	parttype=$(awk "{if (\$2 == \""$tmpname"\") print \$3 }" /proc/mounts)
	dir=$tmpname
    done

    case $parttype in
	nfs|tmpfs) return 1;;
	*) return 0;
    esac
}

inst() {
    if [ "$#" != "2" ];then
        echo "usage: inst <file> <destination>"
        return
    fi 
    [ -n "$verbose" ] && echo "$1 -> $2"
    cp -aL $1 $2
    for i in `ldd $1 | awk '$2 == "=>" {print $3}'`; do
	j=${i##*/}
	[ -e $MNTIMAGE/lib/$j ] || cp -aL $i $MNTIMAGE/lib/$j
    done
}

is_dietlibc_arch() {
    if [ -n "`uname -m | grep '\(i.86\|x86_64\)'`" ]; then return 0; fi
    return 1
}

while [ $# -gt 0 ]; do
    case $1 in
	--fstab*)
	    if echo $1 | grep -q '=' ; then
	    	fstab=`echo $1 | sed 's/^--fstab=//'`
	    else
		fstab=$2
		shift
	    fi		    
	    ;;

	--tmpdir*)
	    if echo $1 | grep '=' >/dev/null ; then
	    	tmpdir=`echo $1 | sed 's/^--tmpdir=//'`
	    else
		tmpdir=$2
		shift
	    fi		    
	    ;;

	--with-usb)
	    withusb=yes
	    ;;

	--with*)
	    if echo $1 | grep -q '=' ; then
	    	modname=`echo $1 | sed 's/^--with=//'`
	    else
		modname=$2
		shift
	    fi		    

	    basicmodules="$basicmodules $modname"
	    ;;

	--builtin*)
	    if echo $1 | grep -q '=' ; then
	    	modname=`echo $1 | sed 's/^--builtin=//'`
	    else
		modname=$2
		shift
	    fi		    
	    builtins="$builtins $modname"
	    ;;

	--initrdfs*)
	    if echo $1 | grep -q '=' ; then
	    	initrdfs=`echo $1 | sed 's/^--initrdfs=//'`
	    else
		initrdfs=$2
		shift
	    fi		    
	    case $initrdfs in
		romfs|cramfs) readonly=1;;
		ext2|ext3|minix) ;;
		*) echo "Unsupported initrd fs ($initrdfs)." 1>&2 ; exit 1 ;;
		esac
	    ;;
	    
	--version)
	    echo "mkinitrd: version $VERSION"
	    exit 0
	    ;;

	-v)
	    verbose=-v
	    ;;

	--nocompress)
	    compress=""
	    ;;

	--nopivot)
	    pivot=""
	    ;;

	--ifneeded)
	    # legacy
	    ;;

	-f)
	    force=1
	    ;;
	--preload*)
	    if echo $1 | grep -q '=' ; then
	    	modname=`echo $1 | sed 's/^--preload=//'`
	    else
		modname=$2
		shift
	    fi		    
	    PREMODS="$PREMODS $modname"
	    ;;
	--omit-scsi-modules)
	    POSTSCSIMODS=""
	    noscsi=1;
	    ;;
	--omit-raid-modules)
	    noraid=1;
	    ;;
	--omit-lvm-modules)
	    nolvm=1
	    ;;
	--lvm-version*)
	    if echo $1 | grep -q '=' ; then
	    	lvmver=`echo $1 | sed 's/^--lvm-version=//'`
	    else
		lvmver=$2
		shift
	    fi		    
	    ;;
	--image-version)
	    img_vers=yes
	    ;;
	--splash*)
	    if echo $1 | grep '=' >/dev/null ; then
	    	splash=`echo $1 | sed 's/^--splash=//'`
	    else
		splash=$2
		shift
	    fi		    
	    [[ $splash == no ]] && splash=
	    ;;
	--dsdt*)
	    if echo $1 | grep '=' >/dev/null ; then
	    	dsdt_file=`echo $1 | sed 's/^--dsdt=//'`
	    else
		dsdt_file=$DEFAULT_DSDT_FILE
	    fi		    
	    ;;
	*)
	    if [ -z "$target" ]; then
		target=$1
	    elif [ -z "$kernel" ]; then
		kernel=$1
	    else
		usage
	    fi
	    ;;
    esac

    shift
done

if [ -z "$target" -o -z "$kernel" ]; then
    usage
fi

check_kernel_25 "$kernel"

if [[ $splash == auto && -f $splash_dir/scripts/detect-resolution ]];then
    splash=$( $splash_dir/scripts/detect-resolution $target )
fi

if [ -n "$img_vers" ]; then
    target="$target-$kernel"
fi

if [ -z "$force" -a -f $target ]; then
    echo "$target already exists." >&2
    exit 1
fi

if [ ! -d /lib/modules/$kernel ]; then
    echo "/lib/modules/$kernel is not a directory." >&2
    exit 1
fi

if [ $UID != 0 ]; then
    echo "mkinitrd must be run as root"
    exit 1
fi

if [ ! -f /proc/version ]; then
    mount -t proc /proc /proc
    if [ ! -f /proc/version ]; then
	echo "/proc filesystem must be available"
	exit 1
    fi
fi

for n in $PREMODS; do
	findmodule $n
done

needusb=""
if [ -n "$withusb" ]; then
    echo "Root on USB is not yet available"
    exit 1
    # If / or /boot is on a USB device include the driver. With root by
    # label we could still get some odd behaviors
    for fs in / /boot ; do
	esc=$(echo $fs | sed 's,/,\\/,g')
	dev=$(mount | awk "/ on ${esc} / { print \$1 }" | sed 's/[0-9]*$//' | cut -d/ -f3)
	if [ "${dev#sd}" != "$dev" ]; then
          if [ `which kudzu 2>/dev/null` ]; then
	    host=$(kudzu --probe -b scsi |
	      gawk '/^device: '${dev}'/,/^host:/ { if (/^host/) { print $2; exit; } }')
	    if [ -d /proc/scsi/usb-storage-${host} ]; then
		needusb=1
	    fi
          fi
	fi
    done
fi

if [ -n "$needusb" ]; then
    drivers=$(awk '/^alias[[:space:]]+usb-controller[0-9]* / { print $3}' $modulefile)
    if [ -n "$drivers" ]; then
	for driver in $drivers; do
	    findmodule $driver
	done
	findmodule sd_mod
	findmodule usb-storage
    fi
fi

if [ -z "$noscsi" ]; then
    if [ ! -f $modulefile ]; then
        modulefile=/etc/conf.modules
    fi

    if [ -f $modulefile ]; then
	# support standard alias form
	# support probeall form as found with Mandrake 8.1 and superior
	# support canonical probeall translation for module-init-tools
	scsimodules=$(grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+scsi_hostadapter' $modulefile | sed 's/^.*scsi_hostadapter//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//')

	if [ -n "$scsimodules" ]; then
	    SAVEMODULES=$MODULES

	    SAVEMODULESCMP=$MODULES

	    for n in $(for m in $scsimodules; do echo $m; done | awk 'a[$1]=="" {print;a[$1]=1}'); do
    # for now allow scsi modules to come from anywhere.  There are some
    # RAID controllers with drivers in block/
		findmodule $n
	    done

	    if [ "$SAVEMODULESCMP" = "$MODULES" ]; then
		MODULES=$SAVEMODULES
	    else
		for n in $POSTSCSIMODS; do
		    findmodule $n
		done
	    fi
	fi
    fi
fi

# If we have ide devices and module ide, do the right thing
ide=/proc/ide/ide*
if [ -n "$ide" ]; then
    if [ -f $modulefile ]; then
	idemodules=$(grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+ide-controller[0-9]*[[:space:]]' $modulefile | sed 's/^.*ide-controller[0-9]*//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//')
    fi
    if [ -n "$idemodules" ]; then
	for idemodule in $idemodules; do
	    findmodule $idemodule
	done

	# Debian patch
	findmodule -ide-mod
	findmodule -ide-probe-mod

	# official way
	findmodule -ide-core

	findmodule -ide-disk
    fi

fi

# check to see if we need to set up a loopback filesystem
rootdev=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $fstab)
fstabrootdev=$rootdev
if [ ${rootdev#LABEL=} != $rootdev ]; then
    rootdev=${rootdev#LABEL=}
    if [ $(e2label /dev/root) = ${rootdev} ]; then
	rootdev=/dev/root
    fi
    echo "rootdev=${rootdev}"
fi
fullloopfile=$(awk '$2 == "/" && $4 ~ "loop" { print $1 }' /etc/fstab)
if [ -n "$fullloopfile" ]; then
    dir=$fullloopfile
    while [ -n "$dir" -a -z "$line" ]; do
        dir=$(dirname $dir)
	line=$(awk -v dir=$dir '$2 == dir { print $0 }' /etc/fstab)	
    done
    if [ -z "$line" -o "$dir" = "/" ]; then
	echo "bad fstab, loopback file doesn't belong to any device"
	exit 1
    fi

    loopDev=$(echo $line | awk '{ print $1 }')
    loopFs=$(echo $line | awk '{print $3 }')
    loopFile=$(echo $fullloopfile | sed "s|$dir||")

    basicmodules="$basicmodules -loop"
    if [ "$loopFs" = "vfat" -o "$loopFs" = "msdos" ]; then
	basicmodules="$basicmodules -fat"
    fi
    basicmodules="$basicmodules -${loopFs}"
fi

# check if the root fs is on a logical volume
while [ -L $rootdev ]; do
	rel=${rootdev%/*}
	rootdev=$(/bin/ls -l $rootdev | /bin/awk '{ print $NF }')
    	[ $rootdev = ${rootdev#/} ] && rootdev=$rel/${rootdev} # devfs makes relative links sometimes
done
root_major=$(/bin/ls -l $rootdev | /bin/awk '{ print $5 }')
[ -f /sbin/lvm1-vgdisplay ] && lvmprefix="lvm1-"
dm_major=`awk '$2 == "device-mapper" {print $1}' /proc/devices`
if [ "$root_major" = "$dm_major", -a -z "$nolvm" ]; then
# trick to support making initrd for kernel that has a different version of lvm
# unless forced by --lvmver
    case x$lvmver in
	x1) findmodule -lvm-mod;;
	x2) findmodule -dm-mod;;
	x)  if ! findmodule -dm-mod && findmodule -lvm-mod; then
		lvmver=1
	    else
		lvmver=2
	    fi;;
    esac
    # root is on an LVM2 LV
    root_lvm=1
    rootvg=`/sbin/lvm2 lvdisplay $fstabrootdev | /bin/awk '/VG Name/ { print $NF }'`
    pvs=$(/sbin/lvm2 vgdisplay -v ${rootvg} | /bin/awk '/PV Name/ { print $NF }')
elif [ $root_major = 58, -a -z "$nolvm" ]; then
    case x$lvmver in
	x1) findmodule -lvm-mod;;
	x2) findmodule -dm-mod;;
	x)  if ! findmodule -lvm-mod && findmodule -dm-mod; then
		lvmver=2
	    else
		lvmver=1
	    fi;;
    esac
    # root is on an LVM LV
    root_lvm=1
    rootvg=`/sbin/${lvmprefix}lvdisplay $fstabrootdev | /bin/awk '/VG Name/ { print $NF }'`
    pvs=$(/sbin/${lvmprefix}vgdisplay -v ${rootvg} | /bin/awk '/PV Name/ { print $(NF-1) }')
elif [ $root_major = 9, -a -z "$noraid" ]; then
    raiddevices=$rootdev
    md=${rootdev##*/}
    md=md${md#md} # /dev/md/0 and /dev/md0 become md0
    mddevs=$(awk '/^'$md'[[:space:]]*:/ {for (i=5;i<=NF;i++) {sub("\\[[0-9]*\\]","",$i); print "/dev/" $i } }' /proc/mdstat)
fi

# let's see if some pv or md are actually raid devices themselves
for mddev in $mddevs $pvs; do
    while [ -L $mddev ]; do
	rel=${mddev%/*}
	mddev=$(/bin/ls -l $mddev | /bin/awk '{ print $NF }')
    	[ $mddev = ${mddev#/} ] && mddev=$rel/${mddev} # devfs makes relative links sometimes
    done
    md_major=$(/bin/ls -l $mddev | /bin/awk '{ print $5 }')
    [ $md_major = 9, ] && raiddevices="$mddev $raiddevices"
done

for md in $raiddevices; do
    startraid=1
    md=${md##*/}
    md=md${md#md} # /dev/md/0 and /dev/md0 become md0
    level=$(awk '/^'$md'[[:space:]]*:/ { print $4 }' /proc/mdstat)
    case $level in
	linear|multipath|raid[015])
	    findmodule $level
	    ;;
	*)
	    echo "raid level $level (in /proc/mdstat) not recognized" >&2
	    ;;
    esac
done

rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' $fstab)
rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' $fstab)

# in case the root filesystem is modular
findmodule -${rootfs}

for n in $basicmodules; do 
    findmodule $n
done

if [ -n "$verbose" ]; then
    echo "Using modules: $MODULES"
fi


[[ -n $tmpdir ]] && { is_good_fs $tmpdir || tmpdir= ;} #command-line
[[ -z $tmpdir && -n $TMPDIR ]] && { is_good_fs $TMPDIR || tmpdir= && tmpdir=$TMPDIR ;} #environement
if [[ -z $tmpdir ]];then
    if is_good_fs /tmp;then
	tmpdir=/tmp
    elif is_good_fs /var/tmp;then
	tmpdir=/var/tmp
    elif is_good_fs /root/tmp;then
	tmpdir=/root/tmp
    else
	echo "Cannot find a suitable tmp directory" >&2
	exit 1
    fi
fi
[[ -n $verbose ]] && echo "Using $tmpdir as temporary directory."

MNTIMAGE=`mktemp -d ${tmpdir}/initrd.XXXXXX`
IMAGE=`mktemp ${tmpdir}/initrd.img.XXXXXX`
MNTPOINT=`mktemp -d ${tmpdir}/initrd.mnt.XXXXXX`
RCFILE=$MNTIMAGE/linuxrc
# cleanup on exit, hangup, interrupt, quit, termination
trap 'rm -rf $MNTIMAGE $MNTPOINT $IMAGE' 0 1 2 3 15

if [ -z "$MNTIMAGE" -o -z "$IMAGE" -o -z "$MNTPOINT" ]; then
    echo "Error creating temporaries.  Try again" >&2
    exit 1
fi

mkdir -p $MNTIMAGE/lib
mkdir -p $MNTIMAGE/bin
mkdir -p $MNTIMAGE/etc
mkdir -p $MNTIMAGE/dev
mkdir -p $MNTIMAGE/loopfs
mkdir -p $MNTIMAGE/proc
mkdir -p $MNTIMAGE/sys
mkdir -p $MNTIMAGE/sysroot
ln -s bin $MNTIMAGE/sbin
# devfs will shadow some of my dev entries, I'll put them here
mkdir -p $MNTIMAGE/safedev   

# We don't need this directory, so let's save space
rm -rf $MNTPOINT/lost+found

inst /sbin/nash "$MNTIMAGE/bin/nash"
if is_dietlibc_arch; then
    if [[ -n "$kernel25" ]]; then
	inst /sbin/insmod-25-DIET "$MNTIMAGE/bin/insmod"
    else
	inst /sbin/insmod-DIET "$MNTIMAGE/bin/insmod"
    fi
else
    if [[ -n "$kernel25" ]]; then
	inst /sbin/insmod.static-25 "$MNTIMAGE/bin/insmod"
    else
	inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
    fi
fi
ln -s ../bin/nash $MNTIMAGE/sbin/modprobe

for MODULE in $MODULES; do
    f="/lib/modules/$kernel/$MODULE"
    if [ -e $f ]; then
	cp $verbose -a $f $MNTIMAGE/lib
    else
	gunzip -c $verbose $f.gz > $MNTIMAGE/lib/`basename $MODULE`
    fi
    [ -x /usr/bin/strip ] && /usr/bin/strip -g $verbose $MNTIMAGE/lib/`basename $MODULE`
done

# mknod'ing the devices instead of copying them works both with and
# without devfs...
mknod $MNTIMAGE/dev/console c 5 1
mknod $MNTIMAGE/dev/null c 1 3
mknod $MNTIMAGE/dev/ram b 1 1
mknod $MNTIMAGE/dev/systty c 4 0
for i in 1 2 3 4; do
    mknod $MNTIMAGE/dev/tty$i c 4 $i
done

echo "#!/bin/nash" > $RCFILE
echo "" >> $RCFILE

for MODULE in $MODULES; do
    text=""
    module=${MODULE##*/}
    module_s=${module%.o}
    module_s=${module_s%.ko}

    options=$(sed -n -e "s/^options[ 	][ 	]*$module_s[ 	][ 	]*//p" $modulefile 2>/dev/null)

    if [ -n "$verbose" ]; then
	if [ -n "$options" ]; then
	    text=" with options $options"
	fi
        echo "Loading module $module$text"
    fi
    echo "echo \"Loading $module module\"" >> $RCFILE
    echo "insmod /lib/$module $options" >> $RCFILE

    # Hack - we need a delay after loading usb-storage to give things
    #        time to settle down before we start looking a block devices
    if [ "$module" = "usb-storage" ]; then
	echo "sleep 5" >> $RCFILE
    fi
done

echo "echo Mounting /proc filesystem" >> $RCFILE
echo "mount -t proc /proc /proc" >> $RCFILE
echo "echo Creating device files" >> $RCFILE
[ -n "$readonly" ] && echo "mountdev" >> $RCFILE
echo "mkdevices /dev" >> $RCFILE
_partitions=`cat /proc/partitions | wc -l`
NB_INODES=$[NB_INODES + $_partitions * 3 ]

if [ -n "$kernel25" ];then
    echo "echo Mounting sysfs" >> $RCFILE
    echo "mount -t sysfs none /sys" >> $RCFILE
fi

if [ -n "$startraid" ]; then
    echo "echo Activating md devices" >> $RCFILE
    if [ -x /sbin/mdadm ]; then
	echo "DEVICE partitions" > $MNTIMAGE/etc/mdadm.conf
    fi
    for dev in $raiddevices; do
	if [ -x /sbin/mdadm ]; then
	    /sbin/mdadm -D -b $dev | grep '^ARRAY' >> $MNTIMAGE/etc/mdadm.conf
    	fi
	md=${dev##*/}
	md=${md#md} # /dev/md/0 and /dev/md0 become 0
	echo "mknod /dev/md$md b 9 $md" >> $RCFILE
	echo "mknod /dev/md/$md b 9 $md" >> $RCFILE
    done
    if [ -x /sbin/mdassemble ]; then
	cp $verbose -aL /sbin/mdassemble $MNTIMAGE/sbin
	echo "mdassemble" >> $RCFILE
    elif [ -x /sbin/mdadm ]; then
	inst /sbin/mdadm $MNTIMAGE/sbin
	echo "mdadm -A -s" >> $RCFILE
    else
	echo "raidautorun /dev/md${md}" >> $RCFILE
    fi
fi

if [ -n "$loopDev" ]; then
    # our dear friend devfsd will create links for us if devfs in use
    cp -aL $loopDev $MNTIMAGE/safedev
    cp -aL /dev/loop7 $MNTIMAGE/safedev

    loopDev=/safedev/${loopDev#/dev/}

    echo "echo Mounting device containing loopback root filesystem" >> $RCFILE
    echo "mount -t $loopFs $loopDev /loopfs" >> $RCFILE
    echo "echo Setting up loopback device on $loopFile" >> $RCFILE
    echo "losetup /safedev/loop7 /loopfs$loopFile" >> $RCFILE
    rootdev=/safedev/loop7
elif [ -n "$root_lvm" ]; then
    if [ "$lvmver" = "2" ]; then
	if [ -x /sbin/lvm2-static ]; then
	    cp $verbose -aL /sbin/lvm2-static $MNTIMAGE/sbin/vgscan
	else 
	    inst /sbin/lvm2 $MNTIMAGE/sbin/vgscan
	fi
	ln -s vgscan $MNTIMAGE/sbin/vgchange
	ln -s vgscan $MNTIMAGE/sbin/vgmknodes
	mkdir -p $MNTIMAGE/etc/lvm/{archive,backup}

	echo "devices {" >> $MNTIMAGE/etc/lvm/lvm.conf
	echo " dir = \"/dev\"" >> $MNTIMAGE/etc/lvm/lvm.conf
	grep "^[[:space:]]*\(scan\|filter\|types\)" /etc/lvm/lvm.conf >> $MNTIMAGE/etc/lvm/lvm.conf
	echo " write_cache_state = 0" >> $MNTIMAGE/etc/lvm/lvm.conf
	echo "}" >> $MNTIMAGE/etc/lvm/lvm.conf

	echo "echo Making device-mapper control node" >> $RCFILE
	echo "mkdmnod" >> $RCFILE
	echo "echo Scanning logical volumes" >> $RCFILE
	echo "vgscan -P --ignorelockingfailure" >> $RCFILE
	echo "echo Activating logical volumes" >> $RCFILE
	echo "vgchange -P -ay --ignorelockingfailure" >> $RCFILE
	echo "echo Making device nodes" >> $RCFILE
	echo "vgmknodes" >> $RCFILE
    else
	if [ -x /sbin/${lvmprefix}vgwrapper ]; then
	    cp $verbose -aL /sbin/${lvmprefix}vgwrapper $MNTIMAGE/sbin/vgscan
	    ln -s vgscan $MNTIMAGE/sbin/vgchange
	else 
	    inst /sbin/${lvmprefix}vgchange $MNTIMAGE/sbin/vgchange
	    inst /sbin/${lvmprefix}vgscan $MNTIMAGE/sbin/vgscan
	fi

	echo "mknod /dev/lvm b 109 0" >> $RCFILE
	echo "mount -t tmpfs /etc /etc" >> $RCFILE
	echo "echo Scanning logical volumes" >> $RCFILE
	echo "vgscan" >> $RCFILE
	echo "echo Activating logical volumes" >> $RCFILE
	echo "vgchange -ay" >> $RCFILE
	echo "umount /etc" >> $RCFILE
    fi
    rootdev=$fstabrootdev
else
    echo "echo Creating root device" >> $RCFILE
    echo "mkrootdev /dev/root" >> $RCFILE
    rootdev=/dev/root
fi

[ -n "$kernel25" ] && echo "umount /sys" >> $RCFILE

if [ -n "$pivot" ]; then
    echo "echo 0x0100 > /proc/sys/kernel/real-root-dev" >> $RCFILE

    [ "$rootopts" != "defaults" ] && rootopts_msg="with flags $rootopts"
    echo "echo Mounting root filesystem $rootopts_msg" >> $RCFILE
    echo "mount -o $rootopts --ro -t $rootfs $rootdev /sysroot" >> $RCFILE

    echo "pivot_root /sysroot /sysroot/initrd" >> $RCFILE
    echo "echo Remounting devfs at correct place if necessary" >> $RCFILE
    echo "handledevfs" >> $RCFILE
    echo "umount /initrd/proc" >> $RCFILE
else
    [ -n "$readonly" ] && echo "umount /dev" >> $RCFILE
    echo "umount /proc" >> $RCFILE
fi

chmod +x $RCFILE

if [ -n "$verbose" ]; then
    echo "Contents of RCFILE:"
    cat $RCFILE 2> /dev/null
fi

case $initrdfs in
    ext2|ext3|minix)
	for i in `/bin/find $MNTIMAGE -printf '%k\n'`; do
	    IMAGESIZE=$[IMAGESIZE + $i]
	    NB_INODES=$[NB_INODES + 1]
	done
	IMAGESIZE=$[IMAGESIZE + NB_INODES / 10]  # 10 inodes needs 1k

	dd if=/dev/zero of=$IMAGE bs=1k count=$IMAGESIZE 2> /dev/null

	if [ -n "$verbose" ]; then
	    echo "Creating filesystem with size ${IMAGESIZE}KB and $NB_INODES inodes"
	fi
	case $initrdfs in
	    ext2|ext3) mkfs.$initrdfs -q -m 0 -F -N $NB_INODES -s 1 $IMAGE;;
	    minix) mkfs.minix $IMAGE;;
	esac

	mkdir -p $MNTPOINT
	mount -t $initrdfs $IMAGE $MNTPOINT -o loop || {
	    echo "Can't get a loopback device" >&2
	    exit 1
	}

	# We don't need this directory, so let's save space
	rm -rf $MNTPOINT/lost+found

	(cd $MNTIMAGE; tar cf - .) | (cd $MNTPOINT; tar xf -) || exit 1

	umount $MNTPOINT
	;;
    cramfs)
	mkfs.cramfs "$MNTIMAGE" "$IMAGE"
	compress=""
	;;
    romfs)
	genromfs -d "$MNTIMAGE" -f "$IMAGE"
	;;
esac

if [ -n "$compress" ]; then
    gzip -9 < $IMAGE > $target || exit 1
else
    cp -a $IMAGE $target || exit 1
fi

if [[ -n "$splash" && -f $splash_dir/scripts/make-boot-splash ]]; then
    $splash_dir/scripts/make-boot-splash $target $splash
fi

if [[ -n "$dsdt_file" && -f "$dsdt_file" ]]; then
    echo -n "INITRDDSDT123DSDT123" >> $target
    cat "$dsdt_file" >> $target
fi

exit $rc
