#!/bin/bash --norc

# mkinitrd
#
# Copyright 2005 Red Hat, Inc.
#
# 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>
#	Peter Jones <pjones@redhat.com>
#	Pixel <pixel@mandrakesoft.com>
#	Luca Berra <bluca@vodka.it>

umask 0022

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

VERSION=4.2.17mdk

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

DEFAULT_DSDT_FILES="/boot/dsdt.aml /boot/DSDT.aml"
dsdt_files=""

IMAGESIZE=100
NB_INODES=100
fstab="/etc/fstab"

[ -f /etc/udev/udev.conf -a \( -x /sbin/udevstart -o -x /sbin/start_udev \) ] && USE_UDEV=yes

[ -f /etc/sysconfig/mkinitrd ] && source /etc/sysconfig/mkinitrd

[ -z "$dsdt_files" -a -n "$dsdt_file" ] && dsdt_files="$dsdt_file"

IGNOREMODS="$IGNOREMODS ppa imm ide-scsi"

usage () {
    echo "usage: `basename $0` [--version] [-v] [-f] [--preload <module>]" >&2
    echo "       [--with=<module>] [--omit-scsi-modules] [--omit-raid-modules]" >&2
    echo "       [--image-version] [--fstab=<fstab>] [--nocompress]" >&2
    echo "       [--builtin=<module>] [--nopivot] [--noudev] [--allow-missing]" >&2
    echo "       [--tmpdir=<tmpdir>] [--initrdfs=<fs>] [--noresume] [--noresume2]" >&2
    echo "       [--dsdt[=<dsdt.aml>]] [--lvm-version=<1|2>] [--force-usb]" >&2
    echo "       [--force-evms] [--debug-busybox=<start|modload|pivot|exit>]" >&2
    echo "       <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
		definitrdfs="initramfs"
		modulefile=/etc/modprobe.conf
		modulemap="s@pdc-ultra@sata_promise@;s@usb-uhci@uhci-hcd@;s@usb-ohci@ohci-hcd@;s@^uhci\$@uhci-hcd@"
		IGNORE="$IGNORE ataraid"
	else
		USE_UDEV=
	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)) } } \
	/^[[:space:]]/ { 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

    # only need to add each module once
    if echo $MODULES | grep -q "/$modName\.k\?o" 2>/dev/null ; then
	return
    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

    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


	if [ -n "$allowmissing" ]; then
	    echo "WARNING: No module $modName found for kernel $kernel, continuing anyway" >&2
	    return
	fi
     
	echo "No module $modName found for kernel $kernel, aborting." >&2
	exit 1
    fi

    zfmPath=${fmPath%.gz}
    # only need to add each module once
    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 '/\// {if($2 == "=>") {print $3} else {print $1}}'`; do
	j=${i##*/}
	[ -e $MNTIMAGE/lib/$j ] || cp -aL $i $MNTIMAGE/lib/$j
    done
}


mddev() {
    local -i major
    local dev md mddevs
    major=$((0x$(stat -L -c '%t' $1)))
    if [ $major = 9 ]; then
	# need to reverse the raiddevices list to account for
	# stacked md devices
	raiddevices="$1 $raiddevices"
	md=${1##*/}
	md=md${md#md} # /dev/md/0 and /dev/md0 become md0
	mddevs=""
	[ -x /sbin/mdadm ] && mddevs=$(/sbin/mdadm -Dv $1 | awk '$1$2$3$4$NF ~ /^[0-9]+\// {print $NF}')
	[ -z "$mddevs" ] && \
	mddevs=$(awk '/^'$md'[[:space:]]*:/ {for (i=5;i<=NF;i++) {sub("\\[[0-9]*\\]","",$i); print "/dev/" $i } }' /proc/mdstat)
	for dev in $mddevs; do
	    mddev $dev
	done
    else
	nonraiddevices="$nonraiddevices $1"
    fi
}

dmraidev() {
    local dev raid major
    major=$((0x$(stat -L -c '%t' $1)))
    if [ -x /sbin/dmraid -a "$major" = "$dm_major" ]; then
	for raid in `/sbin/dmraid -sa -c -g`; do
	    [ ${1#*/$raid} != ${1} ] && \
		dev=`/sbin/dmraid -r -c -c | awk -F: -v raid=$raid '$3 ~ raid {print $1}'`	
		[ -n "$dev" ] && break
	done
    fi
    if [ -n "$dev" ]; then
	root_dmraid=1
	need_dmnod=1
	findmodule -dm-mod
	findmodule -dm-mirror
	findmodule -sd_mod
	nonraiddevices="$nonraiddevices $dev"
    else
	nonraiddevices="$nonraiddevices $1"
    fi
}

scsidriver() {
    local -i major minor count i
    local foo bus j drv
    # try to find the driver through sysfs
    foo=${1##*/}
    if [ -d /sys/block/$foo ]; then
	bus=`readlink -f /sys/block/$foo/device/../..`
    else
	for j in /sys/block/*/$foo; do
	    bus=`readlink -f $j/../device/../..`
	done
    fi
    # does this look like a scsi bus
    if [ -n "$bus" -a "${bus##*/host}" != "$bus" ]; then
	bus=${bus##*/host}
	# this is complex since we must load all scsi drivers
	# that are used by sd, to avoid drive letter change
	for i in `seq 0 $bus`; do
	    for j in /sys/class/scsi_host/host$i/device/target*/*/driver; do
		foo=`readlink -f $j`
		if [ "${foo##*/}" = "sd" ]; then
		    foo=`readlink -f /sys/class/scsi_host/host$i/device/../driver`
		    if [ -z "$foo" ]; then
			# Fallback to old method if we haven't found the driver.
			# This happens for some scsi drives like aic7xxx_old that don't
			# provide a driver link.
			echo -n "FALLBACK"
			return
		    fi
		    drv="$drv ${foo##*/}"
		fi
	    done
	done
	echo -n "$drv"
    	[ -n "$drv" ] && return
    fi

    # the sysfs method turned no driver, try with /proc
    major=$((0x$(stat -L -c '%t' $1)))
    foo=`awk -v major=$major '
	BEGIN { i=0 }
	$1 == major && $2 == "sd" { print i; exit }
	$2 == "sd" { i++ }
	' /proc/devices`
    if [ -n "$foo" ]; then
	minor=$((0x$(stat -L -c '%T' $1)))
	count=$((foo * 16 + $minor / 16))

	bus=`awk -v count=$count '
	    BEGIN { i=0 }
	    /^Host:/ { h=$2; sub("^scsi","",h) }
	    /Type:[[:space:]]*Direct-Access/ {
		print h;
		if (i++==count) {exit }
	    }
	    ' /proc/scsi/scsi`
	for i in $bus; do
	    for j in /proc/scsi/*/$i; do
		if [ -f $j ]; then
		    j=${j%/$i}
		    # filter some drivers
		    case $j in
			*IT8212*)	drv="$drv it821x";;
			*it8212*)	drv="$drv it821x";;
			*iteraid*)	drv="$drv it821x";;
			*)		drv="$drv ${j##*/}";;
		    esac
		else
		    # Fallback to old method if we haven't found the driver.
		    # This happens for example for SATA drivers that aren't populating
		    # /proc/scsi. FL [Thu Sep  2 10:30:42 2004]
		    echo -n "FALLBACK"
		    return
		fi
	    done
	done
	echo -n "$drv"
    fi
}

