#!/bin/bash --norc

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

umask 0022

export MALLOC_PERTURB_=204

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

VERSION=5.0.4

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

IMAGESIZE=8000
PRESCSIMODS="sd_mod"
fstab="/etc/fstab"

DYNAMIC_DEV=
if [ -f /etc/udev/udev.conf ]; then
    DYNAMIC_DEV="--movedev"
fi

vecho()
{
    NONL=""
    if [ "$1" == "-n" ]; then
        NONL="-n"
        shift
    fi
    [ -n "$verbose" ] && echo $NONL "$@"
}

error()
{
    NONL=""
    if [ "$1" == "-n" ]; then
        NONL="-n"
        shift
    fi
    echo $NONL "$@" >&2
}

usage () {
    if [ "$1" == "-n" ]; then
        cmd=echo
    else
        cmd=error
    fi

    $cmd "usage: `basename $0` [--version] [--help] [-v] [-f] [--preload <module>]"
    $cmd "       [--omit-scsi-modules] [--omit-raid-modules] [--omit-lvm-modules]"
    $cmd "       [--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]"
    $cmd "       [--builtin=<module>] <initrd-image> <kernel-version>"
    $cmd ""
    $cmd "       (ex: `basename $0` /boot/initrd-2.2.5-15.img 2.2.5-15)"

    if [ "$1" == "-n" ]; then
        exit 0
    else
        exit 1
    fi
}

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

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

findmodule() {
    skiperrors=""

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

    local modName=$1

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

    if [ $(echo $modName | cut -b1) = "-" ]; then
	skiperrors=--skiperrors
	modName=$(echo $modName | cut -b2-)
    fi

    case "$MODULES " in
        *"/$modName.ko "*) return ;;
    esac

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

    # special cases
    if [ "$modName" = "i2o_block" ]; then
	findmodule i2o_core
	findmodule -i2o_pci
	modName="i2o_block"
    elif [ "$modName" = "ppa" ]; then
	findmodule parport
	findmodule parport_pc
	modName="ppa"
    elif [ "$modName" = "sbp2" ]; then
	findmodule ieee1394
	findmodule ohci1394
	modName="sbp2"
    else
	moduledep $modName
	for i in $deps; do
	    findmodule $i
	done
    fi

    for modExt in o.gz o ko ; do
	if [ -d /lib/modules/$kernel/updates ]; then
	    fmPath=`(cd /lib/modules/$kernel/updates; echo find . -name $modName.$modExt -type f | /sbin/nash --quiet) | /bin/awk {'print $1; exit;'}`
	fi

	if [ -f /lib/modules/$kernel/updates/$fmPath ]; then
	    fmPath=updates/$fmPath
	    break
	fi

	fmPath=`(cd /lib/modules/$kernel; echo find . -name $modName.$modExt -type f | /sbin/nash --quiet) | /bin/awk {'print $1; exit;'}`
	if [ -f /lib/modules/$kernel/$fmPath ]; then
	    break
	fi
    done

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

        # ignore the absence of the scsi modules
	for n in $PRESCSIMODS; do
	    if [ "$n" = "$modName" ]; then
		return;
	    fi
	done;

	if [ -n "$allowmissing" ]; then
	    error "WARNING: No module $modName found for kernel $kernel, continuing anyway"
	    return
	fi

	error "No module $modName found for kernel $kernel, aborting."
	exit 1
    fi

    # only need to add each module once
    MODULES="$MODULES $fmPath"
}

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

readlink() {
    echo readlink "$1" | /sbin/nash --quiet
}

findstoragedriver () {
    for device in $@ ; do
        case " $handledevices " in
            *" $device "*)
                continue ;;
            *) handleddevices="$handleddevices $device" ;;
        esac
        if [[ "$device" =~ "md[0-9]+" ]]; then
            vecho "Found RAID component $device"
            handleraid "$device"
            continue
        fi
        vecho "Looking for driver for device $device"
        sysfs=$(find /sys/block -name $device -type d)
        [ -z "$sysfs" ] && return
        pushd $sysfs >/dev/null 2>&1
        while [ ! -L device ]; do
            [ "$PWD" = "/sys" ] && continue 2
            cd ..
        done
        cd $(readlink ./device)
        while [ ! -f modalias ]; do
            [ "$PWD" = "/sys/devices" ] && continue 2
            cd ..
        done
        modalias=$(cat modalias)
        for driver in $(modprobe --set-version $kernel --show-depends $modalias 2>/dev/null| awk '{ print gensub(".*/","","g",$2) }') ; do
            findmodule ${driver%%.ko}
        done
        popd >/dev/null 2>&1
    done
}

