#!/bin/sh

# geninitrd
#
#	by PLD Linux Team
#
# based on mkinitrd from RedHat
#
# TODO:
# - make udev start before insomds
# - make proper use of USE_UDEV - don't copy fules if USE_UDEV is off no!
# - sanitize - one mounting of /proc and /sys at the begining and one umount at the end!
# - chekup and test and ready to go!
#

RCSID='$Id: geninitrd 8385 2007-03-20 11:27:53Z glen $'
R=${RCSID#* * }; VERSION=${R%% *}
PROGRAM=${0##*/}

. /etc/rc.d/init.d/functions
. /etc/geninitrd/functions

COMPRESS="yes"
# INITRDFS is set later (catch obsoleted FS option)
#INITRDFS="rom"
USERAIDSTART="yes"
USEMDADMSTATIC="no"
USEINSMODSTATIC="no"
USE_SUSPEND="yes"
USE_SUSPEND2="yes"
uselvm="no"
usenfs="no"
# it should be safe to remove scsi_mod from here, but I'm not sure...
PRESCSIMODS="-scsi_mod unknown -sd_mod"
PREIDEMODS="-ide-core unknown -ide-detect -ide-disk"
PREIDEMODSOLD="-ide-probe -ide-probe-mod -ide-disk"
target=""
kernel=""
force=""
verbose=""
MODULES=""
img_vers=""
modulefile=""
fstab="/etc/fstab"
insmod="insmod"
modext=".o"
rootdev_nr=0
# device node for rootfs from fstab
rootdev=""
# default bootsplash is off, if it have to be on, install bootsplash package
BOOT_SPLASH=no
# default same as bootsplash, if on install splashutils and some splashutils theme
FB_SPLASH=no
# defualt we don't use udev to make nodes for static modules, as per default
# PLD loads the modules needed to mount and boot
PROBESTATICMODULES=no

# is /dev on tmpfs. internal variable
tmpfs_dev=

if [ -f /etc/udev/udev.conf -a -x /sbin/initrd-udevd ]; then
	USE_UDEV="yes"
	. /etc/udev/udev.conf
fi

if [ -x /sbin/dmraid-initrd ]; then
	USE_DMRAID="yes"
fi

usage () {
	self=$(basename "$0")
	uname_r=$(uname -r)
	echo "usage: $self [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
	echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
	echo "       [--initrdfs=rom|ext2|cram] [--modules-conf=<modules.conf>]"
	echo "       [--with-raidstart] [--without-raidstart] [--with-insmod-static]"
	echo "       [--without-bootsplash] [--without-fbsplash]"
	echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
	echo "       [--without-suspend] [--without-suspend2] [--without-dmraid]"
	echo "       <initrd-image> <kernel-version>"
	echo ""
	echo "example:"
	echo "  $self -f --initrdfs=rom /boot/initrd-$uname_r.gz $uname_r"
	exit 1
}

debug() {
	[ -n "$verbose" ] && echo "$*"
}

find_depmod () {
	typeset mods module f level depfile first

	depfile=/lib/modules/$kernel/modules.dep

	if [ -f $depfile ] ; then
		: ok
	else
		echo >&2 "Error: no $depfile ! Run depmod and rerun geninitrd."
		exit 1
	fi

	# prepend / if no path given, append $modext.gz if not given,
	# quote /
	origmodule="$2"
	module=$(echo "$2" | \
		awk '/\// {print;next} {print "/" $0}' | \
		awk '/\./ {print;next} {print $0 "'$modext'.gz"}' |
		awk '{gsub("/","\\/");print}')
	mods=$(awk '
BEGIN { here = 0 }
/'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
/:/ { here = 0 }
/(.*)/ { gsub(/\\/," "); if (here) print }
' $depfile | xargs)

	# fallback to $modext
	if [ "$mods" = "" ] ; then
		module=$(echo "$module" | \
		awk '{gsub("\'$modext'\.gz$","\'$modext'",$0);print}')
	fi
	mods=$(awk '
BEGIN { here = 0 }
/'"$module"':(.*)/ { gsub(/:/," "); gsub(/\\/," "); print; here = 1; next }
/:/ { here = 0 }
/(.*)/ { gsub(/\\/," "); if (here) print }
' $depfile | xargs)

	if [ "$mods" = "" ] ; then
		if [ "$1" != silent ] ; then
			echo >&2 "$origmodule: module not found in $depfile"
		fi
		if ! is_no "$EXIT_IF_MISSING" ; then
			exit 1
		else
			echo >&2 "If $origmodule isn't compiled in kernel then this initrd may not start your system."
		fi
	fi

	level=$3
	if [ "$level" = "" ] ; then
		level=0
	fi
	level=$((level + 1))
	if [ $level -gt 20 ] ; then
		echo >&2 "$origmodule: cycle in $depfile"
		exit 1
	fi

	first=
	for f in $mods ; do
		if [ "$first" = "" ] ; then
			first=$f
		else
			find_depmod $1 $f $level
		fi
	done

	echo $first
}

addmodule() {
	fmPath=$1
	skiperrors=$2

	if [ ! -f "/lib/modules/$kernel/$fmPath" ]; then
		if [ -n "$skiperrors" ]; then
			return
		fi

		echo >&2 "module $fmPath present in modules.dep, but not in filesystem (kernel = $kernel)"
		exit 1
	fi

	# only need to add each module once
	# quote /
	tmpFmPath=$(echo $fmPath | awk '{gsub(/\//,"\\/");print}')
	if echo "$MODULES" | awk '/'"$tmpFmPath"'/ {exit 1}' ; then
		MODULES="$MODULES $fmPath"
	fi
}

findmodule() {
	skiperrors=""
	modName=$1

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

	# what's that?
	if [ "$modName" = "pluto" ]; then
		findmodule fc4
		findmodule soc
	fi
	if [ "$modName" = "fcal" ]; then
		findmodule fc4
		findmodule socal
	fi

	if [ -n "$skiperrors" ]; then
		allModulesToFind=$(find_depmod silent $modName)
	else
		allModulesToFind=$(find_depmod normal $modName)
		if [ $? != 0 ]; then
			exit 1
		fi
	fi

	for mod in $allModulesToFind; do
		mod=$(echo $mod | awk '{sub(/^\/lib\/modules\/[^\/]*\//, ""); print}')
		addmodule $mod "$skiperrors"
	done
}

inst() {
	if [ "$#" != "2" ];then
		echo "usage: inst <file> <destination>"
		return
	fi
	debug "$1 -> $2"
	cp "$1" "$2"
}

find_modules_softraid() {
	if [ -f /etc/mdadm.conf ]; then
		debug "Finding RAID details using mdadm for rootdev=$1"
		eval `/sbin/mdadm -v --examine --scan --config=/etc/mdadm.conf | awk -v rootdev="$1" '
		BEGIN {
			found = "no";
			dev_list = "";
			raidlevel = ""
			rootdev_devfs = rootdev;
			if (rootdev ~ /\/dev\/md\/[0-9]/) {
				gsub(/\/dev\/md\//,"/dev/md",rootdev_devfs);
			}
		}

		/^ARRAY/ {
			if (($2 == rootdev) || ($2 == rootdev_devfs)) {
				raidlevel=$3;
				gsub(/level=/,NUL,raidlevel);
				if (raidlevel ~ /^raid([0-6]|10)/) {
					gsub(/raid/,NUL,raidlevel);
				};
				found="yes";
				getline x;
				if (x ~ /devices=/) {
					dev_list = x;
					gsub(".*devices=", NUL, dev_list);
					gsub(",", " ", dev_list);
				}
			}
		}

		END {
			print "raidfound=" found;
			print "raidlevel=" raidlevel;
			print "dev_list=\"" dev_list "\"";
		}'`
	fi

	if [ "$raidfound" != "yes" -a -f /etc/raidtab ]; then
		echo >&2 "ERROR: raidtools are not longer supported. Please migrate to mdadm setup!"
		exit 1
	fi

	if is_yes "$raidfound" ; then
		case "$raidlevel" in
		[01456]|10)
			findmodule "raid$raidlevel"
			;;
		linear)
			findmodule "linear"
			;;
		*)
			echo >&2 "raid level $number (in mdadm config) not recognized"
			;;
		esac
	else
		echo >&2 "ERROR: RAID devices not found for \"$1\", check your configuration!"
		exit 1
	fi

	rootdev_nr=$(( $rootdev_nr + 1 ))
	eval "rootdev${rootdev_nr}=\"$1\""
	eval "dev_list${rootdev_nr}=\"${dev_list}\""

	for device in $dev_list; do
		find_modules_for $device
	done
}

find_modules_scsi() {
	for n in $PRESCSIMODS; do
		if [ "X$n" = "Xunknown" ] ; then
			if [ -f "$modulefile" ]; then
				scsimodules="`awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
				for n in $scsimodules; do
			# for now allow scsi modules to come from anywhere. There are some
			# RAID controllers with drivers in block
					findmodule "$n"
				done
			fi
		else
			findmodule "$n"
		fi
	done
	findmodule "-scsi_wait_scan"
}

find_modules_ide() {
	local rootblkdev

	# set blockdev for rootfs (hda, sdc, ...)
	rootblkdev="$(echo "$1" | awk ' { gsub(/\/dev\//,NUL); gsub(/[0-9].*/, NUL); print $0 } ')"

	if [ "$pack_version_long" -lt "002004021" ]; then
		debug "Finding IDE modules for kernels <= 2.4.20"
		for n in $PREIDEMODSOLD; do
			findmodule "$n"
		done
	else
		tryauto=1
		for n in $PREIDEMODS; do
			if [ "X$n" = "Xunknown" ] ; then
				if [ -f "$modulefile" ]; then
					debug "Finding IDE modules using ide_hostadapter"
					idemodules="`awk '/ide_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
					for na in $idemodules; do
						tryauto=0;
						findmodule "$na"
					done
				fi

				if [ "$tryauto" -eq 1 ]; then
					# If tryauto {{{
					if [ -r /usr/share/pci-database/ide.pci -a -r /proc/bus/pci/devices ]; then
						debug "Finding IDE modules using PCI ID database"
						# Finding IDE modules using PCI ID database {{{
						if is_yes "${ide_only_root}"; then
							if [ -f /sys/block/${rootblkdev}/device/../../vendor -a -f /sys/block/${rootblkdev}/device/../../device ]; then
								vendorid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootblkdev}/device/../../vendor)"
								deviceid="$(awk ' { gsub(/0x/,NUL); print $0 } ' /sys/block/${rootblkdev}/device/../../device)"
								searchpciid="${vendorid}${deviceid}"
							elif [ -f /proc/ide/${rootblkdev}/../config ]; then
								searchpciid="$(awk ' /pci bus/ { print $7$9 } ' /proc/ide/${rootblkdev}/../config)"
							fi
						fi

						if [ -z "${searchpciid}" ]; then
							searchpciid="$(awk ' { print $2 } ' /proc/bus/pci/devices)"
						fi

						idemodules=""

						for nb in $searchpciid; do
							eval `awk -v pciid="$nb" '{
								gsub("\t"," ");
								gsub("  +", " ");
								gsub("^ ","");
								if (/^[\t ]*#/)
									next;
								compmod = $1 "";	# make sure comparison type will be string
											# cause pci IDs are hexadecimal numeric
								if (compmod == pciid) {
									module=$2;
							#		min_kernel=$3;  # now in ide.pci $3,$4 = vendor and device name
							#		max_kernel=$4;  #
									exit 0;
								}
							}

							END {
								print "module=" module "\nmin_kernel=" min_kernel "\nmax_kernel=\"" max_kernel "\"\n";
							}' /usr/share/pci-database/ide.pci`
							[ -n "$module" ] && idemodules="$idemodules $module"
						done
						if is_yes "$(awk ' /ide=reverse/ { print "yes" } ' /proc/cmdline)"; then
							new_idemodules=""
							for nc in idemodules; do
								new_idemodules="$nc $new_idemodules"
							done
							idemodules="${new_idemodules}"
						fi

						if [ -z "$idemodules" ]; then
							echo "WARNING: rootfs on IDE device but no related modules found, loading ide-generic."
							idemodules="ide-generic"
						fi

						# }}}
						for nd in $idemodules; do
							findmodule "-$nd"
						done
					# }}}
					# else tryauto {{{
					else
						[ -r /usr/share/pci-database/ide.pci ] || echo "WARNING: /usr/share/pci-database/ide.pci missing."
						[ -r /proc/bus/pci/devices ] || echo "WARNING: /proc/bus/pci/devices missing."
						echo "Automatic IDE modules finding not available."
					fi
					# }}}
				fi
			else
				findmodule "$n"
			fi
		done
	fi
}