verif_scsidriver() {
    local all_known wanted pb known found wouldlike
    all_known=$(grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+scsi_hostadapter' $modulefile | \
	           sed 's/^.*scsi_hostadapter//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//')

    for wanted in $*; do
	if [ "${wanted}" = "FALLBACK" ]; then
	    echo $all_known
	    return
	fi
	found=
	for known in $all_known; do
	    [ "$known" = "$wanted" ] && found=1
	    # XXX exceptions for new module names not updated in modprobe.conf
	    case "$known:$wanted" in
		mptscsih:mptspi|mptscsih:mptfc) found=1;;
		mptspi:mptscsih|mptfc:mptscsih) found=1;;
		ahci:ata_piix|ata_piix:ahci) found=1;;
	    esac
	done
	if [ -z "$found" ]; then
	    pb=1
	    wouldlike="$wouldlike -$wanted"
	fi
    done

    if [ -n "$pb" ]; then
	echo $all_known $wouldlike
    else
	echo $*
    fi
}

function migrate_scsidriver() {
    local sddev=$1
    shift

    local f drv wanted
    for wanted in $*; do
	case $wanted in
	    # determine new module from pcimap (mptfc, mptspi)
	    mptscsih|mptbase)
		local dev vendor device pcimap
		dev=${sddev##*/}
		dev=${dev%%[0-9]*}
		f=$(readlink /sys/block/$dev/device) && {
		    vendor=$(cat /sys/block/$dev/${f%/host*}/vendor)
		    device=$(cat /sys/block/$dev/${f%/host*}/device)
		    pcimap=$(printf "0x%08x 0x%08x" $vendor $device)
		    wanted=`sed -n "/^\([^ ]*\)  *$pcimap.*/s//\1/p" /lib/modules/$kernel/modules.pcimap`
		}
		;;
	    # assume mptscsih if mptspi was used but it's not in older pcimap
	    mptspi|mptfc)
		grep -q $wanted /lib/modules/$kernel/modules.pcimap || wanted="mptscsih"
		;;
	    # have both ata_piix and ahci so that you can still boot
	    # after changing the config in the BIOS
	    ata_piix)
		wanted="$wanted ahci"
		;;
	    ahci)
		wanted="$wanted ata_piix"
		;;
	esac
	[[ -n "$wanted" ]] && drv="$drv $wanted"
    done

    echo $drv
}