handleraid() {
    local start=0

    if [ -n "$noraid" -o ! -f /proc/mdstat ]; then
        return 0
    fi

    levels=$(grep "^$1[	 ]*:" /proc/mdstat | \
        awk '{ print $4 }')
    devs=$(grep "^$1[	 ]*:" /proc/mdstat | \
        awk '{ print gensub("\\[[0-9]*\\]","","g",gensub("^md.*raid[0-9]*","","1")) }')

    for level in $levels ; do
	case $level in
	linear)
	    findmodule linear
	    start=1
	    ;;
	multipath)
	    findmodule multipath
	    start=1
	    ;;
	raid[01456])
	    findmodule $level
	    start=1
	    ;;
	*)
	    error "raid level $level (in /proc/mdstat) not recognized"
	    ;;
	esac
    done
    findstoragedriver $devs
    if [ "$start" = 1 ]; then
        raiddevices="$raiddevices $1"
    fi
    return $start
}

handlelvordev() {
    local vg=`lvs --noheadings -o vg_name $1 2>/dev/null`
    if [ -n "$vg" ]; then
        vg=`echo $vg` # strip whitespace
        case " $vg_list " in
        *" $vg "*)
            ;;
        *)
            vg_list="$vg_list $vg"
            for device in `vgdisplay -v $vg 2>/dev/null | sed -n 's/PV Name//p'`; do
                findstoragedriver ${device##/dev/}
            done
            ;;
        esac
    else
        findstoragedriver ${1##/dev/}
    fi
}

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

	--with-usb)
	    withusb=yes
	    ;;

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

	    basicmodules="$basicmodules $modname"
	    ;;

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

	--version)
	    echo "mkinitrd: version $VERSION"
	    exit 0
	    ;;

	-v)
	    verbose=-v
	    ;;

	--nocompress)
	    compress=""
	    ;;

	--ifneeded)
	    # legacy
	    ;;

	-f)
	    force=1
	    ;;
	--preload*)
	    if echo $1 | grep -q '=' ; then
	    	modname=`echo $1 | sed 's/^--preload=//'`
	    else
		modname=$2
		shift
	    fi
	    PREMODS="$PREMODS $modname"
	    ;;
	--omit-scsi-modules)
	    PRESCSIMODS=""
	    noscsi=1;
	    ;;
	--omit-raid-modules)
	    noraid=1;
	    ;;
	--omit-lvm-modules)
	    nolvm=1
	    ;;
	--image-version)
	    img_vers=yes
	    ;;
	--noudev)
	    DYNAMIC_DEV=
	    ;;
	--allow-missing)
	    allowmissing=yes
	    ;;
	--noresume)
	    noresume=1
	    ;;
        --help)
            usage -n
            ;;
	*)
	    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

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

if [ -z "$force" -a -f $target ]; then
    error "$target already exists."
    exit 1
fi

if [ ! -d /lib/modules/$kernel ]; then
    error 'No modules available for kernel "'${kernel}'".'
    exit 1
fi

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

vecho "Creating initramfs"
modulefile=/etc/modprobe.conf

# find a temporary directory which doesn't use tmpfs
TMPDIR=""
for t in /tmp /var/tmp /root ${PWD}; do
    if [ ! -d $t ]; then continue; fi
    if ! echo access -w $t | /sbin/nash --quiet; then continue; fi

    fs=$(df -T $t 2>/dev/null | awk '{line=$1;} END {printf $2;}')
    if [ "$fs" != "tmpfs" ]; then
	TMPDIR=$t
	break
    fi
done

