Support module options set in /etc/module.d, amend cmdline options patch
[genkernel.git] / defaults / linuxrc
old mode 100644 (file)
new mode 100755 (executable)
index 8e39fc5..90099c8
@@ -20,7 +20,7 @@ then
        exit 1
 fi
 
-mount -t proc proc /proc >/dev/null 2>&1
+mount -t proc -o noexec,nosuid,nodev proc /proc >/dev/null 2>&1
 mount -o remount,rw / >/dev/null 2>&1
 
 # Set up symlinks
@@ -29,59 +29,57 @@ mount -o remount,rw / >/dev/null 2>&1
 if [ "$0" = '/init' ]
 then
        [ -e /linuxrc ] && rm /linuxrc
-        
-       if [ -e /bin/lvm ]
-       then
-               ln -s /bin/lvm /bin/vgscan
-               ln -s /bin/lvm /bin/vgchange
-       fi
 fi
 
 quiet_kmsg
 
-CMDLINE=`cat /proc/cmdline`
+CMDLINE=$(cat /proc/cmdline)
 # Scan CMDLINE for any specified real_root= or cdroot arguments
-REAL_ROOT=''
 FAKE_ROOT=''
 REAL_ROOTFLAGS=''
+ROOTFSTYPE='auto'
 CRYPT_SILENT=0
+mkdir -p /etc/cmdline /etc/modprobe.d
 for x in ${CMDLINE}
 do
        case "${x}" in
-               real_root\=*)
-                       REAL_ROOT=`parse_opt "${x}"`
+               real_root=*)
+                       REAL_ROOT=${x#*=}
                ;;
-               root\=*)
-                       FAKE_ROOT=`parse_opt "${x}"`
+               root=*)
+                       FAKE_ROOT=${x#*=}
                ;;
-               subdir\=*)
-                       SUBDIR=`parse_opt "${x}"`
+               subdir=*)
+                       SUBDIR=${x#*=}
                ;;
-               real_init\=*)
-                       REAL_INIT=`parse_opt "${x}"`
+               real_init=*)
+                       REAL_INIT=${x#*=}
                ;;
-               init_opts\=*)
-                       INIT_OPTS=`parse_opt "${x}"`
+               init_opts=*)
+                       INIT_OPTS=${x#*=}
                ;;
                # Livecd options
                cdroot)
                        CDROOT=1
                ;;
-               cdroot\=*)
+               cdroot=*)
                        CDROOT=1
-                       CDROOT_DEV=`parse_opt "${x}"`
+                       CDROOT_DEV=${x#*=}
                ;;
-               cdroot_type\=*)
-                       CDROOT_TYPE=`parse_opt "${x}"`
+               cdroot_type=*)
+                       CDROOT_TYPE=${x#*=}
                ;;
                # Start livecd loop, looptype options
-               loop\=*)
-                       LOOP=`parse_opt "${x}"`
+               loop=*)
+                       LOOP=${x#*=}
                ;;
-               looptype\=*)
-                       LOOPTYPE=`parse_opt "${x}"`
+               looptype=*)
+                       LOOPTYPE=${x#*=}
                ;;
-               # Start Volume manager options 
+               isoboot=*)
+                       ISOBOOT=${x#*=}
+               ;;
+               # Start Volume manager options
                dolvm)
                        USE_LVM_NORMAL=1
                ;;
@@ -95,81 +93,123 @@ do
                dodmraid)
                        USE_DMRAID_NORMAL=1
                ;;
-               dodmraid\=*)
-                       DMRAID_OPTS=`parse_opt "${x}"`
+               dodmraid=*)
+                       DMRAID_OPTS=${x#*=}
                        USE_DMRAID_NORMAL=1
                ;;
-               doevms)
-                       USE_EVMS_NORMAL=1
-               ;;
-               doevms2)
-                       bad_msg 'Using doevms2 is deprecated, use doevms, instead.'
-                       USE_EVMS_NORMAL=1
+               dozfs*)
+                       USE_ZFS=1
+
+                       if [ "${x#*=}" = 'force' ]
+                       then
+                               ZPOOL_FORCE=-f
+                       fi
                ;;
                # Debug Options
                debug)
                        DEBUG='yes'
                ;;
-               # Scan delay options 
-               scandelay\=*)
-                       SDELAY=`parse_opt "${x}"`
+               # Scan delay options
+               scandelay=*)
+                       SDELAY=${x#*=}
                ;;
                scandelay)