usbdriver() {
    local driver
    local usbdrivers=$(grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+usb-interface' $modulefile | sed 's/^.*usb-interface//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//')
    if [ -n "$usbdrivers" ]; then
	for driver in $usbdrivers; do
	    findmodule $driver
	done
    fi
}

ieee1394driver() {
    local driver
    local ieee1394drivers=$(grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+ieee1394-controller' $modulefile | sed 's/^.*ieee1394-controller//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//')
    if [ -n "$ieee1394drivers" ]; then
	for driver in $ieee1394drivers; do
	    findmodule $driver
	done
    fi
}

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
	    ;;

	--force-usb)
	    forceusb=yes
	    ;;

	--force-evms)
	    force_evms=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|initramfs) ;;
		*) echo "Unsupported initrd fs ($initrdfs)." 1>&2 ; exit 1 ;;
		esac
	    ;;

	--noresume)
		noresume=1
		;;
	    
	--noresume2)
		noresume2=1
		;;
	    
	--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)
	    noscsi=1;
	    ;;
	--omit-raid-modules)
	    noraid=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
	    ;;
	--noudev)
	    USE_UDEV=
	    ;;
	--allow-missing)
	    allowmissing=yes
	    ;;
	--dsdt*)
	    if echo $1 | grep '=' >/dev/null ; then
	    	dsdt_files=`echo $1 | sed 's/^--dsdt=//'`
	    else
		dsdt_files=$DEFAULT_DSDT_FILES
	    fi		    
	    ;;
	--debug-busybox*)
	    if [ ! -x /usr/bin/busybox ]; then
                echo "busybox is not installed" 1>&2
		exit 1
	    fi
	    if echo $1 | grep -q '=' ; then
	    	debug_busybox=`echo $1 | sed 's/^--debug-busybox=//'`
	    else
		debug_busybox=$2
		shift
	    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"

: ${initrdfs:=$definitrdfs}

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

# check for modular initrdfs
findmodule -$initrdfs
if [ -n "$MODULES" ]; then
    echo "you must use a built-in filesystem for the initrd"
    echo "use the --initrdfs option to change to a different filesystem than $initrdfs"
    exit 1
fi

IGNOREMODS="$IGNOREMODS $initrdfs"

for n in $PREMODS; do
	findmodule $n
done

if [ -n "$forceusb" ]; then
    if [ -n "$kernel25" ]; then
        DRIVERLIST=(uhci-hcd ehci-hcd ohci-hcd)
    else
        DRIVERLIST=(scsi_mod uhci usb-uhci ehci-hcd usb-ohci)
    fi
    for driver in ${DRIVERLIST[*]}; do
	findmodule $driver
    done
    findmodule usbhid
    findmodule sd_mod
    findmodule usb-storage
fi

kbddrivers="$(awk '
		BEGIN {IGNORECASE=1}
		/Name=.*keyboard/ {k=1;next}
		/Name=/ {k=0;next}
		/Phys=isa/ {ph="ps2";next}
		/Phys=usb/ {ph="usb";next}
		/Phys=/ {ph="UNKNOWN";next}
		/Handlers=.*kbd/ && k == 1 {print ph}
	' /proc/bus/input/devices)"