# return true if node is lvm node
_check_lvm() {
	local node="$1"
	if [ ! -e "$node" ]; then
		echo >&2 "WARNING: check_lvm(): node $node doesn't exist!"
		return 1
	fi

	# block-major-58 is lvm1
	ls -lL "$node" 2> /dev/null | awk '{if (/^b/) { if ($5 == "58,") { exit 0; } else { exit 1; } } else { exit 1; }}'
	rc=$?

	if [ $rc = 0 ]; then
		debug "$node is LVM1 node"
		# is lvm1
		return 0
	fi

	/sbin/lvm lvdisplay "$node" > /dev/null 2>&1
	rc=$?
	if [ $rc -gt 127 ]; then
		# lvdisplay terminated by signal! most likely it segfaulted.
		echo >&2 "ERROR: Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
		exit 1
	fi

	if [ $rc = 0 ]; then
		debug "$node is lvm2 node"
	else
		debug "$node is not any lvm node"
	fi
	return $rc
}

find_modules_for() {
	if [ -z "$1" ]; then
		echo "ERROR: no argument passed to find_modules_for() - is your /etc/fstab correct?" >&2
		exit
	fi

	if is_yes "`echo "$1" | awk '/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:|\/dev\/nfs)/ { print "yes"; }'`"; then
		if [ ! -x /usr/bin/pcidev -a -z "$NFS_ETH_MODULES" ] ; then
			echo "ERROR: root on NFS but /usr/bin/pcidev not found." >&2
			echo "Please install correct pci-database package and rerun $0." >&2
			exit 1
		fi
		[ -z "$NFS_ETH_MODULES" ] && NFS_ETH_MODULES=$(/usr/bin/pcidev /m net | xargs)
		for m in $NFS_ETH_MODULES; do
			findmodule "$m"
		done
		findmodule "-ipv4"
		findmodule "nfs"
		usenfs="yes"
		echo "Remember to use \`root=/dev/ram0 init=/linuxrc' when starting kernel" >&2
		echo "or you will have problems like init(xx) being child process of swapper(1)." >&2
	elif is_yes "`echo "$1" | awk '/^\/dev\/md/ { print "yes"; }'`"; then
		find_modules_softraid "$1"
	elif is_yes "$(echo "$1" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')" ; then
		find_modules_scsi
	elif is_yes "`echo "$1" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }'`" ; then
		find_modules_ide "$1"
	elif is_yes "`echo "$1" | awk '/\/dev\/rd\// { print "yes"; }'`" ; then
		findmodule "DAC960"
	elif is_yes "`echo "$1" | awk '/\/dev\/ida\// { print "yes"; }'`" ; then
		findmodule "cpqarray"
	elif is_yes "`echo "$1" | awk '/\/dev\/cciss\// { print "yes"; }'`" ; then
		findmodule "cciss"
	elif is_yes "`echo "$1" | awk '/\/dev\/ataraid\// { print "yes"; }'`"; then
		find_modules_ide
		findmodule "ataraid"
		ataraidmodules="`awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }' $modulefile`"
		if -n "$ataraidmodules" ; then
			# FIXME: think about modules compiled in kernel
			echo "ERROR: ataraid_hostadapter alias not defined in $modulefile !"
			echo "Please set it and run $0 again."
			exit 1
		fi
		for n in $ataraidmodules; do
			findmodule "$n"
		done
	# check to see if we need to set up a loopback filesystem
	elif is_yes "`echo "$1" | awk -F/ '{print($3);}' | awk '/loop/ { print "yes"; }'`" ; then
		echo >&2 "Sorry, root on loop device isn't supported."
		exit 1
		# TODO: rewrite for bsp and make nfs ready
		if [ ! -x /sbin/losetup ]; then
			echo "losetup is missing"
			exit 1
		fi
		key="^# $(echo $1 | awk -F/ '{print($3);}' | tr '[a-z]' '[A-Z]'):"
		if ! is_yes "`awk '/'$key'/ { print( "yes"); }' $fstab`" ; then
			echo >&2 "The root filesystem is on a $1, but there is no magic entry in $fstab"
			echo >&2 "for this device. Consult the geninitrd man page for more information"
			exit 1
		fi

		line="`awk '/'$key'/ { print $0; }' $fstab`"
		loopDev="$(echo $line | awk '{print $3}')"
		loopFs="$(echo $line | awk '{print $4}')"
		loopFile="$(echo $line | awk '{print $5}')"

		BASICMODULES="$BASICMODULES -loop"
		findmodule "-$loopFs"
		BASICMODULES="$BASICMODULES -${loopFs}"
	elif _check_lvm "$1"; then
		node="$1"

		if [ ! -f /sbin/initrd-lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ] ; then
			echo "ERROR: root on LVM but /sbin/initrd-lvm, /sbin/lvdisplay and /sbin/pvdisplay not found." >&2
			echo "Please install lvm(2) and lvm(2)-initrd package and rerun $0." >&2
			exit 1
		fi
		if [ -z "$LVMTOOLSVERSION" ] ; then
			LVMTOOLSVERSION=$(/sbin/initrd-lvm vgchange --version 2>/dev/null|head -n 1|awk '{gsub("vgchange: Logical Volume Manager ",NIL); gsub("LVM version:     ",NIL); gsub(/\..*/,NIL); print $1}')
			if [ -z "$LVMTOOLSVERSION" ] ; then
				echo "ERROR: Can't determine LVM tools version. Please set LVMTOOLSVERSION" >&2
				echo "and rerun $0." >&2
				exit 1
			fi
		fi
		if [ -z "$PVDEVICES" ] ; then
			VGVOLUME=$(/sbin/lvdisplay -c "$node" 2> /dev/null | awk -F":" ' { print $2 } ')
			PVDEVICES=$(/sbin/pvdisplay -c 2>/dev/null | awk -F":" -v vg="$VGVOLUME" ' BEGIN { devices="" } { if ($2 == vg) { devices = devices " " $1 } } END { print devices } ')
		fi
		if [ -n "$PVDEVICES" ] ; then
			for device in $PVDEVICES; do
				find_modules_for $device
			done
		else
			echo "ERROR: I wasn't able to find PV (via lvdisplay and pvdisplay)." >&2
			echo "You can try to set PVDEVICES in /etc/sysconfig/geninitrd." >&2
			exit 1
		fi
		if [ "$LVMTOOLSVERSION" = "2" ]; then
			findmodule "-dm-mod"
		elif [ "$LVMTOOLSVERSION" = "1" ]; then
			findmodule "-lvm"
			findmodule "-lvm-mod"
		else
			echo "ERROR: LVM version $LVMTOOLSVERSION is not supported yet." >&2
			exit 1
		fi
		debug "LVM $LVMTOOLSVERSION enabled"
		uselvm="yes"
	fi
}

