#!/bin/sh

. /etc/initrd.defaults
. /etc/initrd.scripts

# Clean input/output
exec >${CONSOLE} <${CONSOLE} 2>&1

if [ "$$" != "1" ]; then
    echo "/linuxrc has to be run as the init process as the one"
    echo "with a PID of 1. Try adding init=/linuxrc to the"
    echo "kernel command line or running "exec /linuxrc"."
    exit 1
fi

mount -t proc -o noexec,nosuid,nodev proc /proc >/dev/null 2>&1
mount -o remount,rw / >/dev/null 2>&1
mount -t tmpfs -o rw,nosuid,nodev,relatime,mode=755 none /run 2>&1

/bin/busybox --install -s

if [ "$0" = "/init" ]; then
    rm -f /linuxrc
fi

# make sure that /sbin and /usr/sbin are in PATH
# dmraid for instance is in /usr/sbin
PATH="${PATH}:/sbin:/usr/sbin"

CMDLINE=$(cat /proc/cmdline)
FAKE_ROOT=""
FAKE_INIT=""
REAL_INIT=""
FAKE_ROOTFLAGS=""
INIT_OPTS=""
CRYPT_SILENT=0
QUIET=""

mkdir -p /etc/cmdline /etc/modprobe.d
for x in ${CMDLINE}; do
    case "${x}" in
        real_root=*)
            REAL_ROOT=${x#*=}
        ;;
        root=*)
            FAKE_ROOT=${x#*=}
        ;;
        subdir=*)
            SUBDIR=${x#*=}
        ;;
        real_init=*)
            REAL_INIT=${x#*=}
        ;;
        init=*)
            FAKE_INIT=${x#*=}
        ;;
        init_opts=*)
            INIT_OPTS=${x#*=}
        ;;
        cdroot)
            CDROOT=1
        ;;
        cdroot=*)
            CDROOT=1
            CDROOT_DEV=${x#*=}
        ;;
        cdroot_type=*)
            CDROOT_TYPE=${x#*=}
        ;;
        cdroot_marker=*)
            CDROOT_MARKER=${x#*=}
        ;;
        loop=*)
            LOOP=${x#*=}
        ;;
        looptype=*)
            LOOPTYPE=${x#*=}
        ;;
        isoboot=*)
            ISOBOOT=${x#*=}
        ;;
        domdev)
            USE_MDEV=1
        ;;
        dolvm|rd.lvm.lv=*)
            USE_LVM_NORMAL=1
        ;;
        domdadm|rd.md.uuid=*)
            USE_MDADM=1
        ;;
        dodmraid|rd.dm.uuid=*)
            USE_DMRAID_NORMAL=1
        ;;
        dodmraid=*|rd.dm.uuid=*)
            DMRAID_OPTS=${x#*=}
            USE_DMRAID_NORMAL=1
        ;;
        domultipath)
            good_msg "Booting with multipath activated."
            USE_MULTIPATH_NORMAL=1
        ;;
        dozfs=*)
            ZFS_OPTS=${x#*=}
            if [ "${ZFS_OPTS}" = "force" ]; then
                ZPOOL_FORCE=-f
            fi
        ;;
        quiet)
            QUIET=1
        ;;
        debug)
            DEBUG="yes"
        ;;
        scandelay=*)
            SDELAY=${x#*=}
        ;;
        scandelay)
            SDELAY=3
        ;;
        doload=*)
            MDOLIST=${x#*=}
            MDOLIST=$(echo ${MDOLIST} | sed -e "s/,/ /g")
        ;;
        nodetect)
            NODETECT=1
        ;;
        noload=*)
            MLIST=${x#*=}
            MLIST="$(echo ${MLIST} | sed -e "s/,/ /g")"
            export MLIST
        ;;
        CONSOLE=*|console=*)
            CONSOLE=${x#*=}
            CONSOLE=$(basename ${CONSOLE})
        ;;
        splash)
            PLYMOUTH=1
        ;;
        splash=*)
            FBSPLASH=1
        ;;
        lvmraid=*)
            RAID_DEVICES="${x#*=}"
            RAID_DEVICES="$(echo ${RAID_DEVICES} | sed -e "s/,/ /g")"
            USE_LVM_NORMAL=1
        ;;
        part=*)
            MDPART=${x#*=}
        ;;
        part|partitionable)
            MDPART=1
        ;;
        ip=*)
            IP=${x#*=}
        ;;
        nfsroot=*)
            NFSROOT=${x#*=}
        ;;

        netroot=iscsi:*)
            x=${x#*=}
            parse_dracut_iscsi_root "${x}"
        ;;
        iscsi_initiatorname=*|iscsi_initiator=*)
            ISCSI_INITIATORNAME=${x#*=}
        ;;
        iscsi_target=*)
            ISCSI_TARGET=${x#*=}
        ;;
        iscsi_tgpt=*)
            ISCSI_TGPT=${x#*=}
        ;;
        iscsi_address=*)
            ISCSI_ADDRESS=${x#*=}
        ;;
        iscsi_port=*)
            ISCSI_PORT=${x#*=}
        ;;
        iscsi_username=*)
            ISCSI_USERNAME=${x#*=}
        ;;
        iscsi_password=*)
            ISCSI_PASSWORD=${x#*=}
        ;;
        iscsi_username_in=*)
            ISCSI_USERNAME_IN=${x#*=}
        ;;
        iscsi_password_in=*)
            ISCSI_PASSWORD_IN=${x#*=}
        ;;
        iscsi_debug=*)
            ISCSI_DEBUG=${x#*=}
        ;;
        iscsi_noibft)
            ISCSI_NOIBFT=1
        ;;

        crypt_root=*)
            # kept for backward compatibility
            CRYPT_ROOTS=${x#*=}
        ;;
        crypt_swap=*)
            # kept for backward compatibility
            CRYPT_SWAPS=${x#*=}
        ;;

        crypt_roots=*)
            # The first entry will be the one that
            # is going to be mapped to ${REAL_ROOT}.
            # Multiple "roots" devices are needed
            # in order to support multiple dmcrypts
            # aggregated through software raid arrays.
            CRYPT_ROOTS="${CRYPT_ROOTS} ${x#*=}"
        ;;
        crypt_swaps=*)
            CRYPT_SWAPS="${CRYPT_SWAPS} ${x#*=}"
        ;;

        root_key=*)
            CRYPT_ROOT_KEY=${x#*=}
        ;;
        root_keydev=*)
            CRYPT_ROOT_KEYDEV=${x#*=}
        ;;
        root_trim=*)
            CRYPT_ROOT_TRIM=${x#*=}
        ;;

        swap_key=*)
            CRYPT_SWAP_KEY=${x#*=}
        ;;
        swap_keydev=*)
            CRYPT_SWAP_KEYDEV=${x#*=}
        ;;
        real_resume=*|resume=*)
            REAL_RESUME=${x#*=}
        ;;
        noresume)
            NORESUME=1
        ;;
        crypt_silent)
            CRYPT_SILENT=1
        ;;
        real_rootflags=*)
            REAL_ROOTFLAGS=${x#*=}
        ;;
        rootflags=*)
            FAKE_ROOTFLAGS=${x#*=}
        ;;
        rootfstype=*)
            ROOTFSTYPE=${x#*=}
        ;;
        keymap=*|vconsole.keymap=*)
            USE_KEYMAP=${x#*=}
        ;;
        aufs)
            USE_AUFS=1
        ;;
        overlayfs)
            USE_OVERLAYFS=1
        ;;
    esac