if [ -z "${kbddrivers##*ps2*}" ]; then
    findmodule -atkbd
    findmodule -i8042
elif [ -z "${kbddrivers##*usb*}" ]; then
    usbdriver
    findmodule -usbhid
fi

# check to see if we need to set up a loopback filesystem
rootdev=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $fstab)
fstabrootdev=$rootdev
if [ -z "${rootdev}" ]; then
    echo "cannot find root device specification in fstab" 2>&1
    exit
fi
if [ -z "${fstabrootdev##LABEL=*}" -o -z "${fstabrootdev##UUID=*}" ]; then
    rootdev=$(blkid -o device -t ${fstabrootdev})
    if [ -z "${rootdev}" ]; then
	echo "cannot find root device: ${fstabrootdev}" 2>&1
	exit
    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||")
    # to check if loopdev needs some set-up
    rootdev=${loopDev}

    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 or md device
root_major=$((0x$(stat -L -c '%t' $rootdev)))
[ -f /sbin/lvm1-vgdisplay ] && lvmprefix="lvm1-"
dm_major=`awk '$2 == "device-mapper" {print $1}' /proc/devices`
if [ "$root_major" = "$dm_major" ]; then
    if [ -x /sbin/lvm2 ] && /sbin/lvm2 lvdisplay $fstabrootdev > /dev/null 2>&1; 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
		    # DM requires all of these to be there in case someone used the
		    # feature.  broken.  (RH #132001)
		    findmodule -dm-mirror
		    findmodule -dm-zero
		    findmodule -dm-snapshot
		;;
	    x)  if ! findmodule -dm-mod && findmodule -lvm-mod; then
		    lvmver=1
		else
		    lvmver=2
		    findmodule -dm-mirror
		    findmodule -dm-zero
		    findmodule -dm-snapshot
		    need_dmnod=1
		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 }')
    else
	dmraidev ${fstabrootdev}
    fi
    if [ -z "$pvs" -a -x /sbin/evms_query  ]; then
	if /sbin/evms_query info ${fstabrootdev} > /dev/null 2>&1; then
	    for i in `/sbin/evms_query objects ${fstabrootdev} | \
		/usr/bin/xargs -l evms_query plugins | \
		/bin/sort -u`; do
	    	case $i in
		    BBR)
		    	findmodule -dm-bbr
		    	evms_plugins="$evms_plugins bbr";;
		    BBRseg)
		    	findmodule -dm-bbr
			evms_plugins="$evms_plugins bbr_seg";;
		    BSD) evms_plugins="$evms_plugins bsd";;
		    CSM) evms_plugins="$evms_plugins csm";;
		    DosSegMgr) evms_plugins="$evms_plugins dos";;
		    DriveLink) evms_plugins="$evms_plugins drivelink";;
		    Error) evms_plugins="$evms_plugins error";;
		    GptSegMgr) evms_plugins="$evms_plugins gpt";;
		    LocalDskMgr) evms_plugins="$evms_plugins disk";;
		    LVM2)
			findmodule -dm-mirror
			findmodule -dm-zero
			findmodule -dm-snapshot
			evms_plugins="$evms_plugins lvm2";;
		    LvmRegMgr) evms_plugins="$evms_plugins lvm";;
		    MAC) evms_plugins="$evms_plugins mac";;
		    MDLinearRegMgr)
		    	findmodule -linear
			evms_plugins="$evms_plugins md";;
		    MDRaid0RegMgr)
		    	findmodule -raid0
			evms_plugins="$evms_plugins md";;
		    MDRaid1RegMgr)
		    	findmodule -raid1
			evms_plugins="$evms_plugins md";;
		    MDRaid5RegMgr)
		    	findmodule -raid5
		    	findmodule -raid456
			evms_plugins="$evms_plugins md";;
		    "MD Multipath")
		    	findmodule -multipath
			evms_plugins="$evms_plugins md";;
		    Multipath)
		    	findmodule -dm-multipath
			findmodule -dm-emc
		    	evms_plugins="$evms_plugins multipath";;
		    Snapshot)
		    	findmodule -dm-snapshot
		    	evms_plugins="$evms_plugins snapshot";;
		    Replace) evms_plugins="$evms_plugins replace";;
		    *) echo "Unknown EVMS plugin $i, aborting." >&2
			exit 1
		esac
	    done

	    for i in `/sbin/evms_query disks ${fstabrootdev}`; do
		nonraiddevices="$nonraiddevices /dev/evms/.nodes/$i"
	    done
	    root_evms=1
	    findmodule -dm-mod
            need_dmnod=1
	fi
    fi