firmware_install_module_pre() {
	module="$1"
	linuxrc="$2"
	firmware_files="$3"

	debug "Adding Firmwares ($firmware_files) to initrd for module $module"
	mkdir -p $MNTIMAGE/proc
	mkdir -p $MNTIMAGE/sys
	# firmware not yet installed
	if [ ! -f "$MNTIMAGE/lib/firmware/firmware.sh" ]; then
		mkdir -p $MNTIMAGE/lib/firmware
cat << 'EOF' >> "$MNTIMAGE/lib/firmware/firmware.sh"
#!/bin/sh -e
echo 1 > /sys$DEVPATH/loading
cat "/lib/firmware/$FIRMWARE" > /sys$DEVPATH/data
echo 0 > /sys$DEVPATH/loading
exit 0
EOF
	 	chmod 755 "$MNTIMAGE/lib/firmware/firmware.sh"
	fi

	for firmware in $firmware_files; do
		inst "/lib/firmware/$firmware" "$MNTIMAGE/lib/firmware/$firmware"
	done

	echo "mount -t proc none /proc" >> "$linuxrc"
	echo "mount -t sysfs none /sys" >> "$linuxrc"
	echo "echo -n "/lib/firmware/firmware.sh" > /proc/sys/kernel/hotplug" >> "$linuxrc"
}