if [ -z "$TMPDIR" ]; then
    error "no temporary directory could be found."
    exit 1
fi

if [ $TMPDIR = "/root" -o $TMPDIR = "${PWD}" ]; then
    error "WARNING: using $TMPDIR for temporary files"
fi

for n in $PREMODS; do
	findmodule $n
done

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

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

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

    if [ -f $modulefile ]; then
	scsimodules=`grep "alias[[:space:]]\+scsi_hostadapter" $modulefile | grep -v '^[ 	]*#' | LC_ALL=C sort -u | awk '{ print $3 }'`

	if [ -n "$scsimodules" ]; then
	    for n in $PRESCSIMODS; do
		findmodule $n
	    done

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

# If we have ide devices and module ide, do the right thing
ide=/proc/ide/ide*
if [ -n "$ide" ]; then
    findmodule -ide-disk
fi

# If we use LVM, include lvm-mod
if [ -z "$nolvm" ]; then
    if [ -f /proc/lvm/global  ]; then
        if  grep -q '^VG:' /proc/lvm/global ; then
	    findmodule -dm-mod
        fi
    fi

    if [ -x /sbin/dmsetup -a -e /dev/mapper/control ]; then
	dmout=$(/sbin/dmsetup ls 2>/dev/null)
	if [ "$dmout" != "No devices found" -a "$dmout" != "" ]; then
	    findmodule -dm-mod
	fi
    fi
fi

# If we have dasd devices, include the necessary modules (S/390)
if [ -d /proc/dasd ]; then
    findmodule -dasd_mod
    findmodule -dasd_eckd_mod
    findmodule -dasd_fba_mod
fi

# check to see if we need to set up a loopback filesystem
rootdev=$(awk '/^[ \t]*[^#]/ { if ($2 == "/") { print $1; }}' $fstab)
# check if it's root by label
if echo $rootdev | cut -c1-6 | grep -q "LABEL=" ; then
    majmin=$(stat -c "%t:%T" /dev/root)
    if [ -n "$majmin" ]; then
        dev=$(find /sys/block -name dev | while read device ; do \
	      echo "$majmin" | cmp -s $device && echo $device ; done \
	      | sed -e 's,.*/\([^/]\+\)/dev,\1,' )
	if [ -n "$dev" ]; then
            vecho "Found root device $dev for $rootdev"
                rootdev=$dev
	fi
    fi
fi
if echo $rootdev | cut -d/ -f3 | grep -q loop ; then
    key="^# $(echo $rootdev | cut -d/ -f3 | tr '[a-z]' '[A-Z]'):"
    if ! grep "$key" $fstab >> /dev/null; then
	error "The root filesystem is on a $rootdev, but there is no magic entry in $fstab"
	error "for this device. Consult the mkinitrd man page for more information"
	error "loopback root."
	exit 1
    fi

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

    basicmodules="$basicmodules -loop"
    if [ "$loopFs" = "vfat" -o "$loopFs" = "msdos" ]; then
	basicmodules="$basicmodules -fat"
    fi
    basicmodules="$basicmodules -${loopFs}"
# check if the root fs is on a logical volume
# this check must be last
else
    handlelvordev $rootdev
fi

rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' $fstab)
rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' $fstab \
    | sed -e 's/\(^rw,\|rw,$\)//' -e 's/,rw,/,/' -e 's/^rw$/ro/')

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

# find the first swap dev which would get used for swsusp
swsuspdev=$(awk '/^[ \t]*[^#]/ { if ($3 == "swap") { print $1; }}' $fstab | head -n 1)
if ! echo $swsuspdev | cut -c1-6 | grep -q "LABEL=" ; then
    handlelvordev $swsupdev
fi

if [ -n "$vg_list" ]; then
    findmodule -dm-mod
    # DM requires all of these to be there in case someone used the
    # feature.  broken.  (#132001)
    findmodule -dm-mirror
    findmodule -dm-zero
    findmodule -dm-snapshot
fi

for n in $basicmodules; do
    findmodule $n
done

vecho "Using modules: $MODULES"