elif [ $root_major = 58 ]; then
    case x$lvmver in
	x1) findmodule -lvm-mod;;
	x2) findmodule -dm-mod
	    # DM requires all of these to be there in case someone used the
	    # feature.  broken.  (RH #132001)
	    findmodule -dm-mirror
	    findmodule -dm-zero
	    findmodule -dm-snapshot
	    ;;
	x)  if ! findmodule -lvm-mod && findmodule -dm-mod; then
		findmodule -dm-mirror
		findmodule -dm-zero
		findmodule -dm-snapshot
		lvmver=2
		need_dmnod=1
	    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) }')
fi

if [ -n "$force_evms" ]; then
    root_evms=1
    need_dmnod=1
    root_lvm=""
    fstabrootdev=/dev/evms/${fstabrootdev##*/}
    findmodule -dm-mod
    findmodule -dm-bbr
    findmodule -dm-emc
    findmodule -dm-mirror
    findmodule -dm-multipath
    findmodule -dm-snapshot
    findmodule -dm-zero
    findmodule -linear
    findmodule -multipath
    findmodule -raid0
    findmodule -raid1
    findmodule -raid5
    findmodule -raid456
    evms_plugins="$evms_plugins bbr"
    evms_plugins="$evms_plugins bbr_seg"
    evms_plugins="$evms_plugins bsd"
    evms_plugins="$evms_plugins csm"
    evms_plugins="$evms_plugins disk"
    evms_plugins="$evms_plugins dos"
    evms_plugins="$evms_plugins drivelink"
    evms_plugins="$evms_plugins error"
    evms_plugins="$evms_plugins gpt"
    evms_plugins="$evms_plugins lvm"
    evms_plugins="$evms_plugins lvm2"
    evms_plugins="$evms_plugins mac"
    evms_plugins="$evms_plugins md"
    evms_plugins="$evms_plugins replace"
    evms_plugins="$evms_plugins multipath"
    evms_plugins="$evms_plugins snapshot"
fi

# if the machine is an xbox and / is loopback, assume it's a fatx image file
# 10de:02a5 is the xbox signature in /proc/pci
if [ "$root_major" -eq 7 ] && grep -q 10de:02a5 /proc/pci; then
    basicmodules="$basicmodules -fatx"
    fatxloop=yes	
fi

# let's see if some pv or the root device is a raid device
if [ -n "$pvs" ]; then
    for dev in $pvs; do
	mddev $dev
    done
elif [ -z "$nonraiddevices" ]; then
    mddev $rootdev
fi

# now we check if some are fakeraids
if [ -n "nonraiddevices" ]; then
    pvs="$nonraiddevices"
    nonraiddevices=""
    for dev in $pvs; do
	dmraidev $dev
    done
fi

if [ -n "$raiddevices" -a -z "$noraid" ]; then
    for md in $raiddevices; do
	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[01]|raid10)
		findmodule -$level
		;;
	    raid[456])
		findmodule -$level
		findmodule -raid456
		;;
	    *)
		echo "raid level $level (in /proc/mdstat) not recognized" >&2
		;;
	esac
    done
fi

# now see if some device is on a scsi bus, and load appropriate modules
if [ -z "$noscsi" ]; then
    for sddev in $nonraiddevices; do
	scsidriver=$(scsidriver $sddev)
	scsidriver=$(migrate_scsidriver $sddev $scsidriver)
	scsidriver=$(verif_scsidriver $scsidriver)
	if [ -n "$scsidriver" ]; then
	    scsimodules="$scsimodules $scsidriver"
	else
	    nonscsidevices="$nonscsidevices $sddev"
	fi
    done
fi