firmware_install_module_post() {
	module="$1"
	linuxrc="$2"
	firmware_files="$3"
	echo "umount /sys" >> "$linuxrc"
	echo "umount /proc" >> "$linuxrc"
}

modules_install() {
	modules="$1"

	for mod in $modules; do
		MODULEDIR="`dirname "$mod"`"
		mkdir -p "$MNTIMAGE/lib/modules/$kernel/$MODULEDIR"
		cp -a "/lib/modules/$kernel/$mod" "$MNTIMAGE/lib/modules/$kernel/$mod"
		gunzip "$MNTIMAGE/lib/modules/$kernel/$mod" 2> /dev/null
	done
}

modules_add_linuxrc() {
	modules="$1"
	linuxrc="$2"

	for mod in $modules; do
		MODULE2="`dirname "$mod"`"
		NAME2=`basename "$mod" .gz`
		MODULE2=$MODULE2/$NAME2
		module="`echo $mod | awk -F/ '{ $0=$NF } /'$modext'.*$/ { gsub(/'$modext'.*/, NIL, $0); } { print $0; }'`"
		options="`awk '{ if($1 == "options" && $2 == "'${module}'") { for(i=3;i<=NF;i++) printf("%s ",$i); }}' "$modulefile"`"

		generic_module=$(echo "${module}" | awk ' { gsub("-", "_", $0) } { print $0; } ')
		sleep_var="$(eval echo \$MODULE_${generic_module}_USLEEP)"
		firmware_var="$(eval echo \$MODULE_${generic_module}_FIRMWARE)"

		if [ -n "$verbose" ]; then
			echo -n "Loading module [$module] "
			if [ -n "$options" ] ; then
				echo -n "with options [$options]"
			else
				echo -n "without options"
			fi
			if [ -n "$sleep_var" ]; then
				echo " and $sleep_var usleep."
			else
				echo "."
			fi
		fi

		if [ -n "$firmware_var" ]; then
			firmware_install_module_pre "$module" "$linuxrc" "$firmware_var"
		fi
		echo "$insmod /lib/modules/$kernel/$MODULE2 $options" >> "$linuxrc"
		if [ -n "${sleep_var}" ]; then
			echo "usleep $sleep_var" >> "$linuxrc"
		fi
		if [ -n "$firmware_var" ]; then
			firmware_install_module_post "$module" "$linuxrc" "$firmware_var"
		fi
	done
}

if [ -r /etc/sysconfig/geninitrd ] ; then
	. /etc/sysconfig/geninitrd
fi

if [ -r /etc/sysconfig/bootsplash ] ; then
	. /etc/sysconfig/bootsplash
fi

if [ -r /etc/sysconfig/fbsplash ] ; then
	. /etc/sysconfig/fbsplash
fi

if [ ! -x /bin/initrd-busybox ] ; then
	echo "/bin/initrd-busybox is missing !"
	exit 1
fi

while [ $# -gt 0 ]; do
	case $1 in
	--fstab=*)
		fstab="`echo $1 | awk -F= '{print $2;}'`"
		;;
	--fstab)
		fstab="$2"
		shift
		;;
	--modules-conf=*)
		modulefile="`echo $1 | awk -F= '{print $2;}'`"
		;;
	--modules-conf)
		modulefile="$2"
		shift
		;;
	--use-raidstart|--with-raidstart)
		USERAIDSTART="yes"
		;;
	--without-raidstart)
		USERAIDSTART="no"
		;;
	--use-insmod-static|--with-insmod-static)
		USEINSMODSTATIC="yes"
		;;
	--without-insmod-static)
		USEINSMODSTATIC="no"
		;;
	--without-bootsplash)
		BOOT_SPLASH="no"
		;;
	--without-fbsplash)
		FB_SPLASH="no"
		;;
	--without-suspend)
		USE_SUSPEND="no";
		;;
	--without-suspend2)
		USE_SUSPEND2="no";
		;;
	--lvmtoolsversion=|--lvmversion=)
		LVMTOOLSVERSION="`echo $1 | awk -F= '{print $2;}'`"
		;;
	--lvmtoolsversion|--lvmversion)
		LVMTOOLSVERSION="$2"
		shift
		;;
	--without-udev)
		USE_UDEV=
		;;
	--with-udev)
		USE_UDEV="yes"
		;;
	--without-dmraid)
		USE_DMRAID=
		;;
	--with=*)
		BASICMODULES="$BASICMODULES `echo $1 | awk -F= '{print $2;}'`"
		;;
	--with)
		BASICMODULES="$BASICMODULES $2"
		shift
		;;
	--version)
		echo "geninitrd: version $VERSION"
		exit 0
		;;
	-v)
		verbose=-v
		;;
	--nocompress)
		COMPRESS="no"
		;;
	--ifneeded)
		ifneeded=1
		;;
	-f)
		force=1
		;;
	--preload=*)
		PREMODS="$PREMODS `echo $1 | awk -F= '{print $2;}'`"
		;;
	--preload)
		PREMODS="$PREMODS $2"
		shift
		;;
	--fs=*)
		echo >&2 "Warning: --fs option is obsoleted. Use --initrdfs instead"
		INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
		;;
	--fs)
		echo >&2 "Warning: --fs option is obsoleted. Use --initrdfs instead"
		INITRDFS="$2"
		shift
		;;
	--initrdfs=*)
		INITRDFS="`echo $1 | awk -F= '{print $2;}'`"
		;;
	--initrdfs)
		INITRDFS="$2"
		shift
		;;
	--image-version)
		img_vers=yes
		;;
	--ide-only-root)
		ide_only_root="yes"
		;;
	*)
		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