MNTIMAGE=`mktemp -d ${TMPDIR}/initrd.XXXXXX`
IMAGE=`mktemp ${TMPDIR}/initrd.img.XXXXXX`
RCFILE=$MNTIMAGE/init

cemit()
{
    cat >> $RCFILE
}

emit()
{
    NONL=""
    if [ "$1" == "-n" ]; then
        NONL="-n"
        shift
    fi
    echo $NONL "$@" >> $RCFILE
}

if [ -z "$MNTIMAGE" -o -z "$IMAGE" ]; then
    error "Error creating temporaries.  Try again"
    exit 1
fi

mkdir -p $MNTIMAGE
mkdir -p $MNTIMAGE/lib
mkdir -p $MNTIMAGE/bin
mkdir -p $MNTIMAGE/etc
mkdir -p $MNTIMAGE/dev
mkdir -p $MNTIMAGE/loopfs
mkdir -p $MNTIMAGE/proc
mkdir -p $MNTIMAGE/sys
mkdir -p $MNTIMAGE/sysroot
ln -s bin $MNTIMAGE/sbin

if [ -e /etc/fstab.sys ]; then
    inst /etc/fstab.sys "$MNTIMAGE/etc/fstab.sys"
fi
inst /sbin/nash "$MNTIMAGE/bin/nash"
inst /sbin/insmod.static "$MNTIMAGE/bin/insmod"
ln -s /sbin/nash $MNTIMAGE/sbin/modprobe
ln -s /sbin/nash $MNTIMAGE/sbin/setuproot
ln -s /sbin/nash $MNTIMAGE/sbin/preswitchroot
ln -s /sbin/nash $MNTIMAGE/sbin/switchroot

if [ -n "$DYNAMIC_DEV" ]; then
    ln -s /sbin/nash $MNTIMAGE/sbin/hotplug
fi

for MODULE in $MODULES; do
    if [ -x /usr/bin/strip ]; then
	/usr/bin/strip -g $verbose /lib/modules/$kernel/$MODULE -o $MNTIMAGE/lib/$(basename $MODULE)
    else
	cp $verbose -a /lib/modules/$kernel/$MODULE $MNTIMAGE/lib
    fi
done

# mknod'ing the devices instead of copying them works both with and
# without devfs...
mkdir $MNTIMAGE/dev/mapper

mknod $MNTIMAGE/dev/console c 5 1
mknod $MNTIMAGE/dev/null c 1 3
mknod $MNTIMAGE/dev/ram b 1 1
mknod $MNTIMAGE/dev/rtc c 10 135
mknod $MNTIMAGE/dev/systty c 4 0
mknod $MNTIMAGE/dev/tty c 5 0
mknod $MNTIMAGE/dev/zero c 1 5

for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    mknod $MNTIMAGE/dev/tty$i c 4 $i
done
for i in 0 1 2 3 ; do
    mknod $MNTIMAGE/dev/ttyS$i c 4 $(($i + 64))
done

# FIXME -- this can really go poorly with clvm or duplicate vg names.
# nash should do lvm probing for us and write its own configs.
if [ -n "$vg_list" ]; then
    inst /sbin/lvm.static "$MNTIMAGE/bin/lvm"
    if [ -f /etc/lvm/lvm.conf ]; then
	cp $verbose --parents /etc/lvm/lvm.conf $MNTIMAGE/
    fi
fi

echo -n >| $RCFILE
cemit << EOF
#!/bin/nash

mount -t proc /proc /proc
setquiet
echo Mounting proc filesystem
echo Mounting sysfs filesystem
mount -t sysfs /sys /sys
EOF

if [ -n "$DYNAMIC_DEV" ]; then
    cemit <<EOF
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev
mkdir /dev/pts
mkdir /dev/shm
mkdir /dev/mapper
echo Creating initial device nodes
mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/ram b 1 1
mknod /dev/rtc c 10 135
mknod /dev/systty c 4 0
mknod /dev/tty c 5 0
mknod /dev/zero c 1 5
EOF

    # XXX really we need to openvt too, in case someting changes the
    # color palette and then changes vts on fbcon before gettys start.
    # (yay, fbcon bugs!)
    for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 ; do
        emit "mknod /dev/tty$i c 4 $i"
    done

    for i in 0 1 2 3 ; do
        emit "mknod /dev/ttyS$i c 4 $(($i + 64))"
    done

    emit "echo Setting up hotplug."
    emit "echo -n /sbin/hotplug > /proc/sys/kernel/hotplug"

    emit "echo Creating block device nodes."
    emit "mkblkdevs"