if [ -n "$scsimodules" ]; then
    done_scsimodules=""
    for n in $scsimodules; do
	# ensure we don't generate twice the same modules
	case " $done_scsimodules " in
	    (*" $n "*) echo skip dups; continue;;
	esac
	done_scsimodules="$done_scsimodules $n"
	[ ${n#-} = usb-storage ] && usbdriver
	[ ${n#-} = sbp2 ] && ieee1394driver
	findmodule $n
    done
    findmodule sd_mod
fi

for idedev in $nonscsidevices; do
    major=$((0x$(stat -L -c '%t' $idedev)))
    is_ide=`awk -v major=$major '$1 == major && $2 ~ /^ide[0-9]/ {print $2}' /proc/devices`
    if [ -n "$is_ide" ]; then
	idedevices="$idedevices $idedev"
    else
	nonidedevices="$nonidedevices $idedev"
    fi
done

if [ -n "$idedevices" ]; then
    # are we using modular ide?
    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/||//')
	# add any ide modules that ended in scsi_hostadapter
	for scsi_hostadapter in `grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+scsi_hostadapter' $modulefile | \
	    sed 's/^.*scsi_hostadapter//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//'`; do
		if modinfo -F filename ${scsi_hostadapter} | grep -qs /drivers/ide/; then
			idemodules="$idemodules $scsi_hostadapter"
		fi
	done
    fi

    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

for otherdev in $nonidedevices; do
    major=$((0x$(stat -L -c '%t' $otherdev)))
    driver=`awk -v major=$major '
    	/Block devices:/ {block=1}
	block == 0 {next}
	$1 == major && $2 ~ /^ida/ {print "cpqarray";exit}
	$1 == major && $2 ~ /^dac960/ {print "DAC960";exit}
	$1 == major && $2 ~ /^ad/ {print "acsi";exit}
	$1 == major && $2 ~ /^sx8/ {print "sx8";exit}
	$1 == major && $2 ~ /^ataraid/ {print "-FAIL";exit}
	$1 == major {gsub("[0-9]*$","",$2); print "-" $2}
	' /proc/devices`

    findmodule $driver
    if echo $MODULES | grep -q "/$driver\.k\?o" 2>/dev/null ; then
	: #ok
    else
	# we look into scsi_hostadapter even if it is not a scsi driver
	for i in `grep -E '^[[:space:]]*(alias|probeall|install)[[:space:]]+scsi_hostadapter' $modulefile | \
	    sed 's/^.*scsi_hostadapter//;s/\/sbin\/modprobe//g;s/;//g;s/\/bin\/true//;s/||//'`; do
	    findmodule $i
	done
    fi
done

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

if [ "$rootfs" = "auto" ]; then
	rootfs=`blkid -s TYPE $rootdev`
	rootfs=${rootfs##*TYPE=\"}
	rootfs=${rootfs%%\"*}
fi
if [ -z "$rootfs" ]; then
	echo "Cannot determine root filesystem type from fstab" 1>&2
	exit 1
fi

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

for n in $basicmodules; do 
    findmodule $n
done

#add lzf compression for suspend2
[[ -z "$noresume2" ]] && findmodule -lzf

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`
if [ "$initrdfs" = "initramfs" ]; then
    RCFILE=$MNTIMAGE/init
else
    RCFILE=$MNTIMAGE/linuxrc
fi
# 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/proc
mkdir -p $MNTIMAGE/sys
mkdir -p $MNTIMAGE/sysroot
ln -s bin $MNTIMAGE/sbin

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

inst /sbin/nash "$MNTIMAGE/bin/nash"
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
for i in 1 2 3 4; do
    mknod $MNTIMAGE/dev/tty$i c 4 $i
done
mkdir $MNTIMAGE/dev/pts
mkdir $MNTIMAGE/dev/shm

if [ -n "$debug_busybox" ]; then
    mkdir -p $MNTIMAGE/usr/bin
    inst /usr/bin/busybox $MNTIMAGE/usr/bin/busybox
    for i in `/usr/bin/busybox 2>&1| awk '/functions:/ {f=1;next} f==1 {gsub(",","");print}'`; do
	[ "$i" != "busybox" ] && ln $MNTIMAGE/usr/bin/busybox "$MNTIMAGE/usr/bin/$i"
    done
fi

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

[ "$debug_busybox" = "start" ] && echo "echo run debug shell" >> $RCFILE && echo "/usr/bin/sh" >> $RCFILE

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

    options=$(sed -n -e "s/^options[[:space:]]\+${module_s}[[:space:]]\+//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 and sbp2 to give things
    #        time to settle down before we start looking a block devices
    if [ "$module_s" = "usb-storage" ] || [ "$module_s" = "sbp2" ]; then
	echo "sleep 8" >> $RCFILE
    fi
done

[ "$debug_busybox" = "modload" ] && echo "echo run debug shell" >> $RCFILE && echo "/usr/bin/sh" >> $RCFILE

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

echo "echo Creating device files" >> $RCFILE
[ -n "$readonly" -o -n "$USE_UDEV" ] && echo "mountdev size=32M,mode=0755" >> $RCFILE
echo "mkdevices /dev" >> $RCFILE
if [ -z "$readonly" ]; then
    _partitions=`cat /proc/partitions | wc -l`
    NB_INODES=$[NB_INODES + $_partitions * 3 ]
fi

if [ -n "$fatxloop" ]; then
    echo "echo Mount fatx host filesystem to find root filesystem (Xbox)" >> $RCFILE
    echo "mkdir -p /fatx" >> $RCFILE
    echo "mount -t fatx /dev/hda50 /fatx" >> $RCFILE
fi

if [ -n "$need_dmnod" ]; then
	echo "echo Making device-mapper control node" >> $RCFILE
	echo "mkdmnod" >> $RCFILE
fi
if [ -n "$root_dmraid" ]; then
    inst /sbin/dmraid-static $MNTIMAGE/sbin/dmraid
    echo "echo Activating device-mapper raid devices" >> $RCFILE
    echo "dmraid -ay -i" >> $RCFILE
    rootdev=$fstabrootdev
fi

if [ -n "$raiddevices" ]; then
    echo "echo Activating md devices" >> $RCFILE
    if [ -z "$noresume" -o -z "$noresume2" ]; then
	if [ ! -x /sbin/mdadm ]; then
	    echo "WARNING: resume disabled if booting from md and mdadm is not available" >&2
	    noresume=1
	    noresume2=1
	else
	    echo "echo 1 > /sys/module/md_mod/parameters/start_ro" >> $RCFILE
	fi
    fi
    [ -x /sbin/mdadm ] && echo "DEVICE partitions" >| $MNTIMAGE/etc/mdadm.conf
    for dev in $raiddevices; do
	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
	if [ -x /sbin/mdadm ]; then
	    /sbin/mdadm -D -b $dev | grep '^ARRAY' >> $MNTIMAGE/etc/mdadm.conf
    	fi
    done
    if [ -x /sbin/mdassemble ]; then
	inst /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
    loopDev_major=$((0x$(stat -L -c '%t' $loopDev)))
    loopDev_minor=$((0x$(stat -L -c '%T' $loopDev)))
    mkdir -p $MNTIMAGE/loopfs

    echo "echo Mounting device containing loopback root filesystem" >> $RCFILE
    echo "mknod $loopDev b $loopDev_major $loopDev_minor"
    echo "mount -t $loopFs $loopDev /loopfs" >> $RCFILE
    echo "echo Setting up loopback device on $loopFile" >> $RCFILE
    echo "mknod /dev/loop7 b 7 7"
    echo "losetup /dev/loop7 /loopfs$loopFile" >> $RCFILE
    rootdev=/dev/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 $MNTIMAGE/etc/lvm/backup
	mkdir -p $MNTIMAGE/var/lock/lvm

	echo "devices {" >| $MNTIMAGE/etc/lvm/lvm.conf
	echo " dir = \"/dev\"" >> $MNTIMAGE/etc/lvm/lvm.conf
	grep "^[[:space:]]*\(scan\|filter\|types\|md_component_detection\)" /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 "backup {" >> $MNTIMAGE/etc/lvm/lvm.conf
	echo " backup = 0" >> $MNTIMAGE/etc/lvm/lvm.conf
	echo " archive = 0" >> $MNTIMAGE/etc/lvm/lvm.conf
	echo "}" >> $MNTIMAGE/etc/lvm/lvm.conf

	echo "echo Scanning logical volumes" >> $RCFILE
	echo "vgscan -P --ignorelockingfailure" >> $RCFILE
	echo "echo Activating logical volumes" >> $RCFILE
	echo "vgchange -P -ay --ignorelockingfailure ${rootvg}" >> $RCFILE
	echo "echo Making device nodes" >> $RCFILE
	echo "vgmknodes --ignorelockingfailure" >> $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 ${rootvg}" >> $RCFILE
	echo "umount /etc" >> $RCFILE
    fi
    rootdev=$fstabrootdev
elif [ -n "$root_evms" ]; then
    evms_version=`/sbin/evms_query info|awk '$2 == "Version:" {print $3}'`
    [ -d /lib64/evms/$evms_version ] && _lib=lib64 || _lib=lib
    mkdir -p $MNTIMAGE/${_lib}/evms/$evms_version
    for foo in $evms_plugins; do
	inst /${_lib}/evms/$evms_version/${foo}-*.so $MNTIMAGE/${_lib}/evms/$evms_version/
    done
    inst /sbin/evms_activate $MNTIMAGE/sbin
    # FIXME evms requires this library
    inst /${_lib}/libgcc_s.so.1 $MNTIMAGE/lib
    cp /etc/evms.conf $MNTIMAGE/etc
    echo "echo Activating EVMS Volumes" >> $RCFILE
    echo "evms_activate" >> $RCFILE
    rootdev=$fstabrootdev
else
    echo "echo Creating root device" >> $RCFILE
    echo "mkrootdev /dev/root" >> $RCFILE
    rootdev=/dev/root
fi

if [ -z "$noresume" ]; then
    if [ -x /usr/sbin/resume ]; then
	inst /usr/sbin/resume $MNTIMAGE/bin
	cp /etc/suspend.conf $MNTIMAGE/etc
    fi
    echo "resume" >> $RCFILE
fi
[[ -z "$noresume2" ]] && echo "echo 1 > /sys/power/suspend2/do_resume" >> $RCFILE

if [ -z "$noresume" -o -z "$noresume2" ] && [ -n "$raiddevices" ]; then
    echo "echo 0 > /sys/module/md_mod/parameters/start_ro" >> $RCFILE
    if [ -x /sbin/mdassemble ]; then
	echo "mdassemble" >> $RCFILE
    else
	for dev in $raiddevices; do
	    echo "mdadm --readwrite $dev" >> $RCFILE
        done
    fi
fi

if [ -n "$fatxloop" ]; then
    echo "echo Run losetup since root device is mounted on loopback (Xbox)" >> $RCFILE
    echo "losetup /dev/root /fatx/mandriva/rootfs" >> $RCFILE
fi

[ "$debug_busybox" = "pivot" ] && echo "echo run debug shell" >> $RCFILE && echo "/usr/bin/sh" >> $RCFILE

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

    if [ -n "$kernel25" -a "$initrdfs" = "initramfs" ]; then
	echo "echo Switching to new root" >> $RCFILE
	if [ -n "$USE_UDEV" ]; then
	    echo "switchroot --movedev /sysroot" >> $RCFILE
	else
	    echo "switchroot /sysroot" >> $RCFILE
	fi
    else	
	echo "echo 0x0100 > /proc/sys/kernel/real-root-dev" >> $RCFILE
	echo "pivot_root /sysroot /sysroot/initrd" >> $RCFILE
	[ -n "$kernel25" ] && echo "umount /initrd/sys" >> $RCFILE
	echo "umount /initrd/proc" >> $RCFILE
    fi
else
    [ -n "$readonly" ] && echo "umount /dev" >> $RCFILE
    [ -n "$kernel25" ] && echo "umount /sys" >> $RCFILE
    echo "umount /proc" >> $RCFILE
fi

[ "$debug_busybox" = "exit" ] && echo "echo run debug shell" >> $RCFILE && echo "/usr/bin/sh" >> $RCFILE

echo "echo Initrd finished" >> $RCFILE

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
		tune2fs -i0 $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"
	;;
    initramfs)
	if [[ -n "$dsdt_files" ]]; then
		for dsdt_file in $dsdt_files; do
			if [[ -f $dsdt_file ]]; then
				cp -aL $dsdt_file $MNTIMAGE/DSDT.aml
			fi
		done
		dsdt_files=""
	fi
	(cd $MNTIMAGE; find . | cpio --quiet -c -o) >| $IMAGE || exit 1
	;;
esac

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

if [[ -n "$dsdt_files" ]]; then
   for dsdt_file in $dsdt_files; do
      if [[ -f $dsdt_file ]]; then
	 echo -n "INITRDDSDT123DSDT123" >> $target
	 cat "$dsdt_file" >> $target
	 [ -n "$kernel25" ] && echo -n "INITRDDSDT321DSDT321" >> $target
      fi
   done
fi

exit $rc