pack_version="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d",$1,$2)}'`"
pack_version_long="`echo "$kernel"|awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}'`"

if [ "x" = "x$INITRDFS" ] ; then
	if [ "x" = "x$FS" ] ; then
		INITRDFS="rom"
	else
		echo >&2 "Warning: FS configuration options is obsoleted. Use INITRDFS instead"
		INITRDFS="$FS"
	fi
fi

if [ "$pack_version" -lt "002006" ] ; then
	USE_UDEV=
	USE_DMRAID=
fi

if [ "$pack_version" -ge "002005" ] ; then
	modext=".ko"
	insmod="insmod"
fi

if is_yes "$USEINSMODSTATIC" ; then
	insmod="insmod.static"
	INSMOD="/sbin/insmod.static"
	if [ "$pack_version" -lt "002005" -a -f /sbin/insmod.static.modutils ] ; then
		INSMOD="/sbin/insmod.static.modutils"
	fi
	if [ ! -f "$INSMOD" ] ; then
		echo "insmod.static requested but /sbin/insmod.static not found !" >&2
		exit 1
	fi
fi

case "$INITRDFS" in
	ext2)
		if [ ! -x /sbin/mke2fs ]; then
			echo >&2 "/sbin/mke2fs is missing"
			exit 1
		fi
		;;
	rom)
		if [ ! -x /sbin/genromfs ]; then
			echo >&2 "/sbin/genromfs is missing"
			exit 1
		fi
		;;
	cram)
		if [ ! -x /sbin/mkcramfs ]; then
			echo >&2 "/sbin/mkcramfs is missing"
			exit 1
		fi
		;;
	initramfs)
		if [ ! -x /bin/cpio ]; then
			echo >&2 "/bin/cpio is missing"
			exit 1
		fi
		if [ ! -x /usr/bin/find ]; then
			echo >&2 "/usr/bin/find is missing"
			exit 1
		fi
		;;
	*)
		echo >&2 "Filesystem $INITRDFS on initrd is not supported"
		exit 1
		;;
esac

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

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

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

if is_yes "$USE_SUSPEND"; then
	if is_yes "$USE_SUSPEND2"; then
		echo >&2 "Suspend2 shouldn't be used in parallel with mainline suspend!."
		exit 1
	fi
fi

if is_yes "$FB_SPLASH"; then
	if is_yes "$BOOT_SPLASH"; then
		echo >&2 "You can't use both bootsplash and fbsplash! Please choose one."
		exit 1
	elif [ "$INITRDFS" != "initramfs" ]; then
		echo >&2 "FB_SPLASH works only if INITRDFS is initramfs!."
		exit 1
	fi
fi

if [ ! -f /proc/mounts ]; then
	echo >&2 "WARNING: /proc filesystem not mounted, may cause wrong results or failure."
fi

if [ "$pack_version" -lt "002005" ]; then
	modulefile=/etc/modules.conf
	if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
		modulefile=/etc/conf.modules
	fi
else
	modulefile=/etc/modprobe.conf
fi

for n in $PREMODS; do
	findmodule "$n"
done

# allow forcing loading SCSI and/or IDE modules
if is_yes "$ADDSCSI" ; then
	find_modules_scsi
fi

if is_yes "$ADDIDE" ; then
	find_modules_ide
fi

find_root "$fstab" || exit
debug "Using $rootdev as device for rootfs"

find_modules_for "$rootdev"

findmodule "-$rootFs"

for n in $BASICMODULES; do
	findmodule "$n"
done

if is_yes "$USE_SUSPEND2"; then
	findmodule "-lzf"
fi

if is_yes "$FB_SPLASH"; then
	findmodule "-evdev"
fi
if [ -n "$ifneeded" -a -z "$MODULES" ]; then
	debug "No modules are needed -- not building initrd image."
	exit 0
fi

debug "Using modules: $MODULES"

MNTIMAGE="`mktemp -d /tmp/initrd.XXXXXX`"
IMAGE="`mktemp -u /tmp/initrd.img-XXXXXX`"
MNTPOINT="`mktemp -d /tmp/initrd.mnt-XXXXXX`"
RCFILE="$MNTIMAGE/linuxrc"

if [ -f "$MNTIMAGE" ]; then
	echo >&2 "$MNTIMAGE already exists. Remove it and try again"
	exit 1
fi

if [ -f "$IMAGE" ]; then
	echo >&2 "$IMAGE already exists. Remove it and try again"
	exit 1
fi

mkdir -p "$MNTPOINT"


mkdir -p "$MNTIMAGE"/{lib,bin,etc,dev,loopfs,var}


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

modules_install "$MODULES"

# 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/zero" c 1 5

s="$RCFILE"
ln -s /linuxrc $MNTIMAGE/init

inst /bin/initrd-busybox "$MNTIMAGE/bin/initrd-busybox"
ln -s initrd-busybox "$MNTIMAGE/bin/sh"
ln -s initrd-busybox "$MNTIMAGE/bin/busybox" # for older busyboxes who had /bin/busybox as EXEPATH

if is_yes "$USEINSMODSTATIC" ; then
	inst "$INSMOD" $MNTIMAGE/bin/insmod.static
fi

cat > "$s" <<'EOF'
#! /bin/sh
mount -t proc none /proc
if [ "$(awk ' /debuginitrd/  { print "yes"; } ' /proc/cmdline)" = "yes" ]; then
	export DEBUG=yes
	set -x
fi
umount /proc
EOF
chmod 755 "$s"

modules_add_linuxrc "$MODULES" "$s"

# TODO: rewrite for busybox
#if [ -n "$loopDev" ]; then
#	if [ ! -d /initrd ]; then
#		mkdir /initrd
#	fi
#
#	cp -a "$loopDev" "$MNTIMAGE/dev"
#	cp -a "$rootdev" "$MNTIMAGE/dev"
#	echo "echo Mounting device containing loopback root filesystem" >> "$RCFILE"
#	echo "mount -t $loopFs $loopDev /loopfs" >> "$RCFILE"
#	echo "echo Setting up loopback device $rootdev" >> $RCFILE
#	echo "losetup $rootdev /loopfs$loopFile" >> "$RCFILE"
#fi