fi

for MODULE in $MODULES; do
    text=""
    module=`echo $MODULE | sed "s|.*/||" | sed "s/.k\?o$//"`
    fullmodule=`echo $MODULE | sed "s|.*/||"`

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

    if [ -n "$options" ]; then
        vecho "Adding module $module$text with options $options"
    else
        vecho "Adding module $module$text"
    fi
    emit "echo \"Loading $fullmodule module\""
    emit "insmod /lib/$fullmodule $options"

    # Hack - we need a delay after loading usb-storage to give things
    #        time to settle down before we start looking a block devices
    if [ "$module" = "usb-storage" ]; then
	emit "echo Waiting 8 seconds for driver initialization."
	emit "sleep 8"
    fi
    if [ "$module" = "zfcp" -a -f /etc/zfcp.conf ]; then
	emit "echo Waiting 2 seconds for driver initialization."
        emit "sleep 2"
        cat /etc/zfcp.conf | grep -v "^#" | tr "A-Z" "a-z" | while read DEVICE SCSIID WWPN SCSILUN FCPLUN; do
        cemit <<EOF 
echo -n $WWPN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/port_add
echo -n $FCPLUN > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/$WWPN/unit_add
echo -n 1 > /sys/bus/ccw/drivers/zfcp/${DEVICE/0x/}/online
EOF
        done
    fi
done

if [ -n "$vg_list" ]; then
    emit "echo Making device-mapper control node"
    emit "mkdmnod"
fi

# HACK: module loading + device creation isn't necessarily synchronous...
# this will make sure that we have all of our devices before trying
# things like RAID or LVM
if [ -n "$DYNAMIC_DEV" ]; then
    emit "mkblkdevs"
fi

if [ -n "$raiddevices" ]; then
    for dev in $raiddevices; do
	cp -a /dev/${dev} $MNTIMAGE/dev
	emit "raidautorun /dev/${dev}"
    done
fi

if [ -n "$vg_list" ]; then
    emit "echo Scanning logical volumes"
    emit "lvm vgscan --ignorelockingfailure"
    emit "echo Activating logical volumes"
    emit "lvm vgchange -ay --ignorelockingfailure $vg_list"
fi

if [ -n "$loopDev" ]; then
    mkdir /initrd
    cp -a $loopDev $MNTIMAGE/dev
    cp -a $rootdev $MNTIMAGE/dev
    emit "echo Mounting device containing loopback root filesystem."
    emit "mount -t $loopFs $loopDev /loopfs"
    emit "echo Setting up loopback device $rootdev"
    emit "losetup $rootdev /loopfs$loopFile"
fi

if [ -z "$noresume" ]; then
    emit "resume $swsuspdev"
fi

emit "echo Creating root device."
emit "mkrootdev /dev/root"
rootdev=/dev/root

emit "echo Mounting root filesystem"
emit "mount -o $rootopts --ro -t $rootfs $rootdev /sysroot"

emit "echo Setting up root fs"
emit "setuproot $DYNAMIC_DEV /sysroot"

emit "echo Running preswitchroot"
emit "preswitchroot /sysroot"

emit "echo Switching to new root and running init"
emit "exec switchroot $DYNAMIC_DEV /sysroot"

chmod +x $RCFILE

(cd $MNTIMAGE; find . | cpio --quiet -c -o) >| $IMAGE || exit 1

if [ -n "$compress" ]; then
    gzip -9 < $IMAGE >| $target || rc=1
else
    cp -a $IMAGE $target || rc=1
fi
rm -rf $MNTIMAGE $IMAGE
if [ -n "$MNTPOINT" ]; then rm -rf $MNTPOINT ; fi

exit $rc