-                       SDELAY=10
+                       SDELAY=3
                ;;
                # Module no-loads
-               doload\=*)
-                       MDOLIST=`parse_opt "${x}"`
-                       MDOLIST="`echo ${MDOLIST} | sed -e 's/,/ /g'`"
+               doload=*)
+                       MDOLIST=${x#*=}
+                       MDOLIST=$(echo ${MDOLIST} | sed -e 's/,/ /g')
                ;;
                nodetect)
                        NODETECT=1
                ;;
-               noload\=*)
-                       MLIST=`parse_opt "${x}"`
-                       MLIST="`echo ${MLIST} | sed -e 's/,/ /g'`"
+               noload=*)
+                       MLIST=${x#*=}
+                       MLIST="$(echo ${MLIST} | sed -e 's/,/ /g')"
                        export MLIST
                ;;
                # Redirect output to a specific tty
-               CONSOLE\=*|console\=*)
-                       CONSOLE=`parse_opt "${x}"`
-                       exec >${CONSOLE} <${CONSOLE} 2>&1
+               CONSOLE=*|console=*)
+                       CONSOLE=${x#*=}
+                       CONSOLE=$(basename ${CONSOLE})
+#                      exec >${CONSOLE} <${CONSOLE} 2>&1
                ;;
                # /dev/md
-               lvmraid\=*)
-                       RAID_DEVICES="`parse_opt ${x}`"
-                       RAID_DEVICES="`echo ${RAID_DEVICES} | sed -e 's/,/ /g'`"
+               lvmraid=*)
+                       RAID_DEVICES="${x#*=}"
+                       RAID_DEVICES="$(echo ${RAID_DEVICES} | sed -e 's/,/ /g')"
+                       USE_LVM_NORMAL=1
                ;;
-               part\=*)
-                       MDPART=`parse_opt "${x}"`
+               part=*)
+                       MDPART=${x#*=}
                ;;
                # NFS
-               ip\=*)
-                       IP=`parse_opt "${x}"`
+               ip=*)
+                       IP=${x#*=}
+               ;;
+               nfsroot=*)
+                       NFSROOT=${x#*=}
+               ;;
+               # iSCSI
+               iscsi_initiatorname=*)
+                       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#*=}
                ;;
-               nfsroot\=*)
-                       NFSROOT=`parse_opt "${x}"`
+               iscsi_username_in=*)
+                       ISCSI_USERNAME_IN=${x#*=}
                ;;
-               crypt_root\=*)
-                       CRYPT_ROOT=`parse_opt "${x}"`
+               iscsi_password_in=*)
+                       ISCSI_PASSWORD_IN=${x#*=}
                ;;
-               crypt_swap\=*)
-                       CRYPT_SWAP=`parse_opt "${x}"`
+               iscsi_debug=*)
+                       ISCSI_DEBUG=${x#*=}
                ;;
-               root_key\=*)
-                       CRYPT_ROOT_KEY=`parse_opt "${x}"`
+               iscsi_noibft)
+                       ISCSI_NOIBFT=1
                ;;