initrd_gen_suspend() {
	if [ ! -x /usr/sbin/resume ]; then
		echo "/usr/sbin/resume is missing !"
		exit 1
	fi
	mkdir -p $MNTIMAGE/etc
	mkdir -p $MNTIMAGE/dev
	resume_dev="$(awk '/^resume device =/ { print $4 } ' /etc/suspend.conf)"
	cp -HR /dev/snapshot $resume_dev $MNTIMAGE/dev
	inst /etc/suspend.conf $MNTIMAGE/etc/suspend.conf
	inst /usr/sbin/resume "$MNTIMAGE/bin/resume"
	echo "resume" >> "$s"
}

initrd_gen_suspend2() {
	mkdir -p $MNTIMAGE/sys
	mkdir -p $MNTIMAGE/proc
cat << 'EOF' >> "$s"
mount -t proc none /proc
mount -t sysfs none /sys
if [ "$(awk ' /resume2=/  { print "yes"; } ' /proc/cmdline)" = "yes" ]; then
EOF
cat << EOF >> "$s"
		[ -e /proc/suspend2/do_resume ] && echo > /proc/suspend2/do_resume
		[ -e /sys/power/suspend2/do_resume ] && echo > /sys/power/suspend2/do_resume
fi
umount /sys
umount /proc
EOF
}

initrd_gen_tmpfs_dev() {
	tmpfs_dev=yes
	cat <<-EOF
: 'Creating /dev'
mount -o mode=0755 -t tmpfs none /dev
mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/zero c 1 5
mkdir /dev/pts
mkdir /dev/shm
EOF
}

initrd_gen_udev() {
	debug "Setting up udev..."
	mkdir -p $MNTIMAGE/sbin
	mkdir -p $MNTIMAGE/proc
	mkdir -p $MNTIMAGE/etc/udev
	mkdir -p $MNTIMAGE/sys

	inst /sbin/initrd-udevd $MNTIMAGE/sbin/udevd
	inst /etc/udev/udev.conf $MNTIMAGE/etc/udev/udev.conf

	if is_yes "$USE_UDEV"; then
		initrd_gen_tmpfs_dev >> "$s"
		cat >> "$s" <<- 'EOF'
			mount -t proc none /proc
			mount -t sysfs none /sys
			: 'Starting udev'
			/sbin/udevd --daemon
			EOF
		if is_yes "$PROBESTATICMODS"; then
			inst /sbin/initrd-udevtrigger $MNTIMAGE/sbin/udevtrigger
			inst /sbin/initrd-udevsettle $MNTIMAGE/sbin/udevsettle
			cat >> "$s" <<- 'EOF'
				/sbin/udevtrigger
				/sbin/udevsettle
				EOF
		fi
		cat >> "$s" <<- 'EOF'
			killall udevd
			umount /proc
			umount /dev
			umount /sys
			EOF
	fi
}

initrd_gen_dmraid() {
	if [ ! -x /sbin/dmraid-initrd ] ; then
		echo "/sbin/dmraid-initrd is missing missing !"
		exit 1
	fi

	# AFAIR it just needs tmpfs on /dev.
	if [ ! -x $MNTIMAGE/sbin/udevd ]; then
		echo "udev is needed on target initrd for dmraid to work!"
		exit 1
	fi

	mkdir -p "$MNTIMAGE/sbin"
	inst /sbin/dmraid-initrd $MNTIMAGE/sbin/dmraid
	cat <<-EOF >> "$s"
	mount -t proc none /proc
	mount -t sysfs none /sys
	# 2 secs was enough for my system to initialize. but really this is udev issue?
	usleep 2000000
	: 'Activating Device-Mapper RAID(s)'
	/sbin/dmraid -ay -i
	umount /sys
	umount /proc
EOF
}


initrd_gen_softraid() {
	debug "Setting up mdadm..."

	if [ ! -x /sbin/mdadm -o ! -x /sbin/initrd-mdassemble ] ; then
		echo "/sbin/mdadm or /sbin/initrd-mdassemble is missing !"
		exit 1
	fi

	inst /sbin/initrd-mdassemble "$MNTIMAGE/bin/mdassemble"

	# LVM on RAID case
	dev_list_extra=$(awk '/^DEVICE / { for (i=2; i<=NF; i++) { printf "%s ", $i; }; } ' /etc/mdadm.conf)
	for ex_dev in $dev_list_extra; do
		echo "DEVICE $ex_dev" >> "$MNTIMAGE/etc/mdadm.conf"
	done
	do_md0=1
	for nr in `seq 1 $rootdev_nr`; do
		eval cr_rootdev="\$rootdev${nr}"
		eval cr_dev_list="\$dev_list${nr}"
		debug echo "Setting up array ($cr_rootdev = $cr_dev_list)"

		[ "$cr_rootdev" = "/dev/md0" ] && do_md0=0

		echo "DEVICE $cr_dev_list" >> "$MNTIMAGE/etc/mdadm.conf"
		cr_dev_list_md="$(echo "$cr_dev_list" | xargs | awk ' { gsub(/ +/,",",$0); print $0; }')"
		cr_md_conf=$(/sbin/mdadm --detail --brief --config=/etc/mdadm.conf $cr_rootdev | awk ' { gsub(/spares=[0-9]+/, "", $0); print $0; }')
		if [ -n "$cr_md_conf" ]; then
			echo "$cr_md_conf" >> "$MNTIMAGE/etc/mdadm.conf"
		else
			echo "ARRAY $cr_rootdev devices=$cr_dev_list_md" >> "$MNTIMAGE/etc/mdadm.conf"
		fi

		for f in $cr_dev_list $cr_rootdev $dev_list_extra; do
			# mkdir in case of devfs name
			mkdir -p $MNTIMAGE/`dirname $f`
			[ -e "$MNTIMAGE/$f" ] && continue
			debug echo "copying $f"
			# this works fine with and without devfs
			cp -HR $f $MNTIMAGE/$f
		done
	done

	echo "mdassemble" >> "$s"

	# needed to determine md-version
	if [ "$do_md0" -eq 1 ] ; then
		mknod $MNTIMAGE/dev/md0 b 9 0
	fi
}

