]> git.pld-linux.org Git - projects/geninitrd.git/blobdiff - geninitrd
Use kernel ready compression settings for xz.
[projects/geninitrd.git] / geninitrd
index ac88d629687e2a113ef931e885ce15a4b05856d0..f08fdd63d1c9b1c999f0ca75ab26df4a634870ec 100755 (executable)
--- a/geninitrd
+++ b/geninitrd
@@ -6,29 +6,18 @@
 #
 # based on mkinitrd from RedHat Linux
 #
-# TODO:
-# - make udev start before insmods
-# - make proper use of USE_UDEV - don't copy rules if USE_UDEV is off no!
-#
 
-RCSID='$Id$'
-R=${RCSID#* * }; VERSION=${R%% *}
+RCSID='$Revision$ $Date$'
+R=${RCSID#* *}; VERSION=${R%% *}
 PROGRAM=${0##*/}
 
 . /etc/rc.d/init.d/functions
-. /etc/geninitrd/functions
+. /lib/geninitrd/functions
 . /etc/sysconfig/system
 
+# list of geninitrd modules which need setup routine after commandline args parsing
+GENINITRD_MODS=""
 COMPRESS=yes
-USERAIDSTART=yes
-USEMDADMSTATIC=no
-USEINSMODSTATIC=no
-USE_SUSPEND=yes
-USE_TUXONICE=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=""
@@ -36,17 +25,10 @@ verbose=""
 MODULES=""
 img_vers=""
 fstab=/etc/fstab
-insmod=insmod
 modext=.o
 rootdev_nr=0
 # device node for rootfs from fstab
 rootdev=""
-# requires bootsplash package to operate
-BOOT_SPLASH=no
-# requires splashutils package to operate
-FB_SPLASH=no
-# requires splashutils package to operate
-FB_CON_DECOR=no
 
 # internal variables
 # is /dev on tmpfs
@@ -61,53 +43,26 @@ tmp_mounted=no
 # are /dev nodes already created from /proc/devices info?
 proc_partitions=no
 
-# LVM devices that should not be included in vgscan on initrd
-lvm_ignore_devices=''
-
-# whether v86d should be installed
-need_v86d=0
-
-# LVM volumes that are needed to activate
-# VG for root dev
-ROOTVG=""
-# VG for suspend resume dev
-SUSPENDVG=""
-
-# resume device
-resume_dev=""
-
-# if we should init NFS at boot
-have_nfs=no
-# if we should init LVM at boot
-have_lvm=no
-# if we should init md (softraid) at boot
-have_md=no
-# if we should init dmraid at boot
-have_dmraid=no
-# if we should init dm-multipath at boot
-have_multipath=no
-# dm-multipath wwid which is used for rootfs
-MPATH_WWID=
-
 usage() {
        uname_r=$(uname -r)
        echo "usage: $PROGRAM [--version] [-v] [-f] [--ifneeded] [--preload <module>]"
        echo "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
+       echo "       [--compress=yes|xz|lzma|bzip2|gzip]"
        echo "       [--initrdfs=rom|initramfs|ext2|cram] [--modules-conf=<modules.conf>]"
-       echo "       [--with-raidstart] [--without-raidstart] [--with-insmod-static]"
        echo "       [--with-bootsplash] [--without-bootsplash]"
        echo "       [--with-fbsplash] [--without-fbsplash]"
        echo "       [--with-fbcondecor] [--without-fbcondecor]"
        echo "       [--lvmtoolsversion=1|2] [--with-udev] [--without-udev]"
        echo "       [--with-suspend] [--without-suspend]"
        echo "       [--with-tuxonice] [--without-tuxonice]"
-       echo "       [--without-dmraid] [--without-multipath]"
-       echo "       [--without-blkid]"
+       echo "       [--without-dmraid]"
+       echo "       [--with-multipath=DEVPATH] [--without-multipath]"
+       echo "       [--without-blkid] [--without-luks]"
        echo "       <initrd-image> <kernel-version>"
        echo ""
        echo "example:"
        echo "  $PROGRAM -f --initrdfs=rom /boot/initrd-$uname_r.gz $uname_r"
-       exit 1
+       exit 0
 }
 
 msg() {
@@ -125,10 +80,49 @@ debug() {
 # aborts program abnormally
 die() {
        local rc=${2:-1}
-       warn "ERROR: $1"
+       msg "ERROR: $1" >&2
        exit $rc
 }
 
+# find program from specified paths
+find_tool() {
+       local x
+       for x in "$@"; do
+               if [ -x "$x" ]; then
+                       echo $x
+                       debug "find_tool: found $x"
+                       return 0
+               fi
+       done
+       debug "find_tool: did not found any of: $@"
+       return 1
+}
+
+# loads geninitrd modules
+geninitrd_load_mods() {
+       local mod
+       for mod in "$@"; do
+               if [ ! -f /lib/geninitrd/mod-$mod.sh ]; then
+                       die "$mod geninitrd module can't be loaded"
+               fi
+               . /lib/geninitrd/mod-$mod.sh
+
+               if type setup_mod_$mod > /dev/null; then
+                       # add to list which need init
+                       GENINITRD_MODS="$GENINITRD_MODS $mod"
+               fi
+       done
+}
+
+# setup geninitrd modules
+geninitrd_setup_mods() {
+       local mod
+
+       for mod in $GENINITRD_MODS; do
+               eval setup_mod_$mod
+       done
+}
+
 # append text to /linuxrc
 # takes STDIN as input
 add_linuxrc() {
@@ -158,6 +152,7 @@ mount_dev() {
                mknod /dev/console c 5 1
                mknod /dev/null c 1 3
                mknod /dev/zero c 1 5
+               mknod /dev/urandom c 1 9
                mkdir /dev/pts
                mkdir /dev/shm
        EOF
@@ -239,15 +234,15 @@ umount_all() {
 #
 # NB! XXX do not output to STDOUT, it will appear in initrd images in some cases!
 busybox_applet() {
-       local err=0
+       local err=0 applet
 
        if [ -z "$busybox_functions" ]; then
-               local tmp=$(/bin/initrd-busybox 2>&1)
+               local tmp=$($busybox 2>&1)
 
                # BusyBox v1.1.3 says applet not found if it's not called 'busybox'.
                if [[ "$tmp" = *applet\ not\ found* ]]; then
                        local t=$(mktemp -d)
-                       ln -s /bin/initrd-busybox $t/busybox
+                       ln -s $busybox $t/busybox
                        local tmp=$($t/busybox 2>&1)
                        rm -rf $t
                fi
@@ -278,72 +273,58 @@ busybox_applet() {
 # Finds module dependencies
 #
 # @param       $module
-# @param       $mode   [silent]
 #
-# Outputs each dependant module full path including the module itself.
+# Outputs full path to module and it's dependencies
 find_depmod() {
        local module="$1"
-       local mode="$2"
+       local skiperrors=0
 
-       # backwards compatible, process $mode
-       local modfile
-       if [ "$mode" = "silent" ]; then
-               modfile=$(modinfo -k $kernel -n $module 2>/dev/null)
-       else
-               modfile=$(modinfo -k $kernel -n $module)
+       # if module is prefixed with dash, we should ignore errors if the module
+       # can't be found.
+       if [ ${module#-} != $module ]; then
+               skiperrors=1
+               module=${module#-}
        fi
-       if [ ! -f "$modfile" ]; then
-               if [ "$mode" != "silent" ]; then
-                       warn "$module: module not found for $kernel kernel"
+
+       # This works when user has module-init-tools installed even on 2.4 kernels
+       local modprobe
+       modprobe=$(modprobe --set-version $kernel --show-depends $module --ignore-install 2>&1)
+
+       if [ $? != 0 ]; then
+               if [ $skiperrors = 1 ]; then
+                       return
                fi
+               echo >&2 "$modprobe"
+
                if ! is_no "$EXIT_IF_MISSING"; then
-                       exit 1
-               else
-                       warn "If $module isn't compiled in kernel then this initrd may not start your system."
+                       die "$module: module not found for $kernel kernel"
                fi
+
+               warn "$module: module not found for $kernel kernel"
+               warn "If $module isn't compiled in kernel then this initrd may not start your system."
        fi
 
-       # This works when user has module-init-tools installed even on 2.4 kernels
-       modprobe --set-version $kernel --show-depends $module | \
+       echo "$modprobe" | \
        while read insmod modpath options; do
-               echo $modpath
+               [ "$insmod" = "insmod" ] && echo $modpath
        done
 }
 
 find_firmware() {
        local module="$1"
-       echo -n $(modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
-}
-
-findmodule() {
-       local skiperrors=""
-       local 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
+       # no firmware support in 2.4 kernels
+       if [ "$kernel_version_long" -lt "002005048" ]; then
+               return
        fi
+       echo -n $(NEW_MODINFO=1 modinfo -k $kernel -F firmware $module 2>/dev/null | xargs)
+}
 
-       local mod depmod
-       if [ "$skiperrors" = 1 ]; then
-               depmod=$(find_depmod $modName silent)
-       else
-               depmod=$(find_depmod $modName)
-               if [ $? != 0 ]; then
-                       exit 1
-               fi
-       fi
+# @param       $module
+find_module() {
+       local mod depmod module=$1
 
+       depmod=$(find_depmod $module) || exit 1
        for mod in $depmod; do
                mod=${mod#/lib/modules/$kernel/}
 
@@ -353,12 +334,7 @@ findmodule() {
                        [ $m = $mod ] && have=1
                done
                if [ $have = 0 ]; then
-                       MODULES="$MODULES $mod" 
-
-                       # if we are adding uvesafb, we need v86d as well
-                       if [ "$modName" = "uvesafb" ]; then
-                               need_v86d=yes
-                       fi                              
+                       MODULES="$MODULES $mod"
                fi
        done
 }
@@ -379,7 +355,8 @@ inst() {
        done
        local dest=$1
        set -- $src
-
+       parentDir=$(dirname $DESTDIR$dest)
+       [ ! -d "$parentDir" ] && (debug "+ mkdir -p $parentDir"; mkdir -p $parentDir)
        debug "+ cp $* $DESTDIR$dest"
        cp -HR "$@" "$DESTDIR$dest"
 }
@@ -396,7 +373,7 @@ inst_d() {
 # install executable and it's shared libraries
 inst_exec() {
        if [ $# -lt 2 ]; then
-               die 'Usage: inst_exec <file> [, <file>] <destination>'
+               die "Invalid params ($@), Usage: inst_exec <file>[, <file>] <destination>"
        fi
        local src i=0 c=$(($# - 1))
        while [ $i -lt $c ]; do
@@ -409,13 +386,27 @@ inst_exec() {
 
        inst "$@" $dest
 
-       local lib libs=$(ldd "$@" | awk '/statically|linux-gate\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
+       local lib libs=$(ldd "$@" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
        for lib in $libs; do
                if [ ! -f "$DESTDIR/$_lib/${lib##*/}" ]; then
                        inst_d /$_lib
                        inst_exec $lib /$_lib
                fi
        done
+
+       # hack for uclibc linked binaries requiring this fixed path
+       # XXX: shouldn't rpath be used here instead so th
+       if [ -f $DESTDIR/$_lib/libc.so.0 ]; then
+               local lib=$DESTDIR/$_lib/libc.so.0
+               lib=$(ldd "$lib" | awk '/statically|linux-(gate|vdso)\.so/{next} NF == 2 {print $1} /=/{print $3}' | sort -u)
+               local libdir=$(cd $(dirname "$lib"); pwd)
+               if [ ! -e $DESTDIR$libdir ]; then
+                       libdir=$(dirname "$libdir")
+                       inst_d $libdir
+                       debug "+ ln -s /$_lib $DESTDIR$libdir"
+                       ln -s /$_lib $DESTDIR$libdir
+               fi
+       fi
 }
 
 # output modules.conf / modprobe.conf
@@ -427,7 +418,7 @@ modprobe_conf() {
 # defaults to modprobe -c if not told otherwise, this means include statements
 # work from there.
 cache_modprobe_conf() {
-       if [ "$pack_version" -lt "002005" ]; then
+       if [ "$kernel_version" -lt "002005" ]; then
                modulefile=/etc/modules.conf
                if [ ! -f "$modulefile" -a -f /etc/conf.modules ]; then
                        modulefile=/etc/conf.modules
@@ -439,345 +430,8 @@ cache_modprobe_conf() {
                modprobe_conf_cache=$(cat $modulefile)
        else
                debug "Using modprobe -c to get modules config"
-               modprobe_conf_cache=$(modprobe -c)
-       fi
-}
-
-find_modules_md() {
-       local found raidlevel
-
-       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 "have_md=" found;
-                       print "raidlevel=" raidlevel;
-                       print "dev_list=\"" dev_list "\"";
-               }'`
-       fi
-
-       if [ "$have_md" != "yes" -a -f /etc/raidtab ]; then
-               die "raidtools are not longer supported. Please migrate to mdadm setup!"
-       fi
-
-       if is_yes "$have_md"; then
-               case "$raidlevel" in
-               [01]|10)
-                       findmodule "raid$raidlevel"
-                       ;;
-               [456])
-                       findmodule "-raid$raidlevel"
-                       findmodule "-raid456"
-                       ;;
-               linear)
-                       findmodule "linear"
-                       ;;
-               *)
-                       warn "raid level $number (in mdadm config) not recognized"
-                       ;;
-               esac
-       else
-               die "RAID devices not found for \"$1\", check your configuration!"
-       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_devpath $device
-       done
-}
-
-find_modules_scsi() {
-       local n
-       for n in $PRESCSIMODS; do
-               if [ "X$n" = "Xunknown" ]; then
-                       debug "Finding SCSI modules using scsi_hostadapter"
-                       local mod scsimodules=$(modprobe_conf | awk '/scsi_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
-                       for mod in $scsimodules; do
-                               # for now allow scsi modules to come from anywhere. There are some
-                               # RAID controllers with drivers in block
-                               findmodule "$mod"
-                       done
-               else
-                       findmodule "$n"
-               fi
-       done
-       findmodule "-scsi_wait_scan"
-}
-
-find_modules_ide() {
-       local devpath=$1
-       # remove partition, if any
-       local disk=${devpath%[0-9]*}
-       # set blockdev for rootfs (hda, sdc, ...)
-       local rootblkdev=${disk#/dev/}
-
-       local n
-       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
-               local tryauto=1
-               for n in $PREIDEMODS; do
-                       if [ "X$n" = "Xunknown" ]; then
-                               debug "Finding IDE modules using ide_hostadapter"
-                               local mod idemodules=$(modprobe_conf | awk '/ide_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
-                               for mod in $idemodules; do
-                                       tryauto=0;
-                                       findmodule "$mod"
-                               done
-
-                               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
-is_lvm_node() {
-       local node="$1"
-       if [ ! -e "$node" ]; then
-               warn "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 "LVM check: $node is LVM v1 node"
-               # is lvm1
-               return 0
-       fi
-
-       if [ ! -x /sbin/lvm ]; then
-               debug "LVM check: no lvm2 tools present to check"
-               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.
-               die "Unexpected exit from 'lvdisplay $node': $rc - are your lvm tools broken?"
-       fi
-
-       if [ $rc = 0 ]; then
-               debug "LVM check: $node is LVM v2 node"
-       else
-               debug "LVM check: $node is not any LVM node"
-       fi
-       return $rc
-}
-
-# return dependencies MAJOR:MINOR [MAJOR:MINOR] for DM_NAME
-# TODO: patch `dmsetup export`
-dm_deps() {
-       local dm_name="$1"
-       dmsetup deps $dm_name | sed -e 's/, /:/g;s/^.\+ dependencies[^:]: //;s/[()]//g;'
-}
-
-# export info from dmsetup
-# param can be:
-# - MAJOR:MINOR
-# - /dev/dm-MINOR
-# - /dev/mapper/DM_NAME
-dm_export() {
-       local arg="$1"
-
-       case "$arg" in
-       *:*)
-               local maj=${arg%:*} min=${arg#*:}
-               dmsetup -j $maj -m $min export
-               ;;
-       /dev/dm-*)
-               local min=${arg#*dm-}
-               local maj=$(awk '$2 == "device-mapper" {print $1}' /proc/devices)
-               dm_export $maj:$min
-               ;;
-       /dev/mapper/*)
-               local dm_name=${arg#/dev/mapper/}
-               dmsetup export $dm_name
-               ;;
-       *)
-               die "dm_export: unexpected $arg"
-               ;;
-       esac
-}
-
-# find dm-multipath modules for $devpath
-# returns false if $devpath is not dm-multipath
-find_modules_multipath() {
-       local devpath="$1"
-
-       DM_NAME=
-       eval $(dm_export "$devpath")
-       if [ -z "$DM_NAME" ]; then
-               die "dm_export failed unexpectedly"
-       fi
-
-       # Partition:
-       #  DM_NAME=LUN-28p1
-       #  DM_UUID=part1-mpath-36006016002c11800a0aa05fbfae0db11
-       # Disk:
-       #  DM_NAME=LUN-28
-       #  DM_UUID=mpath-36006016002c11800a0aa05fbfae0db11
-       MPATH_WWID=${DM_UUID##*-}
-
-       local info=$(multipath -l $MPATH_WWID)
-       if [ -z "$info" ]; then
-               return 1
-       fi
-
-       debug "Finding modules for dm-multipath (WWID=$MPATH_WWID)"
-       have_multipath=yes
-       local dev phydevs=$(echo "$info" | awk '$2 ~ /^[0-9]+:[0-9]+:[0-9]+:[0-9]+$/{printf("/dev/%s\n", $3)}')
-       for dev in $phydevs; do
-               find_modules_for_devpath $dev
-               lvm_ignore_devices="$lvm_ignore_devices $dev"
-       done
-
-       local hw hwhandlers=$(echo "$info" | awk '/hwhandler=1/{sub(/.*hwhandler=1 /, ""); sub(/\]$/, ""); print}')
-       for hw in $hwhandlers; do
-               findmodule "dm-$hw"
-       done
-
-       local target targets=$(echo "$info" | awk '/prio=/{print $2}' | sort -u)
-       for target in $targets; do
-               findmodule "dm-$target"
-       done
-
-       findmodule "dm-mod"
-       return 0
-}
-
-# find dmraid modules for $devpath
-# returns false if $devpath is not on dmraid
-find_modules_dmraid() {
-       local devpath="$1"
-
-       # get blockdev itself (without partition)
-       # /dev/mapper/sil_ahbgadcbchfc3 -> /dev/mapper/sil_ahbgadcbchfc
-       local blockdev=${devpath%%[0-9]*}
-       local raidname=${blockdev#/dev/mapper/}
-       local found=0
-
-       local dev phydevs=$(dmraid -r -cdevpath,raidname | awk -F, -vv="$raidname" '{if ($2 == v) print $1}')
-       for dev in $phydevs; do
-               find_modules_for_devpath $dev
-               lvm_ignore_devices="$lvm_ignore_devices $dev"
-               found=1
-       done
-
-       if [ $found = 0 ]; then
-               return 1
+               modprobe_conf_cache=$(modprobe -c --set-version $kernel)
        fi
-
-       findmodule "dm-mirror"
-       have_dmraid=yes
-       return 0
 }
 
 # find modules for $devpath
@@ -787,92 +441,89 @@ find_modules_for_devpath() {
                die "No argument passed to find_modules_for_devpath() - is your /etc/fstab correct?"
        fi
 
-       # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
-       case "$devpath" in
-       /dev/dm-*)
+       if [[ "$devpath" = /dev/dm-* ]]; then
+               # /dev/dm-3 -> /dev/mapper/sil_ahbgadcbchfc3
                devpath=$(dm_longname "$devpath")
-               ;;
-       esac
+       fi
+
+       if [ -L "$devpath" ] && ! is_lvm "$devpath"; then
+               # sanitize things like:
+               # /dev/block/104:2 -> /dev/cciss/c0d0p2
+               devpath=$(readlink -f "$devpath")
+       fi
+
        debug "Finding modules for device path $devpath"
 
-       if is_yes "`echo "$devpath" | 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
-                       die "root on NFS but /usr/bin/pcidev not found. Please install correct pci-database package and rerun $PROGRAM."
-               fi
-               if [ ! -f /proc/bus/pci/devices ]; then
-                       warn "Remember to add network card modules in /etc/sysconfig/geninitrd, example:"
-                       warn "BASICMODULES=\"e1000 ne2k-pci mii 8139too 3c59x\""
-               else
-                       local m
-                       [ -z "$NFS_ETH_MODULES" ] && NFS_ETH_MODULES=$(/usr/bin/pcidev /m net | xargs)
-                       warn "NOTE: Network card(s) module(s) $NFS_ETH_MODULES is for this machine"
-                       for m in $NFS_ETH_MODULES; do
-                               findmodule "$m"
-                       done
-               fi
-               findmodule "-ipv4"
-               findmodule "nfs"
-               have_nfs=yes
-               warn "Remember to use \`root=/dev/ram0 init=/linuxrc' when starting kernel"
-               warn "or you will have problems like init(xx) being child process of swapper(1)."
+       if is_luks "$devpath"; then
+               find_modules_luks "$devpath"
                return
        fi
 
-       if [[ "$devpath" == /dev/md* ]]; then
+       if is_nfs "$devpath"; then
+               find_modules_nfs "$devpath"
+               return
+       fi
+
+       if is_md "$devpath"; then
                find_modules_md "$devpath"
                return
        fi
 
-       if is_yes "$USE_MULTIPATH" && [[ "$devpath" == /dev/mapper/* ]]; then
+       if is_multipath "$devpath"; then
                if find_modules_multipath "$devpath"; then
                        return
                fi
+
                # fallback
        fi
 
-       if is_yes "$USE_DMRAID" && is_yes "$(echo "$devpath" | awk '/^\/dev\/mapper\/(sil|hpt37x|hpt45x|isw|lsi|nvidia|pdc|sil|via|dos)_/ { print "yes"; }')"; then
+       if is_dmraid "$devpath"; then
                if find_modules_dmraid "$devpath"; then
                        return
                fi
                # fallback
        fi
 
-       if is_yes "$(echo "$devpath" | awk '/^\/dev\/(sd|scsi)/ { print "yes"; }')"; then
-               find_modules_scsi
+       if is_scsi "$devpath"; then
+               find_modules_scsi "$devpath"
                return
        fi
 
-       if is_yes "$(echo "$devpath" | awk '/^\/dev\/(hd|ide)/ { print "yes"; }')"; then
+       if is_ide "$devpath"; then
                find_modules_ide "$devpath"
                return
        fi
 
        if [[ "$devpath" == /dev/rd/* ]]; then
-               findmodule "DAC960"
+               find_module "DAC960"
+               rootdev_add=/dev/rd/
                return
        fi
 
        if [[ "$devpath" == /dev/ida/* ]]; then
-               findmodule "cpqarray"
+               find_module "cpqarray"
+               rootdev_add=/dev/ida/
                return
        fi
 
        if [[ "$devpath" == /dev/cciss/* ]]; then
-               findmodule "cciss"
+               find_module "cciss"
+               rootdev_add=/dev/cciss/
                return
        fi
 
        if [[ "$devpath" == /dev/ataraid/* ]]; then
                find_modules_ide
-               findmodule "ataraid"
+               find_module "ataraid"
                ataraidmodules=$(modprobe_conf | awk '/ataraid_hostadapter/ && ! /^[\t ]*#/ { print $3; }')
                if [ -n "$ataraidmodules" ]; then
                        # FIXME: think about modules compiled in kernel
                        die "ataraid_hostadapter alias not defined in modprobe.conf! Please set it and run $PROGRAM again."
                fi
                for n in $ataraidmodules; do
-                       findmodule "$n"
+                       find_module "$n"
                done
+               rootdev_add=/dev/ataraid/
                return
        fi
 
@@ -894,46 +545,13 @@ find_modules_for_devpath() {
                loopFile="$(echo $line | awk '{print $5}')"
 
                BASICMODULES="$BASICMODULES -loop"
-               findmodule "-$loopFs"
+               find_module "-$loopFs"
                BASICMODULES="$BASICMODULES -${loopFs}"
                return
        fi
 
-       if is_lvm_node "$devpath"; then
-               node="$devpath"
-
-               if [ ! -f /sbin/initrd-lvm -o ! -x /sbin/lvdisplay -o ! -x /sbin/pvdisplay ]; then
-                       die "root on LVM but /sbin/initrd-lvm, /sbin/lvdisplay and /sbin/pvdisplay not found. Please install lvm(2) and lvm(2)-initrd package and rerun $PROGRAM."
-               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
-                               die "Can't determine LVM tools version. Please set LVMTOOLSVERSION and rerun $PROGRAM."
-                       fi
-               fi
-
-               local vg=$(/sbin/lvdisplay -c "$node" 2> /dev/null | awk -F":" ' { print $2 } ')
-               VGVOLUMES=$(echo $VGVOLUMES $vg | tr ' ' '\n' | sort -u)
-               local pv=$(/sbin/pvdisplay -c 2>/dev/null | awk -F":" -v vg="$vg" ' BEGIN { devices="" } { if ($2 == vg) { devices = devices " " $1 } } END { print devices } ')
-               PVDEVICES=$(echo $PVDEVICES $pv | tr ' ' '\n' | sort -u)
-
-               if [ -n "$PVDEVICES" ]; then
-                       for device in $PVDEVICES; do
-                               find_modules_for_devpath $device
-                       done
-               else
-                       die "I wasn't able to find PV (via lvdisplay and pvdisplay). You can try to set PVDEVICES in /etc/sysconfig/geninitrd."
-               fi
-               if [ "$LVMTOOLSVERSION" = "2" ]; then
-                       findmodule "-dm-mod"
-               elif [ "$LVMTOOLSVERSION" = "1" ]; then
-                       findmodule "-lvm"
-                       findmodule "-lvm-mod"
-               else
-                       die "LVM version $LVMTOOLSVERSION is not supported yet."
-               fi
-               debug "LVM v$LVMTOOLSVERSION enabled"
-               have_lvm=yes
+       if is_lvm "$devpath"; then
+               find_modules_lvm "$devpath"
                return
        fi
 }
@@ -941,7 +559,6 @@ find_modules_for_devpath() {
 firmware_install_module() {
        local module="$1"
        local firmware_files="$2"
-       local force="$3"
 
        debug "Adding Firmwares ($firmware_files) to initrd for module $module"
        # firmware not yet installed
@@ -958,14 +575,16 @@ EOF
        fi
 
        for firmware in $firmware_files; do
-               if [ ! -f "/lib/firmware/$firmware" ]; then
-                       if [ -n "$force" ]; then
-                               die "firmware file /lib/firmware/$firmware doesn't exist."
-                       else
-                               warn "firmware file /lib/firmware/$firmware doesn't exist. Skipping."
-                       fi
-               else
+               if [ -f "/lib/firmware/$kernel/$firmware" ]; then
+                       FIRMWAREDIR=${firmware%/*}
+                       [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
+                       inst /lib/firmware/$kernel/$firmware /lib/firmware/$firmware
+               elif [ -f "/lib/firmware/$firmware" ]; then
+                       FIRMWAREDIR=${firmware%/*}
+                       [ "$FIRMWAREDIR" != "$firmware" ] && inst_d /lib/firmware/$FIRMWAREDIR
                        inst /lib/firmware/$firmware /lib/firmware/$firmware
+               else
+                       die "firmware file /lib/firmware/$firmware nor /lib/firmware/$kernel/$firmware found."
                fi
        done
 
@@ -1014,7 +633,7 @@ modules_add_linuxrc() {
                fi
 
                if [ -n "$firmware_var" ]; then
-                       firmware_install_module "$module" "$firmware_var" "force=yes"
+                       firmware_install_module "$module" "$firmware_var"
                else
                        firmware_files=$(find_firmware "$module")
                        if [ -n "$firmware_files" ]; then
@@ -1024,594 +643,204 @@ modules_add_linuxrc() {
                        fi
                fi
 
-               echo "$insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
+               echo "insmod /lib/modules/$kernel/$modpath $options" | add_linuxrc
                if [ -n "$sleep_var" ]; then
                        echo "usleep $sleep_var" | add_linuxrc
                fi
-       done
-}
-
-find_modules_suspend() {
-       if [ ! -x /usr/${_lib}/suspend/resume -a ! -x /usr/sbin/resume ]; then
-               die "/usr/${_lib}/suspend/resume is missing!"
-       fi
-       resume_dev="$(awk '/^resume device =/ { print $4 } ' /etc/suspend.conf)"
-
-       local vgvolumes=$VGVOLUMES
-       find_modules_for_devpath $resume_dev
+               if [ "$module" = "scsi_wait_scan" ]; then
+                       if [ "$(busybox_applet rmmod 2>/dev/null; echo $?)" = 0 ]; then
+                               echo "rmmod scsi_wait_scan" | add_linuxrc
+                       fi
+               fi
 
-       if [ "$VGVOLUMES" != "$vgvolumes" ]; then
-               # save our VG to be able to differenciate between rootfs VG
-               SUSPENDVG=$VGVOLUMES
-               VGVOLUMES=$vgvolumes
-               debug "suspend device is on LVM"
-       fi
+       done
 }
 
-initrd_gen_suspend() {
-       mknod $DESTDIR/dev/snapshot c 10 231
-       mkdir -p $DESTDIR${resume_dev%/*}
-       inst $resume_dev $resume_dev
-
-       inst /etc/suspend.conf /etc/suspend.conf
-       if [ -x /usr/${_lib}/suspend/resume ]; then
-               inst /usr/${_lib}/suspend/resume /bin/resume
-       else
-               inst /usr/sbin/resume /bin/resume
+# Generates /dev nodes based on /proc/partitions information.
+# Needs /proc mounted.
+# Can be called multiple times.
+initrd_gen_devices() {
+       if is_yes "$proc_partitions"; then
+               return
        fi
+       proc_partitions=yes
 
+       mount_dev
        add_linuxrc <<-'EOF'
-       resume=no
-       for arg in $CMDLINE; do
-               if [ "${arg##resume=}" != "${arg}" ]; then
-                       resume=yes
-               fi
-       done
-       if [ "$resume" = "yes" ]; then
-               resume
-       fi
+               : 'Making device nodes'
+               cat /proc/partitions | (
+                       # ignore first two lines: header, empty line
+                       read b; read b
+
+                       while read major minor blocks dev rest; do
+                               node=/dev/$dev
+                               mkdir -p ${node%/*}
+                               [ -e $node ] || mknod $node b $major $minor
+                       done
+               )
        EOF
 }
 
-initrd_gen_tuxonice() {
-       mount_sys
+
+initrd_gen_setrootdev() {
+       debug "Adding rootfs finding based on kernel cmdline root= option support."
        add_linuxrc <<-'EOF'
-               resume=no
-               for arg in $CMDLINE; do
-                       if [ "${arg##resume=}" != "${arg}" -o "${arg##resume2=}" != "${arg}" ]; then
-                               resume=yes
+               if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
+                       rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
+                       if [ -n "$rootnr" ]; then
+                               echo "$rootnr" > /proc/sys/kernel/real-root-dev
                        fi
-               done
-               if [ "$resume" = "yes" ]; then
-                       [ -e /proc/suspend2/do_resume ] && echo > /proc/suspend2/do_resume
-                       [ -e /sys/power/suspend2/do_resume ] && echo > /sys/power/suspend2/do_resume
-                       [ -e /sys/power/tuxonice/do_resume ] && echo > /sys/power/tuxonice/do_resume
                fi
        EOF
 }
 
-initrd_gen_v86d() {
-       debug "initrd_gen_v86d"
-       mknod $DESTDIR/dev/mem c 1 1
-       mknod $DESTDIR/dev/tty1 c 4 1
-       inst_d /sbin
-       inst_exec /sbin/v86d /sbin
-}
-
-initrd_gen_udev() {
-       debug "Setting up udev..."
-       inst_d /sbin /etc/udev
-
-       if [ ! -x /sbin/initrd-udevd ]; then
-               die "/sbin/initrd-udevd not present"
+initrd_gen_initramfs_switchroot() {
+       inst_d /newroot
+       if [ "$rootdev" = "/dev/nfs" ]; then
+               echo "rootfs on NFS root=/dev/nfs"
+       else
+               [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev $rootdev
        fi
 
-       inst /sbin/initrd-udevd /sbin/udevd
-       inst /etc/udev/udev.conf /etc/udev/udev.conf
-
-       mount_dev
-       mount_sys
+       # parse 'root=xxx' kernel commandline
+       # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
        add_linuxrc <<-'EOF'
-               : 'Starting udev'
-               /sbin/udevd --daemon
-       EOF
+               device=/dev/no_partition_found
+               eval "$(busybox awk -v c="$ROOT" '
+                       BEGIN {
+                               num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
+                               num_pattern = "[0-9a-f]" num_pattern_short;
+                               dev_pattern = "[hms][a-z][a-z]([0-9])+";
+                               partition = "no_partition_found";
+                               min = -1; maj = -1;
 
-       inst /sbin/initrd-udevadm /sbin/udevadm
-       ln -s udevadm $DESTDIR/sbin/udevsettle
-       ln -s udevadm $DESTDIR/sbin/udevtrigger
-       add_linuxrc <<-'EOF'
-               /sbin/udevtrigger
-               /sbin/udevsettle
+                               sub("^0x", "", c);
+                               if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
+                               if (c ~ "^" num_pattern  "$") {
+                                       maj = sprintf("%s",substr(c,1,2));
+                                       min = sprintf("%s",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 {
+                               if (maj >= 0 && min >= 0) {
+                                       printf("device=/dev/%s; maj=%s; min=%s;\n", partition, maj, min);
+                               }
+                       }
+                       ' /proc/partitions)"
+               if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
+                       mknod $device b $maj $min
+               fi
        EOF
 
-       busybox_applet killall
-       add_linuxrc     <<-'EOF'
-               killall udevd
+       add_linuxrc <<-EOF
+               rootdev=$rootdev
+               rootfs=$rootFs
        EOF
-}
 
-initrd_gen_multipath() {
-       inst_d /sbin /lib/udev /etc/multipath
-       inst_exec /sbin/kpartx /sbin
-       inst_exec /sbin/multipath /sbin
-       # for udev callouts
-       inst_exec /sbin/scsi_id /lib/udev
-       inst_exec /sbin/mpath* /sbin
-       egrep -v '^([   ]*$|#)' /etc/multipath.conf > $DESTDIR/etc/multipath.conf
-
-       if [ -f /etc/multipath/bindings ]; then
-               egrep -v '^([   ]*$|#)' /etc/multipath/bindings > $DESTDIR/etc/multipath/bindings
-       else
-               touch $DESTDIR/etc/multipath/bindings
-       fi
-
-       mount_dev
-       initrd_gen_devices
-
-       mount_sys
-       echo "export MPATH_WWID=$MPATH_WWID" | add_linuxrc
        add_linuxrc <<-'EOF'
-               # parse mpath_wwid= from kernel commandline
-               for arg in $CMDLINE; do
-                       if [ "${arg##mpath_wwid=}" != "${arg}" ]; then
-                               MPATH_WWID=${arg##mpath_wwid=}
-                               if [ "$MPATH_WWID" = "*" ]; then
-                                       # '*' would mean activate all WWID-s
-                                       MPATH_WWID=
-                                       echo "multipath: Activating all WWID-s"
-                               else
-                                       echo "multipath: Activating WWID=$WWID"
-                               fi
-                       fi
-               done
-
-               debugshell
-               /sbin/multipath -v 0 $MPATH_WWID
-
-               for a in /dev/mapper/*; do
-                       [ $a = /dev/mapper/control ] && continue
-                       /sbin/kpartx -a -p p $a
-               done
-               debugshell
-       EOF
-}
-
-initrd_gen_dmraid() {
-       if [ ! -x /sbin/dmraid-initrd ]; then
-               die "/sbin/dmraid-initrd is missing!"
-       fi
-
-       inst_d /sbin
-       inst /sbin/dmraid-initrd /sbin/dmraid
-
-       mount_dev
-       mount_sys
-       initrd_gen_devices
-       add_linuxrc <<-EOF
-               # 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
-
-               debugshell
-       EOF
-}
-
-initrd_gen_bootsplash() {
-       local target="$1"
-
-       debug "Generating bootsplash"
-
-       if [ ! -x /bin/splash.bin ]; then
-               warn "Failed to execute /bin/splash.bin. Is bootsplash package installed?"
-               return
-       fi
-
-       if [ -r /etc/sysconfig/bootsplash ]; then
-               . /etc/sysconfig/bootsplash
-       fi
-
-       if [ -z "$THEME" ]; then
-               warn "Please configure your /etc/sysconfig/bootsplash first."
-               warn "Generating bootsplashes skipped."
-               return
-       fi
-
-       if [ -z "$BOOT_SPLASH_RESOLUTIONS" ]; then
-               warn "No BOOT_SPLASH_RESOLUTIONS specified in /etc/sysconfig/bootsplash."
-               warn "Not adding bootsplash to initrd."
-       fi
-
-       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
-                       warn "/etc/bootsplash/themes/$THEME/config/bootsplash-$res.cfg doesn't exist, skipped"
-               fi
-       done
-}
-
-initrd_gen_fbsplash() {
-       debug "Generating fbsplash"
-
-       if [ ! -x /usr/bin/splash_geninitramfs -a ! -x /usr/sbin/splash_geninitramfs ]; then
-               warn "Failed to find splash_geninitramfs. Is splashutils package installed?"
-               return
-       fi
-
-       if [ -r /etc/sysconfig/fbsplash ]; then
-               . /etc/sysconfig/fbsplash
-       fi
-
-       if [ -z "$SPLASH_THEME" ]; then
-               warn "Please configure your /etc/sysconfig/fbsplash first."
-               warn "Generating fbsplashes skipped."
-               return
-       fi
-
-       if [ -z "$FB_SPLASH_RESOLUTIONS" ]; then
-               warn "No FB_SPLASH_RESOLUTIONS specified in /etc/sysconfig/fbsplash."
-               warn "Not adding fbsplash to initramfs."
-               return
-       fi
-
-       for res in $FB_SPLASH_RESOLUTIONS; do
-               if [ -f "/etc/splash/$SPLASH_THEME/$res.cfg" ]; then
-                       /usr/bin/splash_geninitramfs -c $DESTDIR -r $res $SPLASH_THEME && \
-                       debug "Added $res $SPLASH_THEME theme to initramfs."
-               else
-                       warn "/etc/splash/$SPLASH_THEME/$res.cfg doesn't exist, skipped"
+               if [ "$device" = '/dev/no_partition_found' ]; then
+                       device=$rootdev
                fi
-       done
-}
-
-initrd_gen_fbcondecor() {
-       debug "Generating fbcondecor"
-
-       if [ ! -x /usr/bin/splash_geninitramfs -a ! -x /usr/sbin/splash_geninitramfs ]; then
-               warn "Failed to find splash_geninitramfs. Is splashutils package installed?"
-               return
-       fi
-
-       if [ -r /etc/sysconfig/splash ]; then
-               . /etc/sysconfig/splash
-       fi
-
-       if [ -z "$SPLASH_THEME" ]; then
-               warn "Please configure your /etc/sysconfig/splash first."
-               warn "Generating of splashes skipped."
-               return
-       fi
-
-       if [ -z "$FB_SPLASH_RESOLUTIONS" ]; then
-               warn "No FB_SPLASH_RESOLUTIONS specified in /etc/sysconfig/splash."
-               warn "Not adding fbcondecor to initramfs."
-               return
-       fi
 
-       for res in $FB_SPLASH_RESOLUTIONS; do
-               if [ -f "/etc/splash/$SPLASH_THEME/$res.cfg" ]; then
-                       /usr/sbin/splash_geninitramfs -c $DESTDIR -r $res $SPLASH_THEME && \
-                       debug "Added $res $SPLASH_THEME theme to initramfs."
-               else
-                       warn "/etc/splash/$SPLASH_THEME/$res.cfg doesn't exist, skipped"
+               mount -t $rootfs -r $device /newroot
+               init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
+               if [ -z "$init" -o ! -x "/newroot$init" ]; then
+                       init=/sbin/init
                fi
-       done
-}
-
-# Generates /dev nodes based on /proc/partitions information.
-# Needs /proc mounted.
-# Can be called multiple times.
-initrd_gen_devices() {
-       if is_yes "$proc_partitions"; then
-               return
-       fi
-       proc_partitions=yes
-
-       mount_dev
-       add_linuxrc <<-'EOF'
-               : 'Making device nodes'
-               cat /proc/partitions | (
-                       # ignore first two lines: header, empty line
-                       read b; read b
-
-                       while read major minor blocks dev rest; do
-                               node=/dev/$dev
-                               mkdir -p ${node%/*}
-                               [ -e $node ] || mknod $node b $major $minor
-                       done
-               )
        EOF
-}
-
-initrd_gen_md() {
-       debug "Setting up mdadm..."
-
-       if [ ! -x /sbin/mdadm -o ! -x /sbin/initrd-mdassemble ]; then
-               die "/sbin/mdadm or /sbin/initrd-mdassemble is missing!"
-       fi
-
-       inst /sbin/initrd-mdassemble /bin/mdassemble
-
-       # LVM on RAID case
-       dev_list_extra=$(awk '/^DEVICE / { for (i=2; i<=NF; i++) { printf "%s ", $i; }; } ' /etc/mdadm.conf)
-       if [ "$dev_list_extra" = "partitions" ]; then
-               # FIXME: handle this case (see man mdadm.conf)
-               echo "DEVICE partitions" >> "$DESTDIR/etc/mdadm.conf"
-               dev_list_extra=""
-       else
-               for ex_dev in $dev_list_extra; do
-                       echo "DEVICE $ex_dev" >> "$DESTDIR/etc/mdadm.conf"
-               done
-       fi
-       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" >> "$DESTDIR/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" >> "$DESTDIR/etc/mdadm.conf"
-               else
-                       echo "ARRAY $cr_rootdev devices=$cr_dev_list_md" >> "$DESTDIR/etc/mdadm.conf"
-               fi
-
-               for f in $cr_dev_list $cr_rootdev $dev_list_extra; do
-                       # mkdir in case of devfs name
-                       inst_d $(dirname $f)
-                       [ -e "$DESTDIR/$f" ] && continue
-                       # this works fine with and without devfs
-                       inst $f $f
-               done
-       done
-
-       echo "mdassemble" | add_linuxrc
-
-       # needed to determine md-version
-       if [ "$do_md0" -eq 1 ]; then
-               mknod $DESTDIR/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 "$DESTDIR/dev/urandom" c 1 9
-       mkdir "$DESTDIR/newroot"
+       umount_all
+       busybox_applet switch_root
        add_linuxrc <<-'EOF'
-               ifconfig lo 127.0.0.1 up
-               route add -net 127.0.0.0 mask 255.0.0.0 lo
-               ifconfig eth0 up
-               udhcpc -i eth0 -f -q -s /bin/setdhcp
-
-               cd /newroot
-               pivot_root . initrd
-               [ -x /sbin/chroot ] && exec /sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1
-               exec /usr/sbin/chroot . /sbin/init -i < dev/console > dev/console 2>&1
-       EOF
+               exec switch_root /newroot $init ${1:+"$@"}
 
-       cat <<-'EOF' > "$DESTDIR/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
+               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."
 
-               for o in $CMDLINE; do
-                       case $o in
-                       nfsroot=*)
-                               rootpath=${o#nfsroot=}
-                               ;;
-                       esac
-               done
+               exec chroot /newroot $init ${1:+"$@"}
 
-               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
+               echo "Failed to chroot!"
        EOF
-
-       chmod 755 "$DESTDIR/bin/setdhcp"
+       # we need /init being real file, not symlink, otherwise the initramfs will
+       # not be ran by pid 1 which is required for switch_root
+       mv $DESTDIR/linuxrc $DESTDIR/init
+       ln -s init $DESTDIR/linuxrc
 }
 
-initrd_gen_lvm() {
-       debug "Adding LVM support to initrd"
-       inst_d /tmp /newroot
-       inst /sbin/initrd-lvm /bin/lvm.static
-
-       # always make /dev on tmpfs for LVM2
-       if [ "$LVMTOOLSVERSION" = "2" ]; then
-               mount_dev
-       fi
-
-       if ! is_yes "$dev_mounted"; then
-               inst_d /dev/mapper
-               mknod $DESTDIR/dev/mapper/control c 10 63
-               for device in $PVDEVICES; do
-                       # if LVM on RAID then device might be copied already in gen_md
-                       [ -e "$DESTDIR/dev/$(basename $device)" ] && continue
-                       inst $device /dev
-               done
+# find if $symbol exists in System.map $mapfile
+sym_exists() {
+       local mapfile="$1"
+       local symbol="$2"
+       if [ ! -f $mapfile ]; then
+               # missing mapfile (not a pld kernel?)
+               return 1
        fi
 
-       mount_tmp
-       if [ "$LVMTOOLSVERSION" = "1" ]; then
-               add_linuxrc <<-EOF
-                       lvm vgscan -T
-                       for vg in $VGVOLUMES; do
-                               lvm vgchange -T -a y $vg
-                       done
-               EOF
-       else
-               echo "cat /etc/lvm.conf > /tmp/lvm.conf" | add_linuxrc
-               echo "global {" > "$DESTDIR/etc/lvm.conf"
-               echo "  locking_type = 0" >> "$DESTDIR/etc/lvm.conf"
-               echo "  locking_dir = \"/tmp\"" >> "$DESTDIR/etc/lvm.conf"
-               echo "}" >> "$DESTDIR/etc/lvm.conf"
-               echo "devices {" >> "$DESTDIR/etc/lvm.conf"
-               echo "  sysfs_scan=0" >> "$DESTDIR/etc/lvm.conf"
-               if is_yes "$have_md"; then
-                       echo "  md_component_detection = 1" >> "$DESTDIR/etc/lvm.conf"
-               fi
-               if is_yes "$have_dmraid" || is_yes "$have_multipath"; then
-                       echo '  types = [ "device-mapper", 254 ]' >> "$DESTDIR/etc/lvm.conf"
-               fi
-               if [ "$lvm_ignore_devices" ]; then
-                       # TODO: think of merging with lvm dumpconfig output
-                       echo '  filter = [' >> "$DESTDIR/etc/lvm.conf"
-                       local dev
-                       for dev in $lvm_ignore_devices; do
-                               debug "LVM v2: ignore device $dev"
-                               printf '  "r|^%s.*|",\n' $dev
-                       done >> "$DESTDIR/etc/lvm.conf"
-                       echo ']' >> "$DESTDIR/etc/lvm.conf"
-               fi
-               # XXX filter= must be on one line!
-               lvm dumpconfig | awk '/filter=/' >> "$DESTDIR/etc/lvm.conf"
-               echo "}" >> "$DESTDIR/etc/lvm.conf"
-
-               initrd_gen_devices
-
-               add_linuxrc <<-EOF
-                       export ROOTDEV=$rootdev
-                       export ROOTVG="$VGVOLUMES"
-                       export SUSPENDVG=$SUSPENDVG
-               EOF
-               add_linuxrc <<-'EOF'
-                       # parse rootdev from kernel commandline
-                       if [ "$ROOT" != "$ROOTDEV" ]; then
-                               ROOTDEV=$ROOT
-                               echo "LVM: Using 'root=$ROOTDEV' from kernel commandline"
-                               local tmp=${ROOTDEV#/dev/}
-                               if [ "$tmp" != "$ROOTDEV" ]; then
-                                       ROOTVG=${tmp%/*}
-                                       echo "LVM: Using Volume Group '$ROOTVG' for rootfs"
-                               fi
-                       fi
-
-                       # skip duplicate VG
-                       if [ "$SUSPENDVG" = "$ROOTVG" ]; then
-                               export VGVOLUMES="$ROOTVG"
-                       else
-                               export VGVOLUMES="$SUSPENDVG $ROOTVG"
-                       fi
-
-                       # disable noise from LVM accessing devices that aren't ready.
-                       read printk < /proc/sys/kernel/printk
-                       if [ ! "$DEBUGINITRD" ]; then
-                               echo 0 > /proc/sys/kernel/printk
-                       fi
-
-                       export LVM_SYSTEM_DIR=/tmp
-                       : 'Scanning for Volume Groups'
-                       lvm.static vgscan --mknodes --ignorelockingfailure 2>/dev/null
-
-                       : 'Activating Volume Groups'
-                       for vol in $VGVOLUMES; do
-                               lvm.static vgchange --ignorelockingfailure -a y $vol 2>/dev/null
-                       done
-
-                       echo "$printk" > /proc/sys/kernel/printk
-
-                       # Find out major/minor
-                       attrs="$(lvm.static lvdisplay --ignorelockingfailure -c $ROOTDEV 2>/dev/null)"
-                       if [ "$attrs" ]; then
-                               majmin="${attrs#*$ROOTDEV*:*:*:*:*:*:*:*:*:*:*:*}"
-                               if [ "$majmin" != "$attrs" ]; then
-                                       major="${majmin%:*}"
-                                       minor="${majmin#*:}"
-                               fi
-                       fi
-
-                       if [ "$major" -a "$minor" ]; then
-                               # Pass it to kernel
-                               echo $((256 * $major + $minor)) > /proc/sys/kernel/real-root-dev
-                       else
-                               echo 2>&1 "Error figuring out real root device for $ROOTDEV!"
-                               echo 2>&1 "System will not most likely boot up! So dropping you to a shell!"
-                               echo 2>&1 ""
-                               sh
-                       fi
-               EOF
-       fi
+       awk -vc=1 -vsymbol="$symbol" '$2 == "T" && $3 == symbol {c = 0} END {exit c}' $mapfile
 }
 
-initrd_gen_blkid()
-{
-       debug "Adding BLKID support to initrd"
-       inst /sbin/initrd-blkid /bin/blkid
-       initrd_gen_devices
-       add_linuxrc <<-'EOF'
-               # if built with blkid change ROOT=LABEL=something into ROOT=/dev/somethingelse -
-               # parsed by blkid
-               if [ "${ROOT##LABEL=}" != "${ROOT}" -o "${ROOT##UUID=}" != "${ROOT}" ]; then
-                       ROOT="$(/bin/blkid -t $ROOT -o device -l)"
+# find best compressor (or forced one) for initrd
+find_compressor() {
+       local mode="$1"
+       # the best compressor list
+       local compressors='xz lzma bzip2 gzip'
+
+       # a specified one, take it
+       if ! is_yes "$mode"; then
+               compressors="$mode"
+       fi
+
+       debug "finding compressor: $compressors (via $mode)"
+       # check for compressor validity
+       local c prog map=/boot/System.map-$kernel
+       for c in $compressors; do
+               case $c in
+               xz)
+                       sym=unxz
+                       prog=/usr/bin/xz
+                       ;;
+               lzma)
+                       sym=unlzma
+                       prog=/usr/bin/xz
+                       ;;
+               bzip2)
+                       sym=bzip2
+                       prog=/usr/bin/bzip2
+                       ;;
+               gzip)
+                       sym=gunzip
+                       prog=/bin/gzip
+                       ;;
+               *)
+                       die "Unknown compressor $c"
+                       ;;
+               esac
+               if sym_exists $map $sym && [ -x $prog ]; then
+                       echo $c
+                       return
                fi
-       EOF
-}
+       done
 
-initrd_gen_setrootdev() {
-       debug "Adding rootfs finding based on kernel cmdline root= option support."
-       add_linuxrc <<-'EOF'
-               if [ "${ROOT##/dev/}" != "${ROOT}" ]; then
-                       rootnr="$(busybox awk -v rootnode="${ROOT##/dev/}" '$4 == rootnode { print 256 * $1 + $2 }' /proc/partitions)"
-                       if [ -n "$rootnr" ]; then
-                               echo "$rootnr" > /proc/sys/kernel/real-root-dev
-                       fi
-               fi
-       EOF
+       debug "using gzip for compressor (fallback)"
+       echo gzip
 }
 
-# main()
-if [ "$(id -u)" != 0 ]; then
-       die "You need to be root to generate initrd"
-fi
-
-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
-
-if [ -x /sbin/multipath ]; then
-       USE_MULTIPATH=yes
-fi
-
-if [ -x /sbin/initrd-blkid ]; then
-       USE_BLKID=yes
-fi
-
 if [ -r /etc/sysconfig/geninitrd ]; then
        . /etc/sysconfig/geninitrd
 fi
 
-if [ ! -x /bin/initrd-busybox ]; then
-       die "/bin/initrd-busybox is missing!"
+if [ ! -f /proc/mounts ]; then
+       warn "/proc filesystem not mounted, may cause wrong results or failure."
 fi
 
-# backwards compatible
-if [ "$USE_SUSPEND2" ]; then
-       USE_TUXONICE=$USE_SUSPEND2
-       warn "USE_SUSPEND2 is deprecated, use USE_TUXONICE now instead."
-fi
+geninitrd_load_mods ide luks multipath dmraid lvm md blkid udev tuxonice suspend fbsplash condecor bootsplash uvesafb nfs scsi
 
 while [ $# -gt 0 ]; do
        case $1 in
@@ -1629,18 +858,6 @@ while [ $# -gt 0 ]; do
                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
-               ;;
        --with-bootsplash)
                BOOT_SPLASH=yes
                ;;
@@ -1671,10 +888,12 @@ while [ $# -gt 0 ]; do
        --without-suspend2 | --without-tuxonice)
                USE_TUXONICE=no
                ;;
-       --lvmtoolsversion=|--lvmversion=)
-               LVMTOOLSVERSION=${1#--lvmtoolsversion=}
+       --lvmversion=*)
                LVMTOOLSVERSION=${1#--lvmversion=}
                ;;
+       --lvmtoolsversion=*)
+               LVMTOOLSVERSION=${1#--lvmtoolsversion=}
+               ;;
        --lvmtoolsversion|--lvmversion)
                LVMTOOLSVERSION=$2
                shift
@@ -1689,11 +908,17 @@ while [ $# -gt 0 ]; do
                USE_DMRAID=no
                ;;
        --without-multipath)
-               USE_MULTPATH=no
+               USE_MULTIPATH=no
+               ;;
+       --with-multipath=*)
+               USE_MULTIPATH=${1#--with-multipath=}
                ;;
        --without-blkid)
                USE_BLKID=no
                ;;
+       --without-luks)
+               USE_LUKS=no
+               ;;
        --with=*)
                BASICMODULES="$BASICMODULES ${1#--with=}"
                ;;
@@ -1708,6 +933,12 @@ while [ $# -gt 0 ]; do
        -v)
                verbose=-v
                ;;
+       --compress)
+               COMPRESS=$2
+               ;;
+       --compress=*)
+               COMPRESS="${1#--compress=}"
+               ;;
        --nocompress)
                COMPRESS=no
                ;;
@@ -1724,14 +955,8 @@ while [ $# -gt 0 ]; do
                PREMODS="$PREMODS $2"
                shift
                ;;
-       --fs=*)
-               warn "Warning: --fs option is obsoleted. Use --initrdfs instead"
-               INITRDFS=${1#--fs=}
-               ;;
-       --fs)
-               warn "Warning: --fs option is obsoleted. Use --initrdfs instead"
-               INITRDFS=$2
-               shift
+       --fs=* | --fs)
+               die "--fs option is obsoleted. Use --initrdfs instead"
                ;;
        --initrdfs=*)
                INITRDFS=${1#--initrdfs=}
@@ -1752,7 +977,8 @@ while [ $# -gt 0 ]; do
                elif [ -z "$kernel" ]; then
                        kernel="$1"
                else
-                       usage
+                       usage >&2
+                       exit 1
                fi
                ;;
        esac
@@ -1761,78 +987,69 @@ while [ $# -gt 0 ]; do
 done
 
 if [ -z "$target" -o -z "$kernel" ]; then
-       usage
+       usage >&2
+       exit 1
 fi
 
-if [ ! -f /boot/vmlinuz-"$kernel" ]; then
-       warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
+# main()
+if [ "$(id -u)" != 0 ]; then
+       die "You need to be root to generate initrd"
 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 [ -z "$INITRDFS" ]; then
-       if [ -z "$FS" ]; then
-               # default value
-               if [ "$pack_version" -ge "002005" ]; then
-                       INITRDFS="initramfs"
-               else
-                       INITRDFS="rom"
-               fi
-       else
-               warn "Warning: FS configuration options is obsoleted. Use INITRDFS instead"
-               INITRDFS="$FS"
-       fi
+if [ -d /usr/lib64 ]; then
+       _lib=lib64
+else
+       _lib=lib
 fi
 
-if [ "$pack_version" -lt "002006" ]; then
-       USE_UDEV=no
-       USE_DMRAID=no
-fi
+initrd_dir=/usr/$_lib/initrd
+kernel_version=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d",$1,$2)}')
+kernel_version_long=$(echo "$kernel" | awk -F. '{print sprintf("%03d%03d%03d",$1,$2,$3)}')
 
-if [ "$pack_version" -ge "002005" ]; then
-       modext=".ko"
-       insmod="insmod"
+debug "# $RCSID"
+debug "Using _lib: $_lib"
+debug "Using initrd_dir: $initrd_dir"
+
+busybox=$(find_tool $initrd_dir/initrd-busybox /bin/initrd-busybox) || die "Couldn't find busybox suitable for initrd"
+
+# we setup mods after parsing command line args
+geninitrd_setup_mods
+
+if [ ! -f /boot/vmlinuz-"$kernel" ]; then
+       warn "/boot/vmlinuz-$kernel doesn't exist, is your /boot mounted?"
 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"
+if [ -z "$INITRDFS" ]; then
+       if [ -n "$FS" ]; then
+               # FS= can came only via /etc/sysconfig/geninitrd likely?
+               die "FS configuration option is obsoleted. Use INITRDFS instead"
        fi
-       if [ ! -f "$INSMOD" ]; then
-               die "insmod.static requested but /sbin/insmod.static not found!"
+
+       # default value
+       if [ "$kernel_version" -ge "002005" ]; then
+               INITRDFS="initramfs"
+       else
+               INITRDFS="rom"
        fi
 fi
 
 case "$INITRDFS" in
-       ext2)
-               if [ ! -x /sbin/mke2fs ]; then
-                       die "/sbin/mke2fs is missing"
-               fi
-               ;;
-       rom|romfs)
-               if [ ! -x /sbin/genromfs ]; then
-                       die "/sbin/genromfs is missing"
-               fi
-               ;;
-       cram|cramfs)
-               if [ ! -x /sbin/mkcramfs ]; then
-                       die "/sbin/mkcramfs is missing"
-               fi
-               ;;
-       initramfs)
-               if [ ! -x /bin/cpio ]; then
-                       die "/bin/cpio is missing"
-               fi
-               if [ ! -x /usr/bin/find ]; then
-                       die "/usr/bin/find is missing"
-               fi
-               ;;
-       *)
-               die "Filesystem $INITRDFS on initrd is not supported"
-               ;;
+  ext2)
+       [ -x /sbin/mke2fs ] || die "/sbin/mke2fs is missing"
+       ;;
+  rom|romfs)
+       [ -x /sbin/genromfs ] || die "/sbin/genromfs is missing"
+       ;;
+  cram|cramfs)
+       [ -x /sbin/mkcramfs ] || die "/sbin/mkcramfs is missing"
+       ;;
+  initramfs)
+       [ -x /bin/cpio ] || die "/bin/cpio is missing"
+       [ -x /usr/bin/find ] || die "/usr/bin/find is missing"
+       ;;
+  *)
+       die "Filesystem $INITRDFS on initrd is not supported"
+       ;;
 esac
 
 if [ -L "$target" ]; then
@@ -1851,51 +1068,27 @@ if [ ! -d "/lib/modules/$kernel" ]; then
        die "/lib/modules/$kernel is not a directory."
 fi
 
-if [ "$INITRDFS" != "initramfs" ]; then
-       if is_yes "$FB_SPLASH"; then
-               warn "Using fbsplash requires INITRDFS=initramfs; skipping fbsplash generation"
-               FB_SPLASH=no
-       fi
-       if is_yes "$FB_CON_DECOR"; then
-               warn "Using fbcondecor requires INITRDFS=initramfs; skipping fbcondecor generation"
-               FB_CON_DECOR=no
-       fi
-fi
-
-if is_yes "$USE_SUSPEND" && is_yes "$USE_TUXONICE"; then
-       warn "Tuxonice and mainline suspend are exclusive!"
-fi
-
-if is_yes "$FB_SPLASH"  && is_yes "$BOOT_SPLASH"; then
-       warn "bootsplash and fbsplash are exclusive!"
-fi
-
-if [ ! -f /proc/mounts ]; then
-       warn "WARNING: /proc filesystem not mounted, may cause wrong results or failure."
-fi
-
-if [ -d /usr/lib64 ]; then
-       _lib=lib64
-else
-       _lib=lib
+if [ "$kernel_version" -ge "002005" ]; then
+       modext=".ko"
 fi
-debug "Using libdir: $_lib"
 
 cache_modprobe_conf
 
 for n in $PREMODS; do
-       findmodule "$n"
+       find_module "$n"
 done
 
 if [ "$FBMODULE" ]; then
-       findmodule "$FBMODULE"
+       find_module "$FBMODULE"
 fi
 
 # allow forcing loading SCSI and/or IDE modules
+# XXX: where ADDSCSI cames from? drop?
 if is_yes "$ADDSCSI"; then
        find_modules_scsi
 fi
 
+# XXX: where ADDIDE cames from? drop?
 if is_yes "$ADDIDE"; then
        find_modules_ide
 fi
@@ -1908,27 +1101,31 @@ find_root "$fstab" || exit
 debug "Using $rootdev as device for rootfs"
 
 find_modules_for_devpath "$rootdev"
-[ -n "$rootdev_add" ] && find_modules_for_devpath "$rootdev_add"
 
-findmodule "-$rootFs"
+# if USE_MULTIPATH is path to device, scan that too
+# this is to bootstrap multipath setup into initrd.
+if ! is_no "$USE_MULTIPATH" && ! is_yes "$USE_MULTIPATH"; then
+       find_modules_multipath $USE_MULTIPATH
+fi
+
+find_module "-$rootFs"
 
 for n in $BASICMODULES; do
-       findmodule "$n"
+       find_module "$n"
 done
 
 if is_yes "$USE_TUXONICE"; then
-       findmodule "-lzf"
+       find_module "-lzf"
 fi
 
-if is_yes "$FB_SPLASH"; then
-       findmodule "-evdev"
-fi
+find_modules_fbsplash
 
 if [ -n "$ifneeded" -a -z "$MODULES" ]; then
        debug "No modules are needed -- not building initrd image."
        exit 0
 fi
 
+debug "Building initrd..."
 DESTDIR=$(mktemp -d -t initrd.XXXXXX) || die "mktemp failed"
 RCFILE="$DESTDIR/linuxrc"
 > "$RCFILE"
@@ -1945,14 +1142,12 @@ modules_install "$MODULES"
 mknod "$DESTDIR/dev/console" c 5 1
 mknod "$DESTDIR/dev/null" c 1 3
 mknod "$DESTDIR/dev/zero" c 1 5
+mknod "$DESTDIR/dev/urandom" c 1 9
 
-inst /bin/initrd-busybox /bin/initrd-busybox
+inst_exec $busybox /bin/initrd-busybox
 ln -s initrd-busybox $DESTDIR/bin/sh
-ln -s initrd-busybox $DESTDIR/bin/busybox # for older busyboxes who had /bin/busybox as EXEPATH
-
-if is_yes "$USEINSMODSTATIC"; then
-       inst "$INSMOD" /bin/insmod.static
-fi
+# for older busyboxes who had /bin/busybox as EXEPATH
+ln -s initrd-busybox $DESTDIR/bin/busybox
 
 add_linuxrc <<EOF
 #!/bin/sh
@@ -2026,8 +1221,11 @@ if is_yes "$USE_TUXONICE"; then
        initrd_gen_tuxonice
 fi
 
-if is_yes "$need_v86d"; then
-       initrd_gen_v86d
+find_modules_uvesafb
+initrd_gen_uvesafb
+
+if is_yes "$have_luks"; then
+       initrd_gen_luks
 fi
 
 if is_yes "$have_dmraid"; then
@@ -2044,7 +1242,7 @@ fi
 
 if is_yes "$have_nfs"; then
        initrd_gen_nfs
-elif is_yes "$USERAIDSTART" && is_yes "$have_md"; then
+elif is_yes "$have_md"; then
        initrd_gen_md
        if is_yes "$have_lvm"; then
                initrd_gen_lvm
@@ -2064,84 +1262,13 @@ fi
 # additional devs always needed
 [ ! -e "$DESTDIR/$rootdev_add" ] && inst $rootdev_add /dev
 
-if [ "$INITRDFS" = "initramfs" ]; then
-       inst_d /newroot
-       if [ "$rootdev" = "/dev/nfs" ]; then
-               echo "rootfs on NFS root=/dev/nfs"
-       else
-               [ ! -e "$DESTDIR/$rootdev" ] && inst $rootdev /dev
-       fi
-       # Parsing root parameter
-       # We support passing root as hda3 /dev/hda3 0303 0x0303 and 303
-       add_linuxrc <<-'EOF'
-               device=/dev/no_partition_found
-               eval "$(busybox awk -v c="$ROOT" '
-                       BEGIN {
-                               num_pattern_short = "[0-9a-f][0-9a-f][0-9a-f]";
-                               num_pattern = "[0-9a-f]" num_pattern_short;
-                               dev_pattern = "[hms][a-z][a-z]([0-9])+";
-                               partition = "no_partition_found";
-                               min = -1; maj = -1;
-
-                               sub("^0x", "", c);
-                               if (c ~ "^" num_pattern_short "$") sub("^", "0", c);
-                               if (c ~ "^" num_pattern  "$") {
-                                       maj = sprintf("%s",substr(c,1,2));
-                                       min = sprintf("%s",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=%s\nmin=%s",
-                                       partition, maj, min);
-                       }
-                       ' /proc/partitions)"
-               if [ "$device" != '/dev/no_partition_found' -a ! -b $device ]; then
-                       mknod $device b $maj $min
-               fi
-       EOF
-
-       add_linuxrc <<-EOF
-               rootdev=$rootdev
-               rootfs=$rootFs
-       EOF
-
-       add_linuxrc <<-'EOF'
-               if [ "$device" = '/dev/no_partition_found' ]; then
-                       device=$rootdev
-               fi
-
-               mount -t $rootfs -r $device /newroot
-               init="$(echo "$CMDLINE" | busybox awk '/init=\// { gsub(/.*init=/,NIL,$0); gsub(/ .*/,NIL,$0); print }')"
-               if [ -z "$init" -o ! -x "/newroot$init" ]; then
-                       init=/sbin/init
-               fi
-       EOF
-
-       umount_all
-       busybox_applet switch_root
-       add_linuxrc <<-'EOF'
-               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
+if is_yes "$USE_UDEV"; then
+       initrd_gen_stop_udevd
+fi
 
-               echo "Failed to chroot!"
-       EOF
-       # we need /init being real file, not symlink, otherwise the initramfs will
-       # not be ran by pid 1 which is required for switch_root
-       mv $DESTDIR/linuxrc $DESTDIR/init
-       ln -s init $DESTDIR/linuxrc
+if [ "$INITRDFS" = "initramfs" ]; then
+       initrd_gen_initramfs_switchroot
 else
-       # other than initramfs
        umount_all
 fi
 
@@ -2157,51 +1284,67 @@ IMAGE=$(mktemp -t initrd.img-XXXXXX) || die "mktemp failed"
 
 debug "Creating $INITRDFS image $IMAGE"
 case "$INITRDFS" in
-       ext2)
-               IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
-               debug   "ext2 image size: $IMAGESIZE ($DESTDIR)"
-               if [ "$IMAGESIZE" -gt 4096 ]; then
-                       warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
-               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
+  ext2)
+       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
+
+       local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
+       debug "Mounting ext2 image $IMAGE to $tmpmnt"
+       mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
+       # We don't need this directory, so let's save space
+       rm -rf "$tmpmnt"/lost+found
+
+       debug "Copy recursively $DESTDIR -> $tmpmnt"
+       cp -a $DESTDIR/* $tmpmnt
+       umount "$IMAGE"
+       rmdir "$tmpmnt"
+
+       ;;
+  rom|romfs)
+       genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD initrd for kernel $kernel"
+       ;;
+  cram|cramfs)
+       mkcramfs "$DESTDIR" "$IMAGE"
+       ;;
+  initramfs)
+       (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
+       ;;
+  *)
+       die "Filesystem $INITRDFS not supported by $PROGRAM"
+esac
 
-               local tmpmnt=$(mktemp -d -t initrd.mnt-XXXXXX)
-               debug "Mounting ext2 image $IMAGE to $tmpmnt"
-               mount -o loop -t ext2 "$IMAGE" "$tmpmnt"
-               # We don't need this directory, so let's save space
-               rm -rf "$tmpmnt"/lost+found
+# TODO: figure out this automatically
+CONFIG_BLK_DEV_RAM_SIZE=4096
 
-               debug "Copy recursively $DESTDIR -> $tmpmnt"
-               cp -a $DESTDIR/* $tmpmnt
-               umount "$IMAGE"
-               rmdir "$tmpmnt"
+IMAGESIZE=$(du -ks $DESTDIR | awk '{print int(($1+1023+512)/1024)*1024}')
+debug  "image size: $IMAGESIZE KiB ($DESTDIR)"
+if [ "$IMAGESIZE" -gt $CONFIG_BLK_DEV_RAM_SIZE ]; then
+       warn "Your image size is larger than $CONFIG_BLK_DEV_RAM_SIZE, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
+fi
 
+if ! is_no "$COMPRESS"; then
+       tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
+       compressor=$(find_compressor "$COMPRESS")
+       debug "Compressing $target with $compressor"
+
+       # TODO: the image name (specified from kernel.spec) already contains
+       # extension, which is .gz most of the time.
+       case "$compressor" in
+       xz)
+               # don't use -9 here since kernel won't understand it
+               xz --format=xz --check=crc32 --lzma2=preset=6e,dict=1MiB < "$IMAGE" > "$tmp"
                ;;
-       rom|romfs)
-               genromfs -f "$IMAGE" -d "$DESTDIR" -V "PLD initrd for kernel $kernel"
-               IMAGESIZE=$(stat -c %s $IMAGE | awk '{print int((($1/1024)+1023)/1024)*1024}')
-               debug "Image size for romfs: ${IMAGESIZE}KiB ($IMAGE)"
-               if [ "$IMAGESIZE" -gt 4096 ]; then
-                       warn "Your image size is larger than 4096, Be sure to boot kernel with ramdisk_size=$IMAGESIZE!"
-               fi
+       lzma)
+               xz --format=lzma -9 < "$IMAGE" > "$tmp"
                ;;
-       cram|cramfs)
-               mkcramfs "$DESTDIR" "$IMAGE"
+       bzip2)
+               bzip2 -9 < "$IMAGE" > "$tmp"
                ;;
-       initramfs)
-               (cd $DESTDIR; find . | cpio --quiet -H newc -o > "$IMAGE")
+       gzip)
+               gzip -9 < "$IMAGE" > "$tmp"
                ;;
-       *)
-               echo "Filesystem $INITRDFS not supported by $PROGRAM";
-esac
-
-if is_yes "$COMPRESS"; then
-       tmp=$(mktemp "$target".XXXXXX) || die "mktemp failed"
-       debug "Compressing $target"
-       gzip -9 < "$IMAGE" > "$tmp"
+       esac
        mv -f "$tmp" "$target"
 else
        cp -a "$IMAGE" "$target"
This page took 0.105647 seconds and 4 git commands to generate.