You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
genkernel_fork/defaults/initrd.scripts

1235 lines
32 KiB

#!/bin/ash
. /etc/initrd.defaults
backup() {
echo -ne "\033[0G\033[0K"
}
modules_load() {
for module in $*
do
echo ${module} >> /etc/modules/extra_load
done
modules_scan extra_load
}
modules_scan() {
local MODS
[ -d "/etc/modules/${1}" ] || touch /etc/modules/${1}
[ -f "/etc/modules/${1}" ] && MODS=`cat /etc/modules/${1}`
for x in ${MODS}
do
MLOAD=`echo ${MLIST} | sed -e "s/.*${x}.*/${x}/"`
if [ "${MLOAD}" = "${x}" ] # Only module to no-load
then
echo -e "${BOLD} ::${NORMAL} Skipping ${x}..."
elif [ "${MLOAD}" = "${MLIST}" ] # == No change == No specified no-load
then
[ -n "${DEBUG}" ] && echo -ne "${BOLD} ::${NORMAL} Checking for ${x}..."
# find -name does not work since the return status is always zero
if find /lib/modules/${KV} | grep /"${x}${KSUFF}" >/dev/null 2>&1
then
echo -ne "${BOLD} ::${NORMAL} Scanning for ${x}..."
modprobe ${x} -n
backup
echo -ne "${NORMAL}"
fi
else
echo -e "${BOLD} ::${NORMAL} Skipping ${x}..."
fi
done
}
uppercase(){
# needs tr on busybox
echo $1 | tr 'a-z' 'A-Z'
}
findmediamount() {
# $1 = mount dir name / media name
# $2 = recognition file
# $3 = variable to have the device path
# $4 = actual mount dir path (full path)
# args remaining are possible devices
local media=$1 recon=$2 vrbl=$3 mntdir=$4
shift 4
good_msg "Looking for the ${media}" ${CRYPT_SILENT}
if [ "$#" -gt "0" ]
then
[ ! -d "${mntdir}" ] && mkdir -p ${mntdir} 2>/dev/null >/dev/null
if [ -n "${ISOBOOT}" ]
then
mntcddir="${mntdir%${media}}iso"
if [ ! -f ${mntcddir} ]
then
mkdir ${mntcddir}
fi
else
mntcddir=${mntdir}
fi
for x in $*
do
# Check for a block device to mount
if [ -b "${x}" ]
then
skip=0
bsn=`basename "${x}"`
#
# If disk and it has at least one partition, skip.
# We use /sys/block/${bsn}/${bsn}[0-9]* to make sure that we
# don't skip device mapper devices. Even the craziest scenario
# deserves a fair chance.
#
for part in `ls /sys/block/${bsn}/${bsn}*[0-9]* 2>/dev/null`
do
skip=1
break;
done
if [ ${skip} -eq 1 ]
then
continue
fi
good_msg "Attempting to mount media:- ${x}" ${CRYPT_SILENT}
mount -r -t ${CDROOT_TYPE} ${x} ${mntcddir} >/dev/null 2>&1
if [ "$?" = '0' ]
then
if [ -n "${ISOBOOT}" ]; then
if [ -f ${mntcddir}/${ISOBOOT} ]; then
mount -o loop ${mntcddir}/${ISOBOOT} ${mntdir}
if [ "$?" = "0" ]; then
good_msg "iso mounted on ${mntdir}"
fi
fi
fi
# Check for the media
if [ -f "${mntdir}/${recon}" ]
then
#set REAL_ROOT, CRYPT_ROOT_KEYDEV or whatever ${vrbl} is
eval ${vrbl}'='"${x}"
good_msg "Media found on ${x}" ${CRYPT_SILENT}
break
else
umount ${mntcddir}
fi
fi
fi
done
fi
eval local result='$'${vrbl}
[ -n "${result}" ] || bad_msg "Media not found" ${CRYPT_SILENT}
}
devicelist(){
# Locate the cdrom device with our media on it.
# CDROM DEVICES
local DEVICES="/dev/cdroms/* /dev/ide/cd/* /dev/sr*"
# USB Keychain/Storage
DEVICES="$DEVICES /dev/sd*"
# IDE devices
DEVICES="$DEVICES /dev/hd*"
# virtio devices
DEVICES="$DEVICES /dev/vd*"
# USB using the USB Block Driver
DEVICES="$DEVICES /dev/ubd* /dev/ubd/*"
# iSeries devices
DEVICES="$DEVICES /dev/iseries/vcd*"
# builtin mmc/sd card reader devices
DEVICES="$DEVICES /dev/mmcblk* /dev/mmcblk*/*"
# fallback scanning, this might scan something twice, but it's better than
# failing to boot.
[ -e /proc/partitions ] && DEVICES="${DEVICES} $(awk -r '/([0-9]+[[:space:]]+)/{print "/dev/" $4}' /proc/partitions)"
echo ${DEVICES}
}
bootstrapCD() {
local DEVICES=`devicelist`
# The device was specified on the command line, so there's no need to scan
# a bunch of extra devices
[ -n "${CDROOT_DEV}" ] && DEVICES="${CDROOT_DEV}"
findmediamount "cdrom" "${SUBDIR}/livecd" "REAL_ROOT" "${CDROOT_PATH}" ${DEVICES}
}
bootstrapKey() {
# $1 = ROOT/SWAP
local KEYDEVS=`devicelist`
eval local keyloc='"${CRYPT_'${1}'_KEY}"'
findmediamount "key" "${keyloc}" "CRYPT_${1}_KEYDEV" "/mnt/key" ${KEYDEVS}
}
cache_cd_contents() {
# Check loop file exists and cache to ramdisk if DO_cache is enabled
if [ "${LOOPTYPE}" != "noloop" ] && [ "${LOOPTYPE}" != "sgimips" ]
then
check_loop
if [ "${DO_cache}" ]
then
# TODO: Check the size of the image versus the size of our tmpfs
# along with the amount of available RAM and increase tmpfs size
# if necessary. (Not having awk sucks...)
# z=0
# for i in $(cat /proc/meminfo | grep -e ^MemFree -e ^Cached | \
# cut -d: -f2 | cut -dk -f1 | sed -e "s/^\s*//") ; do
# z=$(($z + $i)) ; done
# echo $z
good_msg "Copying loop file for caching..."
# Verify that the needed directory exists
mkdir -p "$(dirname ${NEW_ROOT}/mnt/${LOOP})"
cp -a ${CDROOT_PATH}/${LOOP} ${NEW_ROOT}/mnt/${LOOP}
if [ $? -ne 0 ]
then
bad_msg "Failed to cache the loop file! Lack of space?"
rm -rf ${NEW_ROOT}/mnt/livecd.* 2>/dev/null
rm -rf ${NEW_ROOT}/mnt/image.* 2>/dev/null
rm -rf ${NEW_ROOT}/mnt/zisofs 2>/dev/null
else
LOOPEXT='../'
fi
fi
fi
}
mount_sysfs() {
mount -t sysfs sysfs /sys -o noexec,nosuid,nodev >/dev/null 2>&1
ret=$?
[ ${ret} -eq 0 ] || bad_msg "Failed to mount /sys!"
}
findnfsmount() {
if [ "${IP}" != '' ] || busybox udhcpc -n -T 15 -q
then
[ -e /rootpath ] && NFSROOT=`cat /rootpath`
if [ "${NFSROOT}" = '' ]
then
# Obtain NFSIP
OPTIONS=`busybox dmesg | grep rootserver | sed -e "s/,/ /g"`
for OPTION in $OPTIONS
do
if [ `echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 1` = 'rootserver' ]
then
NFSIP=`echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 2`
fi
done
# Obtain NFSPATH
OPTIONS=`busybox dmesg | grep rootpath | sed -e "s/,/ /g"`
for OPTION in $OPTIONS
do
if [ `echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 1` = 'rootpath' ]
then
NFSPATH=`echo $OPTION | sed -e "s/=/ /g" | cut -d " " -f 2`
fi
done
# Setup NFSROOT
if [ "${NFSIP}" != '' ] && [ "$NFSPATH" != '' ]
then
NFSROOT="${NFSIP}:${NFSPATH}"
else
bad_msg "The DHCP Server did not send a valid root-path."
bad_msg "Please check your DHCP setup, or provide a nfsroot=<...> parameter."
fi
fi
if [ "${NFSROOT}" != '' ]
then
NFSOPTIONS=${NFSROOT#*,}
NFSROOT=${NFSROOT%%,*}
if [ "${NFSOPTIONS}" = "${NFSROOT}" ]
then
NFSOPTIONS=$DEFAULT_NFSOPTIONS
else
NFSOPTIONS="${DEFAULT_NFSOPTIONS},${NFSOPTIONS}"
fi
if [ "${CDROOT}" != '0' ]
then
good_msg "Attempting to mount NFS CD image on ${NFSROOT} with options ${NFSOPTIONS}"
mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${CDROOT_PATH}
if [ "$?" = '0' ]
then
REAL_ROOT="/dev/nfs"
else
bad_msg "NFS Mounting failed. Is the path corrent ?"
fi
else
good_msg "Attempting to mount NFS root on ${NFSROOT} with options ${NFSOPTIONS}"
mount -t nfs -o ${NFSOPTIONS} ${NFSROOT} ${NEW_ROOT}
if [ "$?" = '0' ]
then
REAL_ROOT="/dev/nfs"
else
bad_msg "NFS Mounting failed. Is the path correct ?"
fi
# FIXME: Need to start portmap and the other rpc daemons in
# order to remount rw.
fi
fi
fi
}
check_loop() {
if [ "${LOOP}" = '' -o ! -e "${CDROOT_PATH}/${LOOP}" ]
then
bad_msg "Invalid loop location: ${LOOP}"
bad_msg 'Please export LOOP with a valid location, or reboot and pass a proper loop=...'
bad_msg 'kernel command line!'
run_shell
fi
}
run_shell() {
/bin/ash
}
runmdev() {
# Use devtmpfs if enabled in kernel,
# else tmpfs. Always run mdev just in case
devfs=tmpfs
if grep -qs devtmpfs /proc/filesystems ; then
devfs=devtmpfs
fi
# Options copied from /etc/init.d/udev-mount, should probably be kept in sync
mount -t $devfs -o "exec,nosuid,mode=0755,size=10M" udev /dev \
|| bad_msg "Failed to mount /dev as ${devfs}"
# http://git.busybox.net/busybox/plain/docs/mdev.txt
mkdir -m 0755 /dev/pts
mount -t devpts -o gid=5,mode=0620 devpts /dev/pts || bad_msg "Failed to mount /dev/pts"
mdev -s || bad_msg "Failed to receive dynamic updates from mdev"
}
test_success() {
retcode=$?
# If last command failed send error message and fall back to a shell
if [ "$retcode" != '0' ]
then
error_string=$1
error_string="${error_string:-run command}"
bad_msg 'Failed to $1; failing back to the shell...'
run_shell
fi
}
# msg functions arguments
# $1 string
# $2 hide flag
good_msg() {
msg_string=$1
msg_string="${msg_string:-...}"
[ "$2" != 1 ] && echo -e "${GOOD}>>${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
}
bad_msg() {
msg_string=$1
msg_string="${msg_string:-...}"
if [ "$2" != 1 ]
then
splash 'verbose' > /dev/null &
echo -e "${BAD}!!${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
fi
}
warn_msg() {
msg_string=$1
msg_string="${msg_string:-...}"
[ "$2" != 1 ] && echo -e "${WARN}**${NORMAL}${BOLD} ${msg_string} ${NORMAL}"
}
crypt_filter() {
if [ "${CRYPT_SILENT}" = '1' ]
then
eval $1 >/dev/null 2>/dev/null
else
splash 'verbose' > /dev/null &
eval $1
res=$?
if [ ${res} -eq 0 ]
then
splash set_msg 'Disk unlocked.'
fi
return ${res}
fi
}
prompt_user(){
# $1 = variable whose value is the path (examples: "REAL_ROOT",
# "LUKS_KEYDEV")
# $2 = label
# $3 = optional explanations for failure
eval local oldvalue='$'${1}
[ \( $# != 2 \) -a \( $# != 3 \) ] && \
bad_msg "Bad invocation of function prompt_user, please file a bug \
report with this message" && exit 1
[ -n "${3}" ] && local explnt=" or : ${3}" || local explnt="."
bad_msg "Could not find the ${2} in ${oldvalue}${explnt}"
echo ' Please specify another value or: press Enter for the same, type "shell" for a shell, or "q" to skip...'
echo -n "${2}(${oldvalue}) :: "
read ${1}
case `eval echo '$'${1}` in
'q')
eval ${1}'='${oldvalue}
warn_msg "Skipping step, this will likely cause a boot failure."
break
;;
'shell')
eval ${1}'='${oldvalue}
echo "To leave and try again just press <Ctrl>+D"
run_shell
;;
'')
eval ${1}'='${oldvalue}
;;
esac
}
setup_hotplug() {
if [ "${KV_2_6_OR_GREATER}" ]
then
echo /sbin/mdev > /proc/sys/kernel/hotplug
fi
}
setup_slowusb() {
# This function removes unset DO_slowusb if there is no usb-storage attached.
# If noslowusb is set, skip this function
[ "${DO_slowusb}" ] || return
# Unset DO_slowusb, so we can set it again if usb-storage has something attached
unset DO_slowusb
local usb_storage_dir="/sys/bus/usb/drivers/usb-storage"
if [ ! -d "${usb_storage_dir}" ]
then
# no automated slowusb required. no usb-storage devices attached.
return
fi
for x in "${usb_storage_dir}"/*
do
[ -d "${x}" ] && [ "${x}" != "${usb_storage_dir}/module" ] \
&& { DO_slowusb="1" ; break ; }
done
}
start_dev_mgr() {
if [ "${KV_2_6_OR_GREATER}" ]
then
cd /sys
good_msg 'Activating mdev'
runmdev
cd /
fi
}
cmdline_hwopts() {
# Scan CMDLINE for any "doscsi" or "noscsi"-type arguments
local FOUND
local TMP_HWOPTS
for x in $HWOPTS
do
for y in $CMDLINE
do
if [ "${y}" = "do${x}" ]
then
MY_HWOPTS="${MY_HWOPTS} $x"
elif [ "${y}" = "no${x}" ]
then
MY_HWOPTS="`echo ${MY_HWOPTS} | sed -e \"s/${x}//g\" -`"
fi
if [ "$(echo ${y} | cut -b -7)" = "keymap=" ]
then
MY_HWOPTS="${MY_HWOPTS} keymap"
fi
done
done
# Shouldnt need to sort this as the following loop should figure out the
# duplicates and strip them out
#MY_HWOPTS=`echo ${MY_HWOPTS}| sort`
for x in ${MY_HWOPTS}
do
FOUND=0
for y in ${TMP_HWOPTS}
do
if [ "${y}" = "${x}" ]
then
continue 2
fi
done
TMP_HWOPTS="${TMP_HWOPTS} ${x}"
eval DO_`echo ${x} | sed 's/-//'`=1
done
MY_HWOPTS=${TMP_HWOPTS}
}
load_modules() {
# Load modules listed in MY_HWOPTS if /lib/modules exists for the running
# kernel version
if [ -d "/lib/modules/${KV}" ]
then
good_msg 'Loading modules'
# Load appropriate kernel modules
for modules in $MY_HWOPTS
do
modules_scan $modules
done
else
good_msg 'Skipping module load; no modules in the ramdisk!'
fi
}
setup_keymap() {
if [ "${DO_keymap}" ]
then
if [ ! -e /dev/vc/0 -a ! -e /dev/tty0 ]
then
DEVBIND=1
mount -o bind ${NEW_ROOT}/dev /dev
fi
[ ! -e /dev/tty0 ] && ln -s /dev/tty1 /dev/tty0
[ -f /lib/keymaps/keymapList ] && chooseKeymap
[ "${DEVBIND}" = '1' ] && umount /dev
if [ -e /etc/sysconfig/keyboard -a "${CDROOT}" = '1' ]
then
mkdir -p ${NEW_ROOT}/etc/sysconfig/
cp /etc/sysconfig/keyboard ${NEW_ROOT}/etc/sysconfig/keyboard
fi
fi
}
chooseKeymap() {
good_msg "Loading keymaps"
if [ -z "${keymap}" ]
then
splash 'verbose' > /dev/null &
cat /lib/keymaps/keymapList
read -t 10 -p '<< Load keymap (Enter for default): ' keymap
case ${keymap} in
1|azerty) keymap=azerty ;;
2|be) keymap=be ;;
3|bg) keymap=bg ;;
4|br-a) keymap=br-a ;;
5|br-l) keymap=br-l ;;
6|by) keymap=by ;;
7|cf) keymap=cf ;;
8|croat) keymap=croat ;;
9|cz) keymap=cz ;;
10|de) keymap=de ;;
11|dk) keymap=dk ;;
12|dvorak) keymap=dvorak ;;
13|es) keymap=es ;;
14|et) keymap=et ;;
15|fi) keymap=fi ;;
16|fr) keymap=fr ;;
17|gr) keymap=gr ;;
18|hu) keymap=hu ;;
19|il) keymap=il ;;
20|is) keymap=is ;;
21|it) keymap=it ;;
22|jp) keymap=jp ;;
23|la) keymap=la ;;
24|lt) keymap=lt ;;
25|mk) keymap=mk ;;
26|nl) keymap=nl ;;
27|no) keymap=no ;;
28|pl) keymap=pl ;;
29|pt) keymap=pt ;;
30|ro) keymap=ro ;;
31|ru) keymap=ru ;;
32|se) keymap=se ;;
33|sg) keymap=sg ;;
34|sk-y) keymap=sk-y ;;
35|sk-z) keymap=sk-z ;;
36|slovene) keymap=slovene ;;
37|trf) keymap=trf ;;
38|trq) keymap=trq ;;
39|ua) keymap=ua ;;
40|uk) keymap=uk ;;
41|us) keymap=us ;;
42|wangbe) keymap=wangbe ;;
esac
fi
if [ -e /lib/keymaps/${keymap}.map ]
then
good_msg "Loading the ''${keymap}'' keymap"
loadkmap < /lib/keymaps/${keymap}.map
# xkeymap=${keymap}
# echo ${keymap} | egrep -e "[0-9]+" >/dev/null 2>&1
# if [ $? -eq 0 ]
# then
# xkeymap=`tail -n 7 /lib/keymaps/keymapList | grep ${keymap} | sed -r "s/.*\s+${keymap}\s+([a-z-]+).*/\1/g" | egrep -v 1`
# fi
mkdir -p /etc/sysconfig
# echo "XKEYBOARD=${xkeymap}" > /etc/sysconfig/keyboard
echo "XKEYBOARD=${keymap}" > /etc/sysconfig/keyboard
splash set_msg "Set keymap to ${keymap}"
elif [ -z "${keymap}" ]
then
echo
good_msg "Keeping default keymap"
splash set_msg "Keeping default keymap"
else
bad_msg "Sorry, but keymap ''${keymap}'' is invalid!"
unset keymap
chooseKeymap
fi
}
startVolumes() {
#good_msg 'Checking if volumes need to be started...'
# Here, we check for /dev/device-mapper, and if it exists, we setup a
# a symlink, which should hopefully fix bug #142775 and bug #147015
if [ -e /dev/device-mapper ] && [ ! -e /dev/mapper/control ]
then
mkdir -p /dev/mapper
ln -sf /dev/device-mapper /dev/mapper/control
fi
if [ "${USE_MDADM}" = '1' ]
then
/sbin/mdadm --assemble --scan
fi
if [ "${USE_DMRAID_NORMAL}" = '1' ]
then
if [ -e '/sbin/dmraid' ]
then
good_msg "Activating Device-Mapper RAID(s)"
if [ '${DMRAID_OPTS}' = '' ]
then
/sbin/dmraid -ay
else
/sbin/dmraid -ay ${DMRAID_OPTS}
fi
fi
fi
if [ "${USE_LVM_NORMAL}" = '1' ]
then
if [ -e '/bin/lvm' ]
then
for dev in ${RAID_DEVICES}
do
setup_md_device "${dev}"
done
# This is needed for /bin/lvm to accept the following logic
lvm_commands="#! /bin/lvm"
# If there is a cahe, update it. Unbreak at least dmcrypt
[ -d /etc/lvm/cache ] && lvm_commands="${lvm_commands} \nvgscan"
# To activate volumegroups on all devices in the cache
lvm_commands="${lvm_commands} \nvgchange -ay --sysinit"
# To create symlinks so users can use real_root=/dev/vg/root
# This needs to run after vgchange, using vgchange --mknodes is too
# early.
lvm_commands="${lvm_commands} \nvgmknodes --ignorelockingfailure"
# And finally execute it all (/proc/... needed if lvm is compiled without readline)
good_msg "Scanning for and activating Volume Groups"
printf "%b\n" "${lvm_commands}" | /bin/lvm /proc/self/fd/0
else
bad_msg "vgscan or vgchange not found: skipping LVM volume group activation!"
fi
fi
if [ "${USE_ZFS}" = '1' ]
then
/sbin/zpool import -N -a ${ZPOOL_FORCE}
fi
}
startiscsi() {
if [ ! -n "${ISCSI_NOIBFT}" ]
then
good_msg "Activating iSCSI via iBFT"
iscsistart -b
fi
if [ -n "${ISCSI_INITIATORNAME}" ] && [ -n "${ISCSI_TARGET}" ] && [ -n "${ISCSI_ADDRESS}" ]
then
good_msg "Activating iSCSI via cmdline"
if [ "${ISCSI_TGPT}" ]
then
ADDITIONAL="${ADDITIONAL} -g ${ISCSI_TGPT}"
else
ADDITIONAL="${ADDITIONAL} -g 1"
fi
if [ "${ISCSI_PORT}" ]
then
ADDITIONAL="${ADDITIONAL} -p ${ISCSI_PORT}"
fi
if [ "${ISCSI_USERNAME}" ]
then
ADDITIONAL="${ADDITIONAL} -u ${ISCSI_USERNAME}"
fi
if [ "${ISCSI_PASSWORD}" ]
then
ADDITIONAL="${ADDITIONAL} -w ${ISCSI_PASSWORD}"
fi
if [ "${ISCSI_USERNAME_IN}" ]
then
ADDITIONAL="${ADDITIONAL} -U ${ISCSI_USERNAME_IN}"
fi
if [ "${ISCSI_PASSWORD_IN}" ]
then
ADDITIONAL="${ADDITIONAL} -W ${ISCSI_PASSWORD_IN}"
fi
if [ "${ISCSI_DEBUG}" ]
then
ADDITIONAL="${ADDITIONAL} -d ${ISCSI_DEBUG}"
fi
iscsistart -i "${ISCSI_INITIATORNAME}" -t "${ISCSI_TARGET}" -a "${ISCSI_ADDRESS}" ${ADDITIONAL}
# let iscsid settle - otherwise mounting the iSCSI-disk will fail (very rarely, though)
sleep 1
fi
}
# Open a LUKS device
# It is either the root or a swap, other devices are supported in the scripts provided with sys-fs/cryptsetup-luks
# $1 - root/swap
openLUKS() {
# please use 'tr' and this line, or remove it
# eval local TYPE=`uppercase $1`
case $1 in
root)
local TYPE=ROOT
;;
swap)
local TYPE=SWAP
;;
esac
eval local LUKS_DEVICE='"${CRYPT_'${TYPE}'}"' LUKS_NAME="$1" LUKS_KEY='"${CRYPT_'${TYPE}'_KEY}"' LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"' LUKS_TRIM='"${CRYPT_'${TYPE}'_TRIM}"'
local DEV_ERROR=0 KEY_ERROR=0 KEYDEV_ERROR=0
local mntkey="/mnt/key/" cryptsetup_options=''
[ ! -e /sbin/cryptsetup ] && bad_msg "The ramdisk does not support LUKS" && exit 1
while [ 1 ]
do
local gpg_cmd=""
# if crypt_silent=1 and some error occurs, enter shell quietly
if [ \( ${CRYPT_SILENT} -eq 1 \) -a \( \( \( ${DEV_ERROR} -eq 1 \) -o \( ${KEY_ERROR} -eq 1 \) \) -o \( ${KEYDEV_ERROR} -eq 1 \) \) ]
then
run_shell
elif [ ${DEV_ERROR} -eq 1 ]
then
prompt_user "LUKS_DEVICE" "${LUKS_NAME}"
DEV_ERROR=0
elif [ ${KEY_ERROR} -eq 1 ]
then
prompt_user "LUKS_KEY" "${LUKS_NAME} key"
KEY_ERROR=0
elif [ ${KEYDEV_ERROR} -eq 1 ]
then
prompt_user "LUKS_KEYDEV" "${LUKS_NAME} key device"
KEYDEV_ERROR=0
else
case "${LUKS_DEVICE}" in
UUID\=*|LABEL\=*)
local REAL_LUKS=""
local retval=1
if [ "${retval}" -ne 0 ]; then
REAL_LUKS=`findfs "${LUKS_DEVICE}" 2>/dev/null`
retval=$?
fi
if [ "$retval" -ne 0 ]; then
REAL_LUKS=`busybox findfs "${LUKS_DEVICE}" 2>/dev/null`
retval=$?
fi
if [ "${retval}" -ne 0 ]; then
REAL_LUKS=`blkid -l -t "${LUKS_DEVICE}" | cut -d ":" -f 1 2>/dev/null`
retval=$?
fi
if [ "${retval}" -eq 0 ] && [ -n "${REAL_LUKS}" ]; then
good_msg "Detected device ${REAL_LUKS}"
LUKS_DEVICE="${REAL_LUKS}"
fi
;;
esac
setup_md_device ${LUKS_DEVICE}
cryptsetup isLuks ${LUKS_DEVICE}
if [ $? -ne 0 ]
then
bad_msg "The LUKS device ${LUKS_DEVICE} does not contain a LUKS header" ${CRYPT_SILENT}
DEV_ERROR=1
continue
else
# Handle keys
if [ "x${LUKS_TRIM}" = "xyes" ]
then
good_msg "Enabling TRIM support for ${LUKS_NAME}." ${CRYPT_SILENT}
cryptsetup_options="${cryptsetup_options} --allow-discards"
fi
if [ -n "${LUKS_KEY}" ]
then
if [ ! -e "${mntkey}${LUKS_KEY}" ]
then
if [ -b "${LUKS_KEYDEV}" ]
then good_msg "Using key device ${LUKS_KEYDEV}." ${CRYPT_SILENT}
else
good_msg "Please insert removable device ${LUKS_KEYDEV} for ${LUKS_NAME}" ${CRYPT_SILENT}
# abort after 10 secs
local count=10
while [ ${count} -gt 0 ]
do
count=$((count-1))
sleep 1
if [ -b "${LUKS_KEYDEV}" ]
then
good_msg "Removable device ${LUKS_KEYDEV} detected." ${CRYPT_SILENT}
break
fi
done
if [ ! -b "${LUKS_KEYDEV}" ]
then
eval CRYPT_${TYPE}_KEY=${LUKS_KEY}
bootstrapKey ${TYPE}
eval LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"'
if [ ! -b "${LUKS_KEYDEV}" ]; then
KEYDEV_ERROR=1
bad_msg "Removable device ${LUKS_KEYDEV} not found." ${CRYPT_SILENT}
continue
fi
# continue otherwise will mount keydev which is mounted by bootstrap
continue
fi
fi
# At this point a device was recognized, now let's see if the key is there
[ ! -d "$mntkey" ] && mkdir -p ${mntkey} 2>/dev/null >/dev/null
mount -n -o ro ${LUKS_KEYDEV} ${mntkey} >/dev/null 2>/dev/null
if [ "$?" != '0' ]
then
KEYDEV_ERROR=1
bad_msg "Mounting of device ${LUKS_KEYDEV} failed." ${CRYPT_SILENT}
continue
else
good_msg "Removable device ${LUKS_KEYDEV} mounted." ${CRYPT_SILENT}
sleep 2
# keyfile exists?
if [ ! -e "${mntkey}${LUKS_KEY}" ]; then
umount -n ${mntkey} 2>/dev/null >/dev/null
KEY_ERROR=1
KEYDEV_ERROR=1
bad_msg "Key {LUKS_KEY} on device ${LUKS_KEYDEV} not found." ${CRYPT_SILENT}
continue
fi
fi
fi
# At this point a candidate key exists (either mounted before or not)
good_msg "${LUKS_KEY} on device ${LUKS_KEYDEV} found" ${CRYPT_SILENT}
if [ "$(echo ${LUKS_KEY} | grep -o '.gpg$')" = ".gpg" ] && [ -e /sbin/gpg ] ; then
[ -e /dev/tty ] && mv /dev/tty /dev/tty.org
mknod /dev/tty c 5 1
cryptsetup_options="-d -"
gpg_cmd="/sbin/gpg --logger-file /dev/null --quiet --decrypt ${mntkey}${LUKS_KEY} |"
else
cryptsetup_options="-d ${mntkey}${LUKS_KEY}"
fi
fi
# At this point, keyfile or not, we're ready!
crypt_filter "${gpg_cmd}cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}"
if [ $? -eq 0 ]
then
good_msg "LUKS device ${LUKS_DEVICE} opened" ${CRYPT_SILENT}
break
else
bad_msg "Failed to open LUKS device ${LUKS_DEVICE}" ${CRYPT_SILENT}
DEV_ERROR=1
KEY_ERROR=1
KEYDEV_ERROR=1
fi
fi
fi
done
umount ${mntkey} 2>/dev/null >/dev/null
rmdir -p ${mntkey} 2>/dev/null >/dev/null
}
startLUKS() {
# if key is set but key device isn't, find it
[ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \
&& sleep 6 && bootstrapKey "ROOT"
if [ -n "${CRYPT_ROOT}" ]; then
openLUKS "root"
if [ -n "${REAL_ROOT}" ]
then
# Rescan volumes
startVolumes
else
REAL_ROOT="/dev/mapper/root"
fi
fi
# same for swap, but no need to sleep if root was unencrypted
[ -n "${CRYPT_SWAP_KEY}" ] && [ -z "${CRYPT_SWAP_KEYDEV}" ] \
&& { [ -z "${CRYPT_ROOT}" ] && sleep 6; bootstrapKey "SWAP"; }
if [ -n "${CRYPT_SWAP}" ]; then
openLUKS "swap"
if [ -z "${REAL_RESUME}" ]
then
# Resume from swap as default
REAL_RESUME="/dev/mapper/swap"
fi
fi
}
sdelay() {
# Sleep a specific number of seconds if SDELAY is set
if [ "${SDELAY}" ]
then
good_msg "Waiting ${SDELAY} seconds..."
sleep ${SDELAY}
elif [ "${CDROOT}" = '1' ]
then
# many CD/DVD drives require extra sleep, especially when
# connected via USB. Many people reported that 1 second sleep
# is not enough on their notebooks, that's why sleep 3, when booting
# off a livecd is a better default.
sleep 3
else
good_msg 'Hint: Use parameter scandelay[=seconds] if you need waiting here'
fi
}
quiet_kmsg() {
# if QUIET is set make the kernel less chatty
[ -n "$QUIET" ] && echo '0' > /proc/sys/kernel/printk
}
verbose_kmsg() {
# if QUIET is set make the kernel less chatty
[ -n "$QUIET" ] && echo '6' > /proc/sys/kernel/printk
}
cdupdate() {
if [ "${CDROOT}" = '1' ]
then
if [ -x /${CDROOT_PATH}/cdupdate.sh ]
then
good_msg "Running cdupdate.sh"
${CDROOT_PATH}/cdupdate.sh
if [ "$?" != '0' ]
then
bad_msg "Executing cdupdate.sh failed!"
run_shell
fi
else
good_msg 'No cdupdate.sh script found, skipping...'
fi
fi
}
setup_btrfsctl() {
# start BTRFS volume detection, if available
[ -x /sbin/btrfsctl ] && /sbin/btrfsctl -a
}
setup_md_device() {
local device
[ -z "$1" ] && device="${REAL_ROOT}" || device="$1"
[ -z "${device}" ] && return # LiveCD
if [ `echo ${device}|sed -e 's#\(luks:\)\?\(/dev/md\)[[:digit:]]\+#\2#'` = "/dev/md" ]
then
good_msg 'Detected real_root as a md device. Setting up the device node...'
MD_NUMBER=`echo ${device}|sed -e 's#\(luks:\)\?/dev/md\([[:digit:]]\+\)#\2#'`
if [ ! -e /dev/md${MD_NUMBER} ]
then
mknod /dev/md${MD_NUMBER} b 9 ${MD_NUMBER} >/dev/null 2>&1
[ $? -ne 0 ] && bad_msg "Creation of /dev/md${MD_NUMBER} failed..."
fi
mdstart ${MDPART} /dev/md${MD_NUMBER}
fi
}
rundebugshell() {
if [ -n "$DEBUG" ]
then
good_msg 'Starting debug shell as requested by "debug" option.'
good_msg 'Type "exit" to continue with normal bootup.'
[ -x /bin/sh ] && /bin/sh || /bin/ash
fi
}
do_resume() {
if [ -d /proc/suspend2 -o -d /sys/power/suspend2 -o -d /sys/power/tuxonice ]; then
tuxonice_resume
else
swsusp_resume
fi
}
swsusp_resume() {
# determine swap resume partition
local device=$(ls -lL "${REAL_RESUME}" | sed 's/\ */ /g' | cut -d \ -f 5-6 | sed 's/,\ */:/')
[ -f /sys/power/resume ] && echo "${device}" > /sys/power/resume
}
tuxonice_resume() {
local splash_theme
if grep "splash=" /proc/cmdline > /dev/null 2>&1; then
splash_theme=$(cat /proc/cmdline | sed 's/.*splash=/splash=/' | sed 's/ .*//' | sed 's/.*theme://' | sed 's/,.*//')
fi
local tuxonice_userui_program="/sys/power/tuxonice/user_interface/program"
local tuxonice_do_resume="/sys/power/tuxonice/do_resume"
local tuxonice_resumedev="/sys/power/tuxonice/resume"
local tuxonice_replace_swsusp="/sys/power/tuxonice/replace_swsusp"
#
# Backward compatibility
#
if [ -e /sys/power/suspend2 ]; then
tuxonice_userui_program="/sys/power/suspend2/user_interface/program"
tuxonice_do_resume="/sys/power/suspend2/do_resume"
tuxonice_resumedev="/sys/power/suspend2/resume"
tuxonice_replace_swsusp="/sys/power/suspend2/replace_swsusp"
elif [ -e /proc/suspend2 ]; then
tuxonice_userui_program="/proc/suspend2/userui_program"
tuxonice_do_resume="/proc/suspend2/do_resume"
tuxonice_resumedev="/proc/suspend2/resume"
tuxonice_replace_swsusp="/proc/suspend2/replace_swsusp"
fi
# if 'use_swsusp' is given, use swsusp instead
if grep "use_swsusp" /proc/cmdline > /dev/null 2>&1; then
echo 0 > ${tuxonice_replace_swsusp}
swsusp_resume
return
fi
modules_scan tuxonice
# we both configure tuxonice and activate resuming,
# however the kernel will resume only if an image is found
if ! grep suspend_noui /proc/cmdline > /dev/null 2>&1; then
which suspend2ui_text > /dev/null 2>&1 && which suspend2ui_text > "${tuxonice_userui_program}"
which tuxoniceui_text > /dev/null 2>&1 && which tuxoniceui_text > "${tuxonice_userui_program}"
if [ -n "${splash_theme}" ]; then
ln -s /etc/splash/${splash_theme} /etc/splash/suspend2
ln -s /etc/splash/${splash_theme} /etc/splash/tuxonice
which suspend2ui_fbsplash > /dev/null 2>&1 && which suspend2ui_fbsplash > "${tuxonice_userui_program}"
which tuxoniceui_fbsplash > /dev/null 2>&1 && which tuxoniceui_fbsplash > "${tuxonice_userui_program}"
fi
fi
echo "${REAL_RESUME}" > "${tuxonice_resumedev}"
echo > "${tuxonice_do_resume}"
}
find_loop() {
for loop in ${LOOPS}
do
if [ -e "${CDROOT_PATH}""${loop}" ]
then
LOOP="${loop}"
fi
done
}
find_looptype() {
LOOPTYPE="${LOOP##*.}"
[ "${LOOPTYPE}" == "loop" ] && LOOPTYPE="normal"
[ "${LOOP}" == "/zisofs" ] && LOOPTYPE="${LOOP#/}"
[ -z "${LOOPTYPE}" ] && LOOPTYPE="noloop"
}
getdvhoff() {
echo $(( $(hexdump -n 4 -s $((316 + 12 * $2)) -e '"%i"' $1) * 512))
}
setup_squashfs_aufs() {
(
# Setup aufs directories and vars
local overlay=/mnt/overlay
local static=/mnt/livecd
for i in "${overlay}" "${static}"; do
[ ! -d "${i}" ] && mkdir -p "${i}"
done
good_msg "Loading aufs"
modprobe aufs > /dev/null 2>&1
mount -t squashfs -o loop,ro "${CDROOT_PATH}/${LOOPEXT}${LOOP}" "${static}"
mount -t tmpfs none "${overlay}"
mount -t aufs -o br:${overlay}:${static} aufs "${NEW_ROOT}"
[ ! -d "${NEW_ROOT}${overlay}" ] && mkdir -p "${NEW_ROOT}${overlay}"
[ ! -d "${NEW_ROOT}${static}" ] && mkdir -p "${NEW_ROOT}${static}"
echo "aufs / aufs defaults 0 0" > "${NEW_ROOT}"/etc/fstab
for i in "${overlay}" "${static}"; do mount --move "${i}" "${NEW_ROOT}${i}"; done
# have handy /mnt/cdrom (CDROOT_PATH) as well
local new_cdroot="${NEW_ROOT}${CDROOT_PATH}"
[ ! -d "${new_cdroot}" ] && mkdir -p "${new_cdroot}"
mount --bind "${CDROOT_PATH}" "${new_cdroot}"
)
}
setup_unionfs() {
local rw_dir=$1
local ro_dir=$2
if [ "${USE_UNIONFS_NORMAL}" = '1' ]
then
# Directory used for rw changes in union mount filesystem
UNION=/union
# MEMORY=/memory
# if [ -z "$UID" ]
# then
# CHANGES=$MEMORY/unionfs_changes/default
# else
# CHANGES=$MEMORY/unionfs_changes/$UID
# fi
# mkdir -p ${MEMORY}
mkdir -p ${UNION}
good_msg "Loading fuse module"
modprobe fuse > /dev/null 2>&1
# if [ -n "${UNIONFS}" ]
# then
# CHANGESDEV=${UNIONFS}
# good_msg "mounting $CHANGESDEV to $MEMORY for unionfs support"
# mount -t auto $CHANGESDEV $MEMORY
# # mount tmpfs only in the case when changes= boot parameter was
# # empty or we were not able to mount the storage device
# ret=$?
# if [ ${ret} -ne 0 ]
# then
# bad_msg "mount of $CHANGESDEV failed falling back to ramdisk based unionfs"
# mount -t tmpfs tmpfs $MEMORY
# fi
# if [ "${CDROOT}" -eq '1' -a ! -f ${MEMORY}/livecd.unionfs ]
# then
# umount $MEMORY
# bad_msg "failed to find livecd.unionfs file on $CHANGESDEV"
# bad_msg "create a livecd.unionfs file on this device if you wish to use it for unionfs"
# bad_msg "falling back to ramdisk based unionfs for safety"
# mount -t tmpfs tmpfs $MEMORY
# fi
# else
# good_msg "Mounting ramdisk to $MEMORY for unionfs support..."
# mount -t tmpfs tmpfs $MEMORY
# fi
mkdir /tmp
mkdir -p ${UNION}
# mkdir -p $CHANGES
# mount -t unionfs -o dirs=$CHANGES=rw unionfs ${UNION}
good_msg "Creating union mount"
unionfs -o allow_other,cow,noinitgroups,suid,dev,default_permissions,use_ino ${rw_dir}=RW:${ro_dir}=RO ${UNION} 2>/dev/null
ret=$?
if [ ${ret} -ne 0 ]
then
bad_msg "Can't setup union mount!"
USE_UNIONFS_NORMAL=0
fi
[ ! -d "${NEW_ROOT}${CDROOT_PATH}" ] && mkdir -p "${NEW_ROOT}${CDROOT_PATH}"
mount --bind "${CDROOT_PATH}" "${NEW_ROOT}${CDROOT_PATH}"
else
USE_UNIONFS_NORMAL=0
fi
}
get_mounts_list()
{
awk '
/^[[:blank:]]*#/ { next }
{ print $1 }
' ${NEW_ROOT}/etc/initramfs.mounts
}
get_mount_fstype()
{
awk -v fs="$1" '
/^[[:blank:]]*#/ { next }
$2 == fs { print $3 }
' ${NEW_ROOT}/etc/fstab
}
get_mount_options()
{
awk -v fs="$1" '
/^[[:blank:]]*#/ { next }
$2 == fs { print $4 }
' ${NEW_ROOT}/etc/fstab
}
get_mount_device()
{
awk -v fs="$1" '
/^[[:blank:]]*#/ { next }
$2 == fs { print $1 }
' ${NEW_ROOT}/etc/fstab
}
# If the kernel is handed a mount option is does not recognize, it WILL fail to
# mount. util-linux handles auto/noauto, but busybox passes it straight to the kernel
# which then rejects the mount.
# To make like a little easier, busybox mount does not care about leading,
# trailing or duplicate commas.
strip_mount_options()
{
sed -r 's/(,|^)(no)?auto(,|$)/,/g'
}