initrd_gen_nfs() {
	# use root=/dev/ram0 init=/linuxrc when starting kernel or you will
	# have problems like init(XX) being child process of swapper(1).
	debug "Adding rootfs on NFS support to initrd (dhcp)"
	mknod "$MNTIMAGE/dev/urandom" c 1 9
	mkdir "$MNTIMAGE/newroot"
	mkdir "$MNTIMAGE/proc"
	echo "ifconfig lo 127.0.0.1 up" >> "$s"
	echo "route add -net 127.0.0.0 netmask 255.0.0.0 lo" >> "$s"
	echo "ifconfig eth0 0.0.0.0 up" >> "$s"
	echo "udhcpc -i eth0 -f -q -s /bin/setdhcp" >> "$s"
	cat << 'EOF' > "$MNTIMAGE/bin/setdhcp"
#!/bin/sh
[ "$1" != "bound" ] && exit
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
[ -n "$subnet" ] && NETMASK="netmask $subnet"
ifconfig $interface $ip $BROADCAST $NETMASK up
if [ -n "$router" ]; then
	for r in $router; do
		route add default gw $r dev $interface
	done
fi

mount -t proc none /proc
for o in $(cat /proc/cmdline); do
	case $o in
	nfsroot=*)
		rootpath=${o#nfsroot=}
		;;
	esac
done
umount /proc

if [ -n "$rootpath" ]; then
	mount -n -t nfs -o ro,nolock,posix,tcp,wsize=8192,rsize=8192 $rootpath /newroot
else
	echo "Missing rootpath in what DHCP server sent to us. Failing..."
	echo "All seen variables are listed below:"
	set
fi
EOF
	chmod 755 "$MNTIMAGE/bin/setdhcp"
	echo "cd /newroot" >> "$s"
	echo "pivot_root . initrd" >> "$s"
	echo "[ -x /sbin/chroot ] && exec /sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1" >> "$s"
	echo "exec /usr/sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1" >> "$s"
}

initrd_gen_lvm() {
	debug "Adding LVM support to initrd"
	inst /sbin/initrd-lvm $MNTIMAGE/bin/lvm
	mkdir -p $MNTIMAGE/etc
	mkdir -p $MNTIMAGE/tmp
	mkdir -p $MNTIMAGE/proc
	mkdir -p $MNTIMAGE/newroot

	# always make /dev on tmpfs for LVM2
	if [ "$LVMTOOLSVERSION" = "2" ] && ! is_yes "$tmpfs_dev"; then
		initrd_gen_tmpfs_dev >> "$s"
	fi

	if ! is_yes "$tmpfs_dev"; then
		mkdir -p $MNTIMAGE/dev/mapper
		mknod $MNTIMAGE/dev/mapper/control c 10 63
		for device in $PVDEVICES; do
			# if LVM on RAID then device might be copied already in gen_softraid
			[ -e "$MNTIMAGE/dev/$(basename $device)" ] && continue
			cp -HR $device $MNTIMAGE/dev/
		done
	fi
	echo "mount -t proc none /proc" >> "$s"
	echo "mount -t tmpfs none /tmp" >> "$s"
	if [ "$LVMTOOLSVERSION" = "1" ] ; then
		echo "lvm vgscan -T" >> "$s"
		echo "lvm vgchange -T -a y $VGVOLUME" >> "$s"
		echo "umount /tmp" >> "$s"
		# fail to umount
		echo "umount /dev" >> "$s"
		echo "umount /proc" >> "$s"
	else
		echo "cat /etc/lvm.conf > /tmp/lvm.conf" >> "$s"
		echo "global {" > "$MNTIMAGE/etc/lvm.conf"
		echo "	locking_type = 0" >> "$MNTIMAGE/etc/lvm.conf"
		echo "	locking_dir = \"/tmp\"" >> "$MNTIMAGE/etc/lvm.conf"
		echo "}" >> "$MNTIMAGE/etc/lvm.conf"
		echo "devices {" >> "$MNTIMAGE/etc/lvm.conf"
		echo "	sysfs_scan=0" >> "$MNTIMAGE/etc/lvm.conf"
		if is_yes "$raidfound"; then
			echo "	md_component_detection = 1" >> "$MNTIMAGE/etc/lvm.conf"
		fi
		lvm dumpconfig | awk '/filter=/' >> "$MNTIMAGE/etc/lvm.conf"
		echo "}" >> "$MNTIMAGE/etc/lvm.conf"

		cat <<-EOF >> "$s"
		: 'Making device nodes'
		set +x
		# ignore first two lines, header, empty line and process rest
		cat /proc/partitions | (read b; read b; while read major minor blocks dev rest; do
			mkdir -p /dev/\$(dirname \$dev)
			mknod /dev/\$dev b \$major \$minor
		done
		)

		# disable noise from lvm accessing devices that aren't ready.
		printk=\$(cat /proc/sys/kernel/printk)
		echo 0 > /proc/sys/kernel/printk

		: 'Scanning for Volume Groups'
		LVM_SYSTEM_DIR=/tmp lvm vgscan --ignorelockingfailure 2>/dev/null

		: 'Activating Volume Groups'
		LVM_SYSTEM_DIR=/tmp lvm vgchange --ignorelockingfailure -a y $VGVOLUME 2>/dev/null

		echo "\$printk" > /proc/sys/kernel/printk

		# Find out major/minor
		majmin="\$(LVM_SYSTEM_DIR=/tmp lvm lvdisplay --ignorelockingfailure -c $rootdev 2>/dev/null)"
		majmin="\${majmin#*/}"
		majmin="\${majmin#*:*:*:*:*:*:*:*:*:*:*:*}"
		major="\${majmin%:*}"
		minor="\${majmin#*:}"
		# Pass it to kernel
		val=\$((256 * \$major + \$minor))
		echo \$val > /proc/sys/kernel/real-root-dev
		umount /tmp
		umount /dev
		umount /proc
EOF
	fi
}

initrd_gen_procdata() {
	debug "Adding rootfs finding based on root= option support."
	mkdir -p $MNTIMAGE/proc
cat << 'EOF' >> "$s"
set +x
mount -t proc none /proc
root="$(busybox awk ' /root=\/dev\// { gsub(/.*root=\/dev\//,NIL,$0); gsub(/ .*/,NIL,$0); print $0; } ' /proc/cmdline)"
if [ -n "$root" ]; then
	rootnr="$(busybox awk -v root="$root" ' { if ($4 == root) { print 256*$1+$2; } } ' /proc/partitions)"
	if [ -n "$rootnr" ]; then
		echo "$rootnr" > /proc/sys/kernel/real-root-dev
	fi
fi
umount /proc
EOF
}

# main generation

if is_yes "$USE_UDEV"; then
	initrd_gen_udev
fi

if is_yes "$USE_SUSPEND"; then
	initrd_gen_suspend
fi

if is_yes "$USE_SUSPEND2"; then
	initrd_gen_suspend2
fi

if is_yes "$USE_DMRAID"; then
	initrd_gen_dmraid
fi

if is_yes "$usenfs" ; then
	initrd_gen_nfs
elif is_yes "$USERAIDSTART" && is_yes "$raidfound" ; then
	initrd_gen_softraid
	if is_yes "$uselvm" ; then
		initrd_gen_lvm
	else
		initrd_gen_procdata
	fi