-               root_keydev\=*)
-                       CRYPT_ROOT_KEYDEV=`parse_opt "${x}"`
+               # Crypto
+               crypt_root=*)
+                       CRYPT_ROOT=${x#*=}
                ;;
-               swap_key\=*)
-                       CRYPT_SWAP_KEY=`parse_opt "${x}"`
+               crypt_swap=*)
+                       CRYPT_SWAP=${x#*=}
                ;;
-               swap_keydev\=*)
-                       CRYPT_SWAP_KEYDEV=`parse_opt "${x}"`
+               root_key=*)
+                       CRYPT_ROOT_KEY=${x#*=}
                ;;
-               real_resume\=*)
-                       REAL_RESUME=`parse_opt "${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
@@ -177,30 +217,96 @@ do
                crypt_silent)
                        CRYPT_SILENT=1
                ;;
-               real_rootflags\=*)
-                       REAL_ROOTFLAGS=`parse_opt "${x}"`
+               real_rootflags=*)
+                       REAL_ROOTFLAGS=${x#*=}
+               ;;
+               rootfstype=*)
+                       ROOTFSTYPE=${x#*=}
+               ;;
+               keymap=*)
+                       keymap=${x#*=}
+               ;;
+               aufs)
+                       USE_AUFS_NORMAL=1
                ;;
-               keymap\=*)
-                       keymap=`parse_opt "${x}"`
+               unionfs)
+                       if [ ! -x /sbin/unionfs ]
+                       then
+                               USE_UNIONFS_NORMAL=0
+                               bad_msg 'unionfs binary not found: aborting use of unionfs!'
+                       else
+                               USE_UNIONFS_NORMAL=1
+                       fi
+                       ;;
+               nounionfs)
+                       USE_UNIONFS_NORMAL=0
+                       ;;
+               *=*)
+                       case "${x%%=*}" in
+                       *.*)
+                               echo "${x#*.}" >> "/etc/module_options/${x%%.*}.conf"
+                       ;;
+                       esac
                ;;
        esac
 done
 
-if [ -z "${REAL_ROOT}" -a \( "${CDROOT}" -eq 0 \)  -a \( "${FAKE_ROOT}" != "/dev/ram0" \) ]
+if [ -z "${REAL_ROOT}" -a \( "${CDROOT}" = '0' \)  -a \( "${FAKE_ROOT}" != "/dev/ram0" \) ]
+then
+       REAL_ROOT="${FAKE_ROOT}"
+fi
+
+# Set variables based on the value of REAL_ROOT
+case "${REAL_ROOT}" in
+       ZFS=*)
+               ZFS_POOL=${REAL_ROOT#*=}
+               ZFS_POOL=${ZFS_POOL%%/*}
+               USE_ZFS=1
+       ;;
+       ZFS)
+               USE_ZFS=1
+       ;;
+esac
+
+# Verify that it is safe to use ZFS
+if [ "USE_ZFS" = "1" ]
 then
-       REAL_ROOT="${FAKE_ROOT}"        
+       if [ -x /sbin/zfs -a -x /sbin/zpool ]
+       then
+               MY_HWOPTS="${MY_HWOPTS} zfs"
+       else
+               USE_ZFS=0
+
+               [ -x /sbin/zfs ] || bad_msg '/sbin/zfs not found!'
+               [ -x /sbin/zpool ] || bad_msg '/sbin/zpool not found!'
+               bad_msg 'Aborting use of zfs!'
+       fi
 fi
 
 splash 'init'
 
-detect_sbp2_devices
 cmdline_hwopts
 
+# Mount devfs
+mount_devfs
+
 # Mount sysfs
 mount_sysfs
 
-# Setup hotplugging for firmware loading
-setup_hotplug
+# Start mdev
+if [ "${KV_2_6_OR_GREATER}" ]
+then
+       good_msg 'Activating mdev'
+
+       # Serialize hotplug events
+       touch /dev/mdev.seq
+
+       # Setup hotplugging for firmware loading
+       echo /sbin/mdev > /proc/sys/kernel/hotplug
+
+       # Setup mdev netlink socket daemon
+       ( cd /sys && mdev -s ) || bad_msg "Failed to receive dynamic updates from mdev"
+fi
 
 # Load modules listed in MY_HWOPTS if /lib/modules exists for the running kernel
 if [ -z "${DO_modules}" ]
@@ -223,11 +329,25 @@ else
        good_msg 'Skipping module load; no modules in the ramdisk!'
 fi
 
-# Delay if needed for USB hardware
+# Apply scan delay if specified
 sdelay
 
-# Start device manager
-start_dev_mgr
+# Setup slow USB bits
+setup_slowusb
+
+cd /
+
+# if doslowusb is passed, pause other 10 seconds here, after mdev load
+[ "${DO_slowusb}" ] && sleep 10
+
+# Start iSCSI
+if [ -e /bin/iscsistart ]
+then
+       startiscsi
+fi
+
+# Setup btrfs, see bug 303529
+setup_btrfsctl
 
 # Setup md device nodes if they dont exist
 setup_md_device
@@ -243,9 +363,35 @@ then
        startLUKS
        if [ "${NORESUME}" != '1' ] && [ -n "${REAL_RESUME}" ]
        then
-               swsusp_resume
-#              suspend_resume
-               tuxonice_resume
+               case "${REAL_RESUME}" in
+                       LABEL=*|UUID=*)
+
+                               RESUME_DEV=""
+                               retval=1
+
+                               if [ ${retval} -ne 0 ]; then
+                                       RESUME_DEV=$(findfs "${REAL_RESUME}" 2>/dev/null)
+                                       retval=$?
+                               fi
+
+                               if [ ${retval} -ne 0 ]; then
+                                       RESUME_DEV=$(busybox findfs "${REAL_RESUME}" 2>/dev/null)
+                                       retval=$?
+                               fi
+
+                               if [ ${retval} -ne 0 ]; then
+                                       RESUME_DEV=$(blkid -o device -l -t "${REAL_RESUME}")
+                                       retval=$?
+                               fi
+
+                               if [ ${retval} -eq 0 ] && [ -n "${RESUME_DEV}" ]; then
+                                       good_msg "Detected real_resume=${RESUME_DEV}"
+                                       REAL_RESUME="${RESUME_DEV}"
+                               fi
+                               ;;
+               esac
+
+               do_resume
        fi
 fi
 
@@ -258,13 +404,14 @@ rundebugshell
 if [ "${CDROOT}" = '1' ]
 then
        good_msg "Making tmpfs for ${NEW_ROOT}"
-       mount -t tmpfs tmpfs "${NEW_ROOT}"
-       
-       for i in dev mnt mnt/cdrom mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
+       mount -n -t tmpfs tmpfs "${NEW_ROOT}"
+
+       for i in dev mnt mnt/livecd mnt/key tmp tmp/.initrd mnt/gentoo sys
        do
                mkdir -p "${NEW_ROOT}/${i}"
                chmod 755 "${NEW_ROOT}/${i}"
        done
+       [ ! -d "${CDROOT_PATH}" ] && mkdir -p "${CDROOT_PATH}"
        [ ! -e "${NEW_ROOT}/dev/null" ] && mknod "${NEW_ROOT}"/dev/null c 1 3
        [ ! -e "${NEW_ROOT}/dev/console" ] && mknod "${NEW_ROOT}"/dev/console c 5 1
 
@@ -290,7 +437,7 @@ then
        if [ "${REAL_ROOT}" = '' ]
        then
                echo -n -e "${WARN}>>${NORMAL}${BOLD} No bootable medium found. Waiting for new devices"
-               
+
                COUNTER=0
                while [ ${COUNTER} -lt 3 ]; do
                        sleep 3
@@ -325,41 +472,94 @@ do
        while [ "${got_good_root}" != '1' ]
        do
                case "${REAL_ROOT}" in
-                       LABEL\=*|UUID\=*)
-                       
+                       LABEL=*|UUID=*)
+
                                ROOT_DEV=""
                                retval=1
-                               
-                               if [ "${retval}" -ne '0' ]; then
-                                       ROOT_DEV=`findfs "${REAL_ROOT}" 2>/dev/null`
+
+                               if [ ${retval} -ne 0 ]; then
+                                       ROOT_DEV=$(findfs "${REAL_ROOT}" 2>/dev/null)
                                        retval=$?
                                fi
-                               
-                               if [ "$retval" -ne '0' ]; then
-                                       ROOT_DEV=`busybox findfs "${REAL_ROOT}" 2>/dev/null`
+
+                               if [ ${retval} -ne 0 ]; then
+                                       ROOT_DEV=$(busybox findfs "${REAL_ROOT}" 2>/dev/null)
                                        retval=$?
                                fi
-                               
-                               if [ "${retval}" -ne '0' ]; then
-                                       ROOT_DEV=`blkid -t "${REAL_ROOT}" | cut -d ":" -f 1 2>/dev/null`
+
+                               if [ ${retval} -ne 0 ]; then
+                                       ROOT_DEV=$(blkid -o device -l -t "${REAL_ROOT}")
                                        retval=$?
                                fi
-                               
-                               if [ "${retval}" -eq '0' ] && [ -n "${ROOT_DEV}" ]; then
+
+                               if [ ${retval} -eq 0 ] && [ -n "${ROOT_DEV}" ]; then
                                        good_msg "Detected real_root=${ROOT_DEV}"
                                        REAL_ROOT="${ROOT_DEV}"
                                else
-                                       whereis "REAL_ROOT" "root block device"
+                                       prompt_user "REAL_ROOT" "root block device"
                                        got_good_root=0
                                        continue
                                fi
                                ;;
+                       ZFS*)
+                               if [ "${USE_ZFS}" = '0' ]; then
+                                       prompt_user "REAL_ROOT" "root block device"
+                                       continue
+                               fi
+                                       
+                               ROOT_DEV="${REAL_ROOT#*=}"
+                               if [ "${ROOT_DEV}" != 'ZFS' ] 
+                               then
+                                       if [ "$(zfs get type -o value -H ${ROOT_DEV})" = 'filesystem' ]
+                                       then
+                                               got_good_root=1;
+                                               REAL_ROOT=${ROOT_DEV}
+                                               ROOTFSTYPE=zfs
+                                       else
+                                               bad_msg "${ROOT_DEV} is not a filesystem"
+                                               prompt_user "REAL_ROOT" "root block device"
+                                               got_good_root=0
+                                               continue
+                                       fi
+                               else
+                                       BOOTFS=$(/sbin/zpool list -H -o bootfs)
+                                       if [ "${BOOTFS}" != '-' ]
+                                       then
+
+                                               for i in ${BOOTFS}
+                                               do
+
+                                                       zfs get type ${i} > /dev/null
+                                                       retval=$?
+
+                                                       if [ ${retval} -eq 0 ]; then
+                                                               got_good_root=1
+                                                               REAL_ROOT=${i}
+                                                               ROOTFSTYPE=zfs
+                                                               break
+                                                       fi      
+                                               
+                                               done;
+
+                                       else
+                                               got_good_root=0
+                                       fi
+
+                               fi
+
+                               if [ ${got_good_root} -ne 1 ]; then
+                                       prompt_user "REAL_ROOT" "root block device"
+                                       got_good_root=0
+                               fi
+                                       
+                               continue
+                               ;;
                esac
-                               
+
                if [ "${REAL_ROOT}" = '' ]
                then
                        # No REAL_ROOT determined/specified. Prompt user for root block device.
-                       whereis "REAL_ROOT" "root block device"
+                       prompt_user "REAL_ROOT" "root block device"
                        got_good_root=0
 
                # Check for a block device or /dev/nfs
@@ -385,26 +585,42 @@ do
                # there is no isofs filesystem to worry about
                break
        else
-               good_msg "Mounting root..."
+               good_msg "Mounting $REAL_ROOT as root..."
+
+               if [ "${ROOTFSTYPE}" = 'zfs' ]
+               then
+                       if [ "zfs get -H -o value mountpoint ${REAL_ROOT}" = 'legacy' ]
+                       then
+                               MOUNT_STATE=rw
+                       else
+                               MOUNT_STATE=rw,zfsutil
+                       fi
+               else
+                       MOUNT_STATE=ro
+               fi
 
                # Try to mount the device as ${NEW_ROOT}
                if [ "${REAL_ROOT}" = '/dev/nfs' ]; then
                        findnfsmount
                else
+                       # If $REAL_ROOT is a symlink
+                       # Resolve it like util-linux mount does
+                       [ -L ${REAL_ROOT} ] && REAL_ROOT=`readlink ${REAL_ROOT}`
                        # mount ro so fsck doesn't barf later
                        if [ "${REAL_ROOTFLAGS}" = '' ]; then
-                               mount -o ro ${REAL_ROOT} ${NEW_ROOT}
+                               good_msg "Using mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE}"
+                               mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE} ${REAL_ROOT} ${NEW_ROOT}
                        else
-                               good_msg "Using mount -o ro,${REAL_ROOTFLAGS}"
-                               mount -o ro,${REAL_ROOTFLAGS} ${REAL_ROOT} ${NEW_ROOT}
+                               good_msg "Using mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE},${REAL_ROOTFLAGS}"
+                               mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE},${REAL_ROOTFLAGS} ${REAL_ROOT} ${NEW_ROOT}
                        fi
                fi
-               
-               # If mount is successful break out of the loop 
+
+               # If mount is successful break out of the loop
                # else not a good root and start over.
                if [ "$?" = '0' ]
                then
-                       if [ -d ${NEW_ROOT}/dev -a -x ${NEW_ROOT}/sbin/init ]
+                       if [ -d ${NEW_ROOT}/dev -a -x ${NEW_ROOT}/sbin/init ] || [ "${REAL_ROOT}" = "/dev/nfs" ]
                        then
                                break
                        else
@@ -436,13 +652,13 @@ then
        cache_cd_contents
 
        # If encrypted, find key and mount, otherwise mount as usual
-       if [ -n "${CRYPT_ROOT}" ] 
+       if [ -n "${CRYPT_ROOT}" ]
        then
-               CRYPT_ROOT_KEY="$(head -n 1 ${NEW_ROOT}/mnt/cdrom/livecd)"
+               CRYPT_ROOT_KEY="$(head -n 1 "${CDROOT_PATH}"/livecd)"
                CRYPT_ROOT='/dev/loop0'
                good_msg 'You booted an encrypted livecd' "${CRYPT_SILENT}"
 
-               losetup /dev/loop0 "${NEW_ROOT}/mnt/cdrom/${LOOPEXT}${LOOP}"
+               losetup /dev/loop0 "${CDROOT_PATH}/${LOOPEXT}${LOOP}"
                test_success 'Preparing loop filesystem'
 
                startLUKS
@@ -463,19 +679,36 @@ then
                if [ "${LOOPTYPE}" = 'normal' ]
                then
                        good_msg 'Mounting loop filesystem'
-                       mount -t ext2 -o loop,ro "${NEW_ROOT}/mnt/cdrom/${LOOPEXT}${LOOP}" "${NEW_ROOT}/mnt/livecd"
+                       mount -t ext2 -o loop,ro "${CDROOT_PATH}/${LOOPEXT}${LOOP}" "${NEW_ROOT}/mnt/livecd"
                        test_success 'Mount filesystem'
                        FS_LOCATION='mnt/livecd'
                elif [ "${LOOPTYPE}" = 'squashfs' ]
                then
-                       good_msg 'Mounting squashfs filesystem'
-                       mount -t squashfs -o loop,ro "${NEW_ROOT}/mnt/cdrom/${LOOPEXT}${LOOP}" "${NEW_ROOT}/mnt/livecd"
-                       test_success 'Mount filesystem'
+                       if [ "${USE_AUFS_NORMAL}" != '1' ]; then
+                               good_msg 'Mounting squashfs filesystem'
+                               _CACHED_SQUASHFS_PATH="${NEW_ROOT}/mnt/${LOOP}"
+                               _squashfs_path="${CDROOT_PATH}/${LOOPEXT}${LOOP}"  # Default to uncached
+                               # Upgrade to cached version if possible
+                               [ "${DO_cache}" -a -f "${_CACHED_SQUASHFS_PATH}" ] \
+                                               && _squashfs_path=${_CACHED_SQUASHFS_PATH}
+                               mount -t squashfs -o loop,ro "${_squashfs_path}" "${NEW_ROOT}/mnt/livecd" || {
+                                       bad_msg "Squashfs filesystem could not be mounted, dropping into shell."
+                                       if [ -e /proc/filesystems ]; then
+                                               fgrep -q squashfs /proc/filesystems || \
+                                                       bad_msg "HINT: Your kernel does not know filesystem \"squashfs\"."
+                                       fi
+                                       do_rundebugshell
+                               }
+                       else
+                               good_msg 'Mounting squashfs & aufs filesystems'
+                               setup_squashfs_aufs
+                               test_success 'Mount filesystem'
+                       fi
                        FS_LOCATION='mnt/livecd'
                elif [ "${LOOPTYPE}" = 'gcloop' ]
                then
                        good_msg 'Mounting gcloop filesystem'
-                       echo ' ' | losetup -E 19 -e ucl-0 -p0 "${NEW_ROOT}/dev/loop0" "${NEW_ROOT}/mnt/cdrom/${LOOPEXT}${LOOP}"
+                       echo ' ' | losetup -E 19 -e ucl-0 -p0 "${NEW_ROOT}/dev/loop0" "${CDROOT_PATH}/${LOOPEXT}${LOOP}"
                        test_success 'losetup the loop device'
 
                        mount -t ext2 -o ro "${NEW_ROOT}/dev/loop0" "${NEW_ROOT}/mnt/livecd"
@@ -483,10 +716,10 @@ then
                        FS_LOCATION='mnt/livecd'
                elif [ "${LOOPTYPE}" = 'zisofs' ]
                then
-                       FS_LOCATION="mnt/cdrom/${LOOPEXT}${LOOP}"
+                       FS_LOCATION="${CDROOT_PATH/\/}/${LOOPEXT}${LOOP}"
                elif [ "${LOOPTYPE}" = 'noloop' ]
                then
-                       FS_LOCATION='mnt/cdrom'
+                       FS_LOCATION="${CDROOT_PATH/\/}"
                elif [ "${LOOPTYPE}" = 'sgimips' ]
                then
                        # getdvhoff finds the starting offset (in bytes) of the squashfs
@@ -504,7 +737,7 @@ then
                                        "${NEW_ROOT}${CDROOT_DEV}" \
                                        "${NEW_ROOT}${REAL_ROOT}"
                        test_success 'losetup /dev/sr0 /dev/loop0'
-       
+
                        good_msg 'Mounting the Root Partition'
                        mount -t squashfs -o ro "${NEW_ROOT}${CDROOT_DEV}" "${NEW_ROOT}/mnt/livecd"
                        test_success 'mount /dev/loop0 /'
@@ -512,33 +745,44 @@ then
                fi
        fi
 
+
+
        # Unpacking additional packages from NFS mount
        # This is useful for adding kernel modules to /lib
        # We do this now, so that additional packages can add whereever they want.
        if [ "${REAL_ROOT}" = '/dev/nfs' ]
        then
-               if [ -e "${CHROOT}/mnt/cdrom/add" ]
+               if [ -e "${CDROOT_PATH}/add" ]
                then
-                               for targz in `ls ${CHROOT}/mnt/cdrom/add/*.tar.gz`
-                               do      
-                                       tarname=`basename ${targz}`
+                               for targz in $(ls ${CDROOT_PATH}/add/*.tar.gz)
+                               do
+                                       tarname=$(basename ${targz})
                                        good_msg "Adding additional package ${tarname}"
-                                       (cd ${CHROOT} ; /bin/tar -xzf ${targz})
+                                       (cd ${NEW_ROOT} ; /bin/tar -xzf ${targz})
                                done
                fi
        fi
 
-       
+
+       if [ "${USE_UNIONFS_NORMAL}" = '1' ]
+       then
+               setup_unionfs ${NEW_ROOT} /${FS_LOCATION}
+               CHROOT=/union
+       elif [ "${USE_AUFS_NORMAL}" != '1' ]; then
+
        good_msg "Copying read-write image contents to tmpfs"
        # Copy over stuff that should be writable
-       (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}")
+       (cd "${NEW_ROOT}/${FS_LOCATION}"; cp -a ${ROOT_TREES} "${NEW_ROOT}") || {
+               bad_msg "Copying failed, dropping into a shell."
+               do_rundebugshell
+       }
 
        # Now we do the links.
        for x in ${ROOT_LINKS}
        do
                if [ -L "${NEW_ROOT}/${FS_LOCATION}/${x}" ]
                then
-                       ln -s "`readlink ${NEW_ROOT}/${FS_LOCATION}/${x}`" "${x}" 2>/dev/null
+                       ln -s "$(readlink ${NEW_ROOT}/${FS_LOCATION}/${x})" "${x}" 2>/dev/null
                else
                        # List all subdirectories of x
                        find "${NEW_ROOT}/${FS_LOCATION}/${x}" -type d 2>/dev/null | while read directory
@@ -547,8 +791,8 @@ then
                                directory="${directory#${NEW_ROOT}/${FS_LOCATION}/}"
 
                                # Skip this directory if we already linked a parent directory
-                               if [ "${curent_parrent}" != '' ]; then
-                                       var=`echo "${directory}" | grep "^${curent_parrent}"`
+                               if [ "${current_parent}" != '' ]; then
+                                       var=$(echo "${directory}" | grep "^${current_parent}")
                                        if [ "${var}" != '' ]; then
                                                continue
                                        fi
@@ -557,7 +801,7 @@ then
                                if [ -e "/${NEW_ROOT}/${directory}" ]
                                then
                                        # It does exist, link all the individual files
-                                       for file in `ls /${NEW_ROOT}/${FS_LOCATION}/${directory}`
+                                       for file in $(ls /${NEW_ROOT}/${FS_LOCATION}/${directory})
                                        do
                                        if [ ! -d "/${NEW_ROOT}/${FS_LOCATION}/${directory}/${file}" ] && [ ! -e "${NEW_ROOT}/${directory}/${file}" ]; then
                                                        ln -s "/${FS_LOCATION}/${directory}/${file}" "${directory}/${file}" 2> /dev/null
@@ -572,14 +816,12 @@ then
                fi
        done
 
-       if [ "${DO_slowusb}" ] || [ "${FORCE_slowusb}" ]
-       then
-               sleep 10
-       fi
-       mkdir initramfs proc tmp sys 2>/dev/null
+       mkdir initramfs proc tmp sys run 2>/dev/null
        chmod 1777 tmp
 
-       #UML=`cat /proc/cpuinfo|grep UML|sed -e 's|model name.*: ||'`
+       fi
+
+       #UML=$(cat /proc/cpuinfo|grep UML|sed -e 's|model name.*: ||')
        #if [ "${UML}" = 'UML' ]
        #then
        #       # UML Fixes
@@ -589,13 +831,47 @@ then
        # Let Init scripts know that we booted from CD
        export CDBOOT
        CDBOOT=1
-       check_slowusb
-       if [ "${DO_slowusb}" ] || [ "${FORCE_slowusb}" ]
+else
+       if [ "${USE_UNIONFS_NORMAL}" = '1' ]
        then
-               sleep 10
+               mkdir /union_changes
+               mount -t tmpfs tmpfs /union_changes
+               setup_unionfs /union_changes ${NEW_ROOT}
+               mkdir -p ${UNION}/tmp/.initrd
        fi
 fi
 
+# Mount the additional things as required by udev & systemd
+if [ -f ${NEW_ROOT}/etc/initramfs.mounts ]; then
+       fslist=$(get_mounts_list)
+else
+       fslist="/usr" 
+fi
+
+for fs in $fslist; do
+       dev=$(get_mount_device $fs)
+       [ -z "${dev}" ] && continue
+       # Resolve it like util-linux mount does
+       [ -L ${dev} ] && dev=`readlink ${dev}`
+       # In this case, it's probably part of the filesystem
+       # and not a mountpoint
+       [ -z "$dev" ] && continue
+       fstype=$(get_mount_fstype $fs)
+       if get_mount_options $fs | fgrep -q bind ; then
+               opts='bind'
+               dev=${NEW_ROOT}${dev}
+       else
+               # ro must be trailing, and the options will always contain at least 'defaults'
+               opts="$(get_mount_options $fs | strip_mount_options),ro"
+       fi
+       mnt=${NEW_ROOT}${fs}
+       cmd="mount -t $fstype -o $opts $dev $mnt"
+       good_msg "Mounting $dev as ${fs}: $cmd"
+       if ! $cmd; then
+               bad_msg "Unable to mount $dev for $fs"
+       fi
+done
+
 # Execute script on the cdrom just before boot to update things if necessary
 cdupdate
 
@@ -608,30 +884,44 @@ fi
 verbose_kmsg
 
 echo -ne "${GOOD}>>${NORMAL}${BOLD} Booting (initramfs)${NORMAL}"
+
+cd "${CHROOT}"
+mkdir "${CHROOT}/proc" "${CHROOT}/sys" "${CHROOT}/run" 2>/dev/null
+echo -ne "${BOLD}.${NORMAL}"
+
+# If devtmpfs is mounted, try move it to the new root
+# If that fails, try to unmount all possible mounts of devtmpfs as stuff breaks otherwise
+for fs in /dev /sys /proc
+do
+       if grep -qs "$fs" /proc/mounts
+       then
+               if ! mount --move $fs "${CHROOT}"$fs
+               then
+                       umount $fs || echo '*: Failed to move and unmount the ramdisk $fs!'
+               fi
+       fi
+done
+
 if [ ! -e "${CHROOT}/dev/console" ] || [ ! -e "${CHROOT}/dev/null" ]
 then
-       echo -ne "${BAD}>>${NORMAL}${BOLD} ERROR: your /dev is missing files required to boot (console and null)${NORMAL}"
+       echo -ne "${BAD}>>${NORMAL}${BOLD} ERROR: your real /dev is missing files required to boot (console and null)${NORMAL}"
 elif [ -e /etc/initrd.splash -a ! -e "${CHROOT}/dev/tty1" ]
 then
-       echo -ne "${BAD}>>${NORMAL}${BOLD} ERROR: your /dev is missing tty1, which is required for splash${NORMAL}"
+       echo -ne "${BAD}>>${NORMAL}${BOLD} ERROR: your real /dev is missing tty1, which is required for splash${NORMAL}"
 fi
 
-cd "${CHROOT}"
-mkdir "${CHROOT}/proc" "${CHROOT}/sys" 2>/dev/null
-echo -ne "${BOLD}.${NORMAL}"
-umount /sys || echo '*: Failed to unmount the ramdisk /sys!'
-umount /proc || echo '*: Failed to unmount the ramdisk /proc!'
 echo -e "${BOLD}.${NORMAL}"
 
-exec switch_root -c "/dev/console" "${CHROOT}" "${REAL_INIT:-/sbin/init}" "${INIT_OPTS}"
+exec /sbin/switch_root -c "/dev/console" "${CHROOT}" "${REAL_INIT:-/sbin/init}" "${INIT_OPTS}"
 
 # If we get here, something bad has happened
 splash 'verbose'
 
-echo 'A fatal error has probably occured since /sbin/init did not'
-echo 'boot correctly. Trying to open a shell...'
+echo "A fatal error has probably occured since ${REAL_INIT:-/sbin/init} did not"
+echo "boot correctly. Trying to open a shell..."
 echo
 exec /bin/bash
 exec /bin/sh
 exec /bin/ash
+exec /bin/dash
 exec sh