done

quiet_kmsg

maybe_setup_ld_cache

real_init_init

is_livecd || {
    real_root_init && zfs_real_root_init;
}

cmdline_hwopts

mount_devfs

mount_sysfs

devmgr_init

splash_init

modules_init

# If we're mdev, we better wait for all the modules to be loaded.
is_mdev && splashcmd init

cd /

start_iscsi

# Apply scan delay if specified
sdelay

start_volumes
zfs_start_volumes

setup_keymap

# Initialize LUKS root device except for livecd's
is_livecd || start_luks

start_volumes
zfs_start_volumes

# Initialize resume from hibernation
is_livecd || resume_init

mkdir -p "${NEW_ROOT}"
CHROOT="${NEW_ROOT}"

# Run debug shell if requested
rundebugshell "before setting up the root filesystem"

# Setup Live system mounts
is_livecd && livecd_init

# Determine root device
rootdev_init

# If CD root is set determine the looptype to boot
is_livecd && livecd_mount

# Re-run this here, which makes sure that it at least had a chance
# to be called.
ensure_initramfs_mounts

splashcmd hasroot "${NEW_ROOT}"

# Execute script on the cdrom just before boot to update
# things if necessary
is_livecd && cd_update

if [ "${SUBDIR}" != "" ] && [ -e "${CHROOT}/${SUBDIR}" ]; then
    good_msg "Entering ${SUBDIR} to boot"
    CHROOT="${CHROOT}/${SUBDIR}"
fi

verbose_kmsg

devmgr_terminate

good_msg "Booting (initramfs)"

cd "${CHROOT}"

move_mounts_to_chroot

# Run debug shell if requested
rundebugshell "before entering switch_root"

exec /sbin/switch_root -c "/dev/console" "${CHROOT}" \
    "${REAL_INIT}" "${INIT_OPTS}"

# If we get here, something bad has happened
splashcmd verbose

bad_msg "A fatal error has occurred since ${REAL_INIT} did not"
bad_msg "boot correctly. Trying to open a shell..."

exec /bin/bash
exec /bin/sh
exec /bin/ash
exec /bin/dash
exec sh