elif is_yes "$uselvm" ; then
	initrd_gen_lvm
else
	initrd_gen_procdata
fi

if [ "$INITRDFS" = "initramfs" ]; then
	mkdir -p $MNTIMAGE/newroot
	[ ! -e "$MNTIMAGE/$rootdev" ] && cp -HR $rootdev $MNTIMAGE/dev
	# Parsing root parameter
	# We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
	cat << 'EOF' >> "$s"
set +x
mount -t proc none /proc

CMDLINE="$(busybox cat /proc/cmdline)"
eval "$(busybox awk -v c="$CMDLINE" '
BEGIN {
	num_pattern_short = "[0-9][0-9][0-9]";
	num_pattern = "[0-9]" num_pattern_short;
	dev_pattern = "[hms][a-z][a-z]([0-9])+";
	partition = "no_partition_found";
	min = -1; maj = -1;

	gsub(/.*root=/,NIL,c);
	gsub(/ .*/,NIL,c);

	sub("^0x", "", c);
	if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
	if (c ~ "^" num_pattern  "$") {
		maj = sprintf("%d",substr(c,1,2));
		min = sprintf("%d",substr(c,3));
	}
	if (c ~ "^\/dev\/" dev_pattern "$") sub("^/dev/","", c);
	if (c ~ "^" dev_pattern "$") partition = c;
}

$4 ~ partition { maj = $1; min = $2; }
$1 ~ maj && $2 ~ min { partition = $4; }

END {
	print sprintf("device=/dev/%s\nmaj=%d\nmin=%d",
		partition, maj, min);
}
' /proc/partitions)"
if [ ! -b $device ]; then
	mknod $device b $maj $min
fi
EOF
	cat << EOF >> "$s"
mount -t $rootFs -r \$device /newroot
init="\$(busybox awk ' /init=\// { gsub(/.*init=/,NIL,\$0); gsub(/ .*/,NIL,\$0); print \$0; }  ' /proc/cmdline )"
if [ -z "\$init" -o ! -x "/newroot\$init" ]; then
	init=/sbin/init
fi
umount /proc
exec switch_root /newroot \$init

echo "Error ! initramfs should not reach this place."
echo "It probably means you've got old version of busybox, with broken"
echo "initramfs support. Trying to boot anyway, but won't promise anything."

exec chroot /newroot \$init

echo "Failed to chroot !"
EOF
	# we need real file, not symlink
	rm -f $MNTIMAGE/init
	cp -a $MNTIMAGE/linuxrc $MNTIMAGE/init
fi

chmod +x "$RCFILE"

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

case "$INITRDFS" in
	ext2)
		IMAGESIZE=$(du -ks $MNTPOINT | awk '{print int(($1+1023+512)/1024)*1024}')
		debug 	"ext2 image size: $IMAGESIZE ($MNTPOINT)"
		if [ "$IMAGESIZE" -gt 4096 ]; then
			echo >&2 "$0: Your image size is larger than 4096, You should add ramdisk_size=$IMAGESIZE to your kernel commandline!"
		fi

		dd if=/dev/zero of="$IMAGE" bs=1k count="$IMAGESIZE" 2> /dev/null
		mke2fs -q -F -b 1024 -m 0 "$IMAGE" 2>/dev/null 1>&2
		tune2fs -i 0 "$IMAGE" >/dev/null 2>&1

		tmpmnt="`mktemp -d /tmp/initrd.mnte2-XXXXXX`"
		mount -o loop -t ext2 "$IMAGE" "$tmpmnt"

		(cd "$MNTPOINT"; tar cf - .) | (cd "$tmpmnt"; tar xf -)

		umount "$IMAGE"
		;;
	rom)
		genromfs -f "$IMAGE" -d "$MNTPOINT" -V "PLD initrd for kernel $kernel"
		;;
	cram)
		mkcramfs "$MNTPOINT" "$IMAGE"
		;;
	initramfs)
		(cd $MNTPOINT ; find . | cpio -H newc -o > "$IMAGE")
		;;
	*)
		echo "Filesystem $INITRDFS not supported by $0";
esac

if is_yes "$COMPRESS" ; then
	gzip -9 < "$IMAGE" > "$target"
else
	cp -a "$IMAGE" "$target"
fi

if is_yes "$BOOT_SPLASH"; then
	if [ ! -x /bin/splash.bin ]; then
		echo >&2 "Failed to execute /bin/splash.bin. Is bootsplash package installed?"
	elif [ -z "$THEME" ]; then
		echo >&2 "Please configure your /etc/sysconfig/bootsplash first."
		echo >&2 "Generating bootsplashes skipped."
	else
		if [ -n "$BOOT_SPLASH_RESOLUTIONS" ]; then
			for res in $BOOT_SPLASH_RESOLUTIONS; do
				if [ -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" ]; then
					/bin/splash.bin -s -f "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg" >> "$target" && \
					debug "Added $res $THEME theme to initrd."
				else
					echo >&2 "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg doesn't exist, skipped"
				fi
			done
		else
			echo >&2 "No BOOT_SPLASH_RESOLUTIONS specified in /etc/sysconfig/bootsplash."
			echo >&2 "Not adding bootsplash to initrd."
		fi
	fi
fi

if is_yes "$FB_SPLASH"; then
	if [ ! -x /usr/bin/splash_geninitramfs ]; then
		echo >&2 "Failed to execute /usr/bin/splash_geninitramfs. Is splashutils package installed?"
	elif [ -z "$SPLASH_THEME" ]; then
		echo >&2 "Please configure your /etc/sysconfig/fbsplash first."
		echo >&2 "Generating fbsplashes skipped."
	else
		if [ -n "$FB_SPLASH_RESOLUTIONS" ]; then
			for res in $FB_SPLASH_RESOLUTIONS; do
				if [ -f "/etc/splash/$SPLASH_THEME/$res.cfg" ]; then
					/usr/bin/splash_geninitramfs -a $target -r $res $SPLASH_THEME && \
					debug "Added $res $SPLASH_THEME theme to initramfs."
				else
					echo >&2 "/etc/splash/$SPLASH_THEME/$res.cfg doesn't exist, skipped"
				fi
			done
		else
			echo >&2 "No FB_SPLASH_RESOLUTIONS specified in /etc/sysconfig/fbsplash."
			echo >&2 "Not adding fbsplash to initramfs."
		fi
	fi
fi

rm -rf "$MNTIMAGE" "$MNTPOINT" "$IMAGE"

# vim:ts=4:sw=4:noet:fdm=marker
