|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
. /etc/initrd.defaults
|
|
|
|
|
|
|
|
splash() {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
[ -e "${INITRD_SPLASH}" ] && . "${INITRD_SPLASH}"
|
|
|
|
|
|
|
|
is_fbsplash() {
|
|
|
|
if [ -e "${INITRD_SPLASH}" ] && [ "${FBSPLASH}" = '1' ]
|
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
is_plymouth() {
|
|
|
|
if [ "${PLYMOUTH}" = '1' ] && [ "${QUIET}" = '1' ] \
|
|
|
|
&& [ -e "${PLYMOUTHD_BIN}" ]
|
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
is_plymouth_started() {
|
|
|
|
[ -n "${PLYMOUTH_FAILURE}" ] && return 1
|
|
|
|
is_plymouth && "${PLYMOUTH_BIN}" --ping 2>/dev/null && return 0
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
splashcmd() {
|
|
|
|
# plymouth support
|
|
|
|
local cmd="${1}"
|
|
|
|
shift
|
|
|
|
|
|
|
|
case "${cmd}" in
|
|
|
|
init)
|
|
|
|
is_fbsplash && splash init
|
|
|
|
is_plymouth && plymouth_init
|
|
|
|
;;
|
|
|
|
|
|
|
|
verbose)
|
|
|
|
is_fbsplash && splash verbose
|
|
|
|
plymouth_hide
|
|
|
|
;;
|
|
|
|
|
|
|
|
quiet)
|
|
|
|
# no fbsplash support
|
|
|
|
plymouth_show
|
|
|
|
;;
|
|
|
|
|
|
|
|
set_msg)
|
|
|
|
is_fbsplash && splash set_msg "${1}"
|
|
|
|
plymouth_message "${1}"
|
|
|
|
;;
|
|
|
|
|
|
|
|
hasroot)
|
|
|
|
# no fbsplash support
|
|
|
|
plymouth_newroot "${1}"
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
plymouth_init() {
|
|
|
|
good_msg "Enabling Plymouth"
|
|
|
|
mkdir -p /run/plymouth || return 1
|
|
|
|
|
|
|
|
# Make sure that udev is done loading tty and drm
|
|
|
|
if is_udev
|
|
|
|
then
|
|
|
|
udevadm trigger --action=add --attr-match=class=0x030000 \
|
|
|
|
>/dev/null 2>&1
|
|
|
|
udevadm trigger --action=add --subsystem-match=graphics \
|
|
|
|
--subsystem-match=drm --subsystem-match=tty \
|
|
|
|
>/dev/null 2>&1
|
|
|
|
udevadm settle
|
|
|
|
fi
|
|
|
|
|
|
|
|
local consoledev=
|
|
|
|
local other=
|
|
|
|
read consoledev other < /sys/class/tty/console/active
|
|
|
|
consoledev=${consoledev:-tty0}
|
|
|
|
"${PLYMOUTHD_BIN}" --attach-to-session --pid-file /run/plymouth/pid \
|
|
|
|
|| {
|
|
|
|
bad_msg "Plymouth load error";
|
|
|
|
PLYMOUTH_FAILURE=1
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
plymouth_show
|
|
|
|
good_msg "Plymouth enabled"
|
|
|
|
}
|
|
|
|
|
|
|
|
plymouth_hide() {
|
|
|
|
is_plymouth_started && "${PLYMOUTH_BIN}" --hide-splash
|
|
|
|
}
|
|
|
|
|
|
|
|
plymouth_show() {
|
|
|
|
is_plymouth_started && "${PLYMOUTH_BIN}" --show-splash
|
|
|
|
}
|
|
|
|
|
|
|
|
plymouth_message() {
|
|
|
|
is_plymouth_started && "${PLYMOUTH_BIN}" --update="${1}"
|
|
|
|
}
|
|
|
|
|
|
|
|
plymouth_newroot() {
|
|
|
|
is_plymouth_started && "${PLYMOUTH_BIN}" --newroot="${1}"
|
|
|
|
}
|
|
|
|
|
|
|
|
splash_init() {
|
|
|
|
if is_udev; then
|
|
|
|
# if udev, we can load the splash earlier
|
|
|
|
# In the plymouth case, udev will load KMS automatically
|
|
|
|
splashcmd init
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
call_func_timeout() {
|
|
|
|
local func=$1 timeout=$2 pid watcher
|
|
|
|
[ $# -ne 2 ] && gen_die "call_func_timeout() called with $# arguments"
|
|
|
|
|
|
|
|
( ${func} ) & pid=$!
|
|
|
|
( sleep ${timeout} && kill -HUP ${pid} ) 2>/dev/null & watcher=$!
|
|
|
|
if wait ${pid} 2>/dev/null; then
|
|
|
|
kill -HUP $watcher 2> /dev/null
|
|
|
|
wait $watcher 2>/dev/null
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
modules_load() {
|
|
|
|
for module in $*
|
|
|
|
do
|
|
|
|
echo ${module} >> /etc/modules/extra_load
|
|
|
|
done
|
|
|
|
|
|
|
|
modules_scan extra_load
|
|
|
|
}
|
|
|
|
|
|
|
|
modules_scan() {
|
|
|
|
local MODS
|
|
|
|
local loaded
|
|
|
|
|
|
|
|
MODS=$(cat /etc/modules/${1} 2>/dev/null)
|
|
|
|
[ -n "${MODS}" ] && [ -z "${QUIET}" ] && \
|
|
|
|
echo -ne "${BOLD} ::${NORMAL} Loading from ${1}: "
|
|
|
|
|
|
|
|
for x in ${MODS}
|
|
|
|
do
|
|
|
|
MLOAD=$(echo ${MLIST} | sed -e "s/.*${x}.*/${x}/")
|
|
|
|
if [ "${MLOAD}" = "${x}" ] # Only module to no-load
|
|
|
|
then
|
|
|
|
[ -z "${QUIET}" ] && \
|
|
|
|
echo -e "${BOLD} ::${NORMAL} Skipping ${x}..."
|
|
|
|
elif [ "${MLOAD}" = "${MLIST}" ]
|
|
|
|
then
|
|
|
|
if [ -n "${DEBUG}" ]; then
|
|
|
|
echo -ne "${BOLD} ::${NORMAL} "
|
|
|
|
echo -ne "Scanning for ${x}..."
|
|
|
|
fi
|
|
|
|
modprobe ${x} > /dev/null 2>&1
|
|
|
|
loaded=${?}
|
|
|
|
|
|
|
|
[ -n "${DEBUG}" -a "${loaded}" = "0" ] && \
|
|
|
|
echo "loaded"
|
|
|
|
[ -n "${DEBUG}" -a "${loaded}" != "0" ] && \
|
|
|
|
echo "not loaded"
|
|
|
|
|
|
|
|
[ -z "${DEBUG}" -a "${loaded}" = "0" ] && \
|
|
|
|
[ -z "${QUIET}" ] && \
|
|
|
|
echo -en "${x} "
|
|
|
|
else
|
|
|
|
[ -z "${QUIET}" ] && \
|
|
|
|
echo -e "${BOLD} ::${NORMAL} Skipping ${x}..."
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
[ -n "${MODS}" ] && [ -z "${QUIET}" ] && echo
|
|
|
|
}
|
|
|
|
|
|
|
|
modules_init() {
|
|
|
|
if [ -z "${DO_modules}" ]; then
|
|
|
|
good_msg 'Skipping module load; disabled via commandline'
|
|
|
|
elif [ -d "/lib/modules/${KV}" ]; then
|
|
|
|
good_msg 'Loading modules'
|
|
|
|
# Load appropriate kernel modules
|
|
|
|
if [ "${NODETECT}" != '1' ]; then
|
|
|
|
for modules in ${MY_HWOPTS}
|
|
|
|
do
|
|
|
|
modules_scan ${modules}
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
# Always eval doload=...
|
|
|
|
modules_load ${MDOLIST}
|
|
|
|
else
|
|
|
|
good_msg 'Skipping module load; no modules in the ramdisk!'
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Give udev time to execute all the rules. This may be beneficial
|
|
|
|
# for usb-storage devices.
|
|
|
|
is_udev && udevadm settle
|
|
|
|
}
|
|
|
|
|
|
|
|
uppercase() {
|
|
|
|
# needs tr on busybox
|
|
|
|
echo $1 | tr 'a-z' 'A-Z'
|
|
|
|
}
|
|
|
|
|
|
|
|
is_livecd() {
|
|
|
|
[ "${CDROOT}" = "1" ] && return 0
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
is_nfs() {
|
|
|
|
[ "${REAL_ROOT}" = "/dev/nfs" ] && return 0
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
setup_real_root() {
|
|
|
|
if ! is_livecd
|
|
|
|
then
|
|
|
|
if [ -z "${REAL_ROOT}" -a "${FAKE_ROOT}" != "/dev/ram0" ]
|
|
|
|
then
|
|
|
|
REAL_ROOT="${FAKE_ROOT}"
|
|
|
|
fi
|
|
|
|
if [ -z "${REAL_INIT}" -a "${FAKE_INIT}" != "/linuxrc" ]
|
|
|
|
then
|
|
|
|
REAL_INIT="${FAKE_INIT}"
|
|
|
|
fi
|
|
|
|
if [ -z "${REAL_ROOTFLAGS}" ]
|
|
|
|
then
|
|
|
|
REAL_ROOTFLAGS="${FAKE_ROOTFLAGS}"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
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 '/([0-9]+[[:space:]]+)/{print "/dev/" $4}' /proc/partitions)"
|
|
|
|
echo ${DEVICES}
|
|
|
|
}
|
|
|
|
|
|
|
|
bootstrap_cd() {
|
|
|
|
local DEVICES=
|
|
|
|
|
|
|
|
# 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}"
|
|
|
|
[ -z "${CDROOT_DEV}" ] && DEVICES=$(devicelist)
|
|
|
|
|
|
|
|
findmediamount "cdrom" "${SUBDIR}/${CDROOT_MARKER}" \
|
|
|
|
"REAL_ROOT" "${CDROOT_PATH}" ${DEVICES}
|
|
|
|
}
|
|
|
|
|
|
|
|
bootstrap_key() {
|
|
|
|
# $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
|
|
|
|
warn_msg "Failed to cache the loop file! Lack of RAM?"
|
|
|
|
rm -rf ${NEW_ROOT}/mnt/${LOOP} 2>/dev/null
|
|
|
|
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
|
|
|
|
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 is_livecd
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
find_real_device() {
|
|
|
|
local DEVICE="${1}"
|
|
|
|
case "${DEVICE}" in
|
|
|
|
UUID\=*|LABEL\=*)
|
|
|
|
local REAL_DEVICE=""
|
|
|
|
local retval=1
|
|
|
|
|
|
|
|
if [ "${retval}" -ne 0 ]; then
|
|
|
|
REAL_DEVICE=$(findfs "${DEVICE}" 2>/dev/null)
|
|
|
|
retval=$?
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "$retval" -ne 0 ]; then
|
|
|
|
REAL_DEVICE=$(busybox findfs "${DEVICE}" 2>/dev/null)
|
|
|
|
retval=$?
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${retval}" -ne 0 ]; then
|
|
|
|
REAL_DEVICE=$(blkid -o device -l -t "${DEVICE}")
|
|
|
|
retval=$?
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${retval}" -eq 0 ] && [ -n "${REAL_DEVICE}" ]; then
|
|
|
|
DEVICE="${REAL_DEVICE}"
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
echo -n "${DEVICE}"
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
fs_type_in_use() {
|
|
|
|
fs_type=$1
|
|
|
|
cut -d ' ' -f 3 < /proc/mounts | fgrep -q "${fs_type}"
|
|
|
|
}
|
|
|
|
|
|
|
|
is_udev() {
|
|
|
|
[ -x "${UDEVD}" ] && [ -z "${USE_MDEV}" ] && return 0
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
is_mdev() {
|
|
|
|
if [ ! -x "${UDEVD}" ] || [ -n "${USE_MDEV}" ]
|
|
|
|
then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
devmgr_init() {
|
|
|
|
if is_udev; then
|
|
|
|
good_msg 'Activating udev'
|
|
|
|
echo "${UDEVD}" > /proc/sys/kernel/hotplug
|
|
|
|
echo "" > /sys/kernel/uevent_helper
|
|
|
|
"${UDEVD}" --daemon --resolve-names=never && \
|
|
|
|
udevadm trigger --action=add && \
|
|
|
|
udevadm settle || bad_msg "udevd failed to run"
|
|
|
|
elif is_mdev; then
|
|
|
|
good_msg 'Activating mdev'
|
|
|
|
# Serialize hotplug events
|
|
|
|
touch /dev/mdev.seq
|
|
|
|
echo "${MDEVD}" > /proc/sys/kernel/hotplug
|
|
|
|
# Ensure that device nodes are properly configured
|
|
|
|
"${MDEVD}" -s || bad_msg "mdev -s failed"
|
|
|
|
else
|
|
|
|
bad_msg "Cannot find either udev or mdev"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
mount_devfs () {
|
|
|
|
# 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
|
|
|
|
if ! fs_type_in_use devtmpfs; then
|
|
|
|
mount -t $devfs -o "exec,nosuid,mode=0755,size=10M" udev /dev \
|
|
|
|
|| bad_msg "Failed to mount /dev as ${devfs}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# http://git.busybox.net/busybox/plain/docs/mdev.txt
|
|
|
|
if ! fs_type_in_use devpts; then
|
|
|
|
mkdir -m 0755 /dev/pts
|
|
|
|
mount -t devpts -o gid=5,mode=0620 devpts /dev/pts || bad_msg "Failed to mount /dev/pts"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
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() {
|
|
|
|
[ -n "${QUIET}" ] && [ -z "${DEBUG}" ] && return 0
|
|
|
|
|
|
|
|
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
|
|
|
|
splashcmd verbose
|
|
|
|
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}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Courtesy of dracut. Licensed under GPL-2.
|
|
|
|
# Taken from: dracut/modules.d/90crypt/crypt-lib.sh
|
|
|
|
# ask_for_password
|
|
|
|
#
|
|
|
|
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
|
|
|
|
# if plymouth is not present.
|
|
|
|
#
|
|
|
|
# --cmd command
|
|
|
|
# Command to execute. Required.
|
|
|
|
# --prompt prompt
|
|
|
|
# Password prompt. Note that function already adds ':' at the end.
|
|
|
|
# Recommended.
|
|
|
|
# --tries n
|
|
|
|
# How many times repeat command on its failure. Default is 3.
|
|
|
|
# --ply-[cmd|prompt|tries]
|
|
|
|
# Command/prompt/tries specific for plymouth password ask only.
|
|
|
|
# --tty-[cmd|prompt|tries]
|
|
|
|
# Command/prompt/tries specific for tty password ask only.
|
|
|
|
# --tty-echo-off
|
|
|
|
# Turn off input echo before tty command is executed and turn on after.
|
|
|
|
# It's useful when password is read from stdin.
|
|
|
|
ask_for_password() {
|
|
|
|
local cmd; local prompt; local tries=3
|
|
|
|
local ply_cmd; local ply_prompt; local ply_tries=3
|
|
|
|
local tty_cmd; local tty_prompt; local tty_tries=3
|
|
|
|
local ret
|
|
|
|
|
|
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case "$1" in
|
|
|
|
--cmd) ply_cmd="$2"; tty_cmd="$2" shift;;
|
|
|
|
--ply-cmd) ply_cmd="$2"; shift;;
|
|
|
|
--tty-cmd) tty_cmd="$2"; shift;;
|
|
|
|
--prompt) ply_prompt="$2"; tty_prompt="$2" shift;;
|
|
|
|
--ply-prompt) ply_prompt="$2"; shift;;
|
|
|
|
--tty-prompt) tty_prompt="$2"; shift;;
|
|
|
|
--tries) ply_tries="$2"; tty_tries="$2"; shift;;
|
|
|
|
--ply-tries) ply_tries="$2"; shift;;
|
|
|
|
--tty-tries) tty_tries="$2"; shift;;
|
|
|
|
--tty-echo-off) tty_echo_off=yes;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
{ flock -s 9;
|
|
|
|
# Prompt for password with plymouth, if installed and running.
|
|
|
|
if is_plymouth_started
|
|
|
|
then
|
|
|
|
"${PLYMOUTH_BIN}" ask-for-password \
|
|
|
|
--prompt="$ply_prompt" \
|
|
|
|
--number-of-tries=$ply_tries \
|
|
|
|
--command="$ply_cmd"
|
|
|
|
ret=$?
|
|
|
|
else
|
|
|
|
splashcmd verbose
|
|
|
|
if [ "$tty_echo_off" = yes ]; then
|
|
|
|
stty_orig="$(stty -g)"
|
|
|
|
stty -echo
|
|
|
|
fi
|
|
|
|
|
|
|
|
local i=1
|
|
|
|
while [ $i -le $tty_tries ]; do
|
|
|
|
[ -n "$tty_prompt" ] && \
|
|
|
|
printf "$tty_prompt [$i/$tty_tries]:" >&2
|
|
|
|
eval "$tty_cmd" && ret=0 && break
|
|
|
|
ret=$?
|
|
|
|
i=$(($i+1))
|
|
|
|
[ -n "$tty_prompt" ] && printf '\n' >&2
|
|
|
|
done
|
|
|
|
|
|
|
|
[ "$tty_echo_off" = yes ] && stty $stty_orig
|
|
|
|
|
|
|
|
# no need for: splashcmd quiet
|
|
|
|
# since fbsplash does not support it
|
|
|
|
if [ $ret -ne 0 ] && is_fbsplash
|
|
|
|
then
|
|
|
|
splashcmd set_msg 'Disk unlocked.'
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
} 9>/.console_lock
|
|
|
|
|
|
|
|
[ $ret -ne 0 ] && bad_msg "Wrong password"
|
|
|
|
return $ret
|
|
|
|
}
|
|
|
|
|
|
|
|
crypt_exec() {
|
|
|
|
if [ "${CRYPT_SILENT}" = '1' ]
|
|
|
|
then
|
|
|
|
eval ${1} >/dev/null 2>/dev/null
|
|
|
|
else
|
|
|
|
ask_for_password --ply-tries 5 \
|
|
|
|
--ply-cmd "${1}" \
|
|
|
|
--ply-prompt "Encryption password (${LUKS_DEVICE}): " \
|
|
|
|
--tty-tries 5 \
|
|
|
|
--tty-cmd "${1}" || return 1
|
|
|
|
return 0
|
|
|
|
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."
|
|
|
|
bad_msg "Please file a bug report with this message" && exit 1
|
|
|
|
[ -n "${3}" ] && local explnt=" or : ${3}" || local explnt="."
|
|
|
|
|
|
|
|
splashcmd verbose
|
|
|
|
bad_msg "Could not find the ${2} in ${oldvalue}${explnt}"
|
|
|
|
bad_msg "Please specify another value or:"
|
|
|
|
bad_msg "- press Enter for the same"
|
|
|
|
bad_msg '- type "shell" for a shell'
|
|
|
|
bad_msg '- type "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}
|
|
|
|
warn_msg "To leave and try again just press <Ctrl>+D"
|
|
|
|
run_shell
|
|
|
|
;;
|
|
|
|
'')
|
|
|
|
eval ${1}'='${oldvalue}
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
splashcmd quiet
|
|
|
|
}
|
|
|
|
|
|
|
|
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 ] && choose_keymap
|
|
|
|
|
|
|
|
[ "${DEVBIND}" = '1' ] && umount /dev
|
|
|
|
|
|
|
|
if [ -e /etc/sysconfig/keyboard ] && is_livecd
|
|
|
|
then
|
|
|
|
mkdir -p ${NEW_ROOT}/etc/sysconfig/
|
|
|
|
cp /etc/sysconfig/keyboard ${NEW_ROOT}/etc/sysconfig/keyboard
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
choose_keymap() {
|
|
|
|
good_msg "Loading keymaps"
|
|
|
|
if [ -z "${keymap}" ]
|
|
|
|
then
|
|
|
|
splashcmd verbose
|
|
|
|
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 ;;
|
|
|
|
43|sf|ch*) keymap=sf ;;
|
|
|
|
esac
|
|
|
|
fi
|
|
|
|
if [ -e /lib/keymaps/${keymap}.map ]
|
|
|
|
then
|
|
|
|
good_msg "Loading the ''${keymap}'' keymap"
|
|
|
|
loadkmap < /lib/keymaps/${keymap}.map
|
|
|
|
mkdir -p /etc/sysconfig
|
|
|
|
echo "XKEYBOARD=${keymap}" > /etc/sysconfig/keyboard
|
|
|
|
splashcmd set_msg "Set keymap to ${keymap}"
|
|
|
|
elif [ -z "${keymap}" ]
|
|
|
|
then
|
|
|
|
good_msg
|
|
|
|
good_msg "Keeping default keymap"
|
|
|
|
splashcmd set_msg "Keeping default keymap"
|
|
|
|
else
|
|
|
|
bad_msg "Sorry, but keymap ''${keymap}'' is invalid!"
|
|
|
|
unset keymap
|
|
|
|
choose_keymap
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# This helper function is to be called using call_func_timeout.
|
|
|
|
# This works around the inability of busybox modprobe to handle complex module
|
|
|
|
# dependencies. This also enables us to wait a reasonable amount of time until
|
|
|
|
# /dev/zfs appears.
|
|
|
|
wait_for_zfs() {
|
Workaround busybox modprobe's inability to load ZFS modules
Commit 3a054014e880e5b1ff28e3d87767c45a073da6b5 replaced our modprobe
with busybox's modprobe. Unfortunately, busybox's modprobe appears to be
unable to properly load modules with more than 1 level of dependencies.
The zfs and zpool commands will invoke modprobe if /dev/zvol is missing,
which concealed this problem. However, this caused problems because some
invocations would fail and under certain circumstances, init would be
killed, causing a kernel panic. This issue was made clear by commit
c812c35100771bb527f6b03853fa6d8ef66a48fe, which ensured that the zpool
and zfs commands were not run until the ZFS module was loaded.
busybox modprobe's failure to load module dependencies correctly appears
to occur because busybox modprobe does not wait until until a module is
loaded before loading a module that depends on it, which is a race. It
would be best to correct this race by waiting until the module has
properly loaded, but it is not clear that the race is the only thing
going wrong and developer time is a premium.
We implement a workaround by modifying the busy loop added in the
previous commit to explicit call `modprobe zfs` on each iteration. While
the first few calls fail due to bugs in busybox modprobe, it will
eventually work, after which each call is a noop. This lets us keep
looping until either the loop exit condition that /dev/zvol exist is
reached or the 5 second timeout is reached.
Once the busybox modprobe issue is fixed, this workaround should be safe
to revert.
Signed-off-by: Richard Yao <ryao@gentoo.org>
12 years ago
|
|
|
while [ ! -c /dev/zfs ]; do modprobe zfs 2> /dev/null; done;
|
|
|
|
}
|
|
|
|
|
|
|
|
zfs_init() {
|
|
|
|
# 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
|
|
|
|
for i in /sbin/zfs /sbin/zpool
|
|
|
|
do
|
|
|
|
if [ ! -x ${i} ]
|
|
|
|
then
|
|
|
|
USE_ZFS=0
|
|
|
|
bad_msg 'Aborting use of zfs because ${i} not found!'
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
start_volumes() {
|
|
|
|
#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
|
|
|
|
if [ -e '/sbin/mdadm' ]
|
|
|
|
then
|
|
|
|
/sbin/mdadm --assemble --scan
|
|
|
|
else
|
|
|
|
bad_msg "mdadm not found: skipping mdadm raid assembly!"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${USE_MULTIPATH_NORMAL}" = '1' ]
|
|
|
|
then
|
|
|
|
good_msg "Scanning for multipath devices"
|
|
|
|
/sbin/multipath -v 0
|
|
|
|
sleep 2
|
|
|
|
good_msg "Activating multipath devices"
|
|
|
|
/sbin/dmsetup ls --target multipath --exec "/sbin/kpartx -a -v"
|
|
|
|
#for MULTIPATH_VOLUMES in /dev/mapper/*; do kpartx -a $MULTIPATH_VOLUMES; done
|
|
|
|
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 '/sbin/lvm' ]
|
|
|
|
then
|
|
|
|
|
|
|
|
if is_mdev
|
|
|
|
then
|
|
|
|
for dev in ${RAID_DEVICES}
|
|
|
|
do
|
|
|
|
setup_md_device "${dev}"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
|
|
|
|
# This is needed for /sbin/lvm to accept the following logic
|
|
|
|
lvm_commands="#! /sbin/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"
|
|
|
|
if is_mdev
|
|
|
|
then
|
|
|
|
# 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"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# 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}" | /sbin/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
|
|
|
|
|
|
|
|
# Avoid race involving asynchronous module loading
|
|
|
|
if call_func_timeout wait_for_zfs 5
|
|
|
|
then
|
|
|
|
bad_msg "Cannot import ZFS pool because /dev/zfs is missing"
|
|
|
|
elif [ -z "${ZFS_POOL}" ]
|
|
|
|
then
|
|
|
|
good_msg "Importing ZFS pools"
|
|
|
|
|
|
|
|
/sbin/zpool import -N -a ${ZPOOL_FORCE}
|
|
|
|
|
|
|
|
if [ "$?" = '0' ]
|
|
|
|
then
|
|
|
|
good_msg "Importing ZFS pools succeeded"
|
|
|
|
else
|
|
|
|
bad_msg "Imported ZFS pools failed"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
|
|
|
|
if [ "$(zpool list -H -o name ${ZFS_POOL} 2>&1)" = "$ZFS_POOL" ]
|
|
|
|
then
|
|
|
|
good_msg "ZFS pool ${ZFS_POOL} already imported."
|
|
|
|
|
|
|
|
if [ -n "${CRYPT_ROOT}" -o -n "${CRYPT_SWAP}" ]
|
|
|
|
then
|
|
|
|
good_msg "LUKS detected. Reimporting ${ZFS_POOL}"
|
|
|
|
/sbin/zpool export -f "${ZFS_POOL}"
|
|
|
|
/sbin/zpool import -N ${ZPOOL_FORCE} "${ZFS_POOL}"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
good_msg "Importing ZFS pool ${ZFS_POOL}"
|
|
|
|
|
|
|
|
/sbin/zpool import -N ${ZPOOL_FORCE} "${ZFS_POOL}"
|
|
|
|
|
|
|
|
if [ "$?" = '0' ]
|
|
|
|
then
|
|
|
|
good_msg "Import of ${ZFS_POOL} succeeded"
|
|
|
|
else
|
|
|
|
bad_msg "Import of ${ZFS_POOL} failed"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
is_udev && udevadm settle
|
|
|
|
}
|
|
|
|
|
|
|
|
start_iscsi() {
|
|
|
|
if [ ! -e /usr/sbin/iscsistart ]; then
|
|
|
|
return 0 # disabled
|
|
|
|
fi
|
|
|
|
|
|
|
|
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
|
|
|
|
open_luks() {
|
|
|
|
# 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
|
|
|
|
LUKS_DEVICE=$(find_real_device "${LUKS_DEVICE}")
|
|
|
|
|
|
|
|
setup_md_device ${LUKS_DEVICE}
|
|
|
|
/sbin/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
|
|
|
|
local REAL_LUKS_KEYDEV="${LUKS_KEYDEV}"
|
|
|
|
if [ ! -e "${mntkey}${LUKS_KEY}" ]
|
|
|
|
then
|
|
|
|
REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}")
|
|
|
|
if [ -b "${REAL_LUKS_KEYDEV}" ]
|
|
|
|
then good_msg "Using key device ${REAL_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
|
|
|
|
REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}")
|
|
|
|
if [ -b "${REAL_LUKS_KEYDEV}" ]
|
|
|
|
then
|
|
|
|
good_msg "Removable device ${REAL_LUKS_KEYDEV} detected." ${CRYPT_SILENT}
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
if [ ! -b "${REAL_LUKS_KEYDEV}" ]
|
|
|
|
then
|
|
|
|
eval CRYPT_${TYPE}_KEY=${LUKS_KEY}
|
|
|
|
bootstrap_key ${TYPE}
|
|
|
|
eval LUKS_KEYDEV='"${CRYPT_'${TYPE}'_KEYDEV}"'
|
|
|
|
REAL_LUKS_KEYDEV=$(find_real_device "${LUKS_KEYDEV}")
|
|
|
|
if [ ! -b "${REAL_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 ${REAL_LUKS_KEYDEV} ${mntkey} >/dev/null 2>/dev/null
|
|
|
|
if [ "$?" != '0' ]
|
|
|
|
then
|
|
|
|
KEYDEV_ERROR=1
|
|
|
|
bad_msg "Mounting of device ${REAL_LUKS_KEYDEV} failed." ${CRYPT_SILENT}
|
|
|
|
continue
|
|
|
|
else
|
|
|
|
good_msg "Removable device ${REAL_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 ${REAL_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 ${REAL_LUKS_KEYDEV} found" ${CRYPT_SILENT}
|
|
|
|
if [ "$(echo ${LUKS_KEY} | grep -o '.gpg$')" = ".gpg" ] && [ -e /usr/bin/gpg ] ; then
|
|
|
|
[ -e /dev/tty ] && mv /dev/tty /dev/tty.org
|
|
|
|
mknod /dev/tty c 5 1
|
|
|
|
cryptsetup_options="${cryptsetup_options} -d -"
|
|
|
|
gpg_cmd="/usr/bin/gpg --logger-file /dev/null --quiet --decrypt ${mntkey}${LUKS_KEY} |"
|
|
|
|
else
|
|
|
|
cryptsetup_options="${cryptsetup_options} -d ${mntkey}${LUKS_KEY}"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
# At this point, keyfile or not, we're ready!
|
|
|
|
crypt_exec "${gpg_cmd}/sbin/cryptsetup ${cryptsetup_options} luksOpen ${LUKS_DEVICE} ${LUKS_NAME}"
|
|
|
|
crypt_exec_ret=$?
|
|
|
|
|
|
|
|
[ -e /dev/tty.org ] \
|
|
|
|
&& rm -f /dev/tty \
|
|
|
|
&& mv /dev/tty.org /dev/tty
|
|
|
|
|
|
|
|
if [ ${crypt_exec_ret} -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
|
|
|
|
}
|
|
|
|
|
|
|
|
start_luks() {
|
|
|
|
# if key is set but key device isn't, find it
|
|
|
|
[ -n "${CRYPT_ROOT_KEY}" ] && [ -z "${CRYPT_ROOT_KEYDEV}" ] \
|
|
|
|
&& sleep 6 && bootstrap_key "ROOT"
|
|
|
|
|
|
|
|
if [ -n "${CRYPT_ROOT}" ]; then
|
|
|
|
open_luks "root"
|
|
|
|
if [ -n "${REAL_ROOT}" ]
|
|
|
|
then
|
|
|
|
# Rescan volumes
|
|
|
|
start_volumes
|
|
|
|
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; bootstrap_key "SWAP"; }
|
|
|
|
|
|
|
|
if [ -n "${CRYPT_SWAP}" ]; then
|
|
|
|
open_luks "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 [ -n "${SDELAY}" ]
|
|
|
|
then
|
|
|
|
good_msg "Waiting ${SDELAY} seconds..."
|
|
|
|
sleep ${SDELAY}
|
|
|
|
elif is_livecd
|
|
|
|
then
|
|
|
|
good_msg 'Hint: Use scandelay[=seconds] if your live medium is slowand boot fails'
|
|
|
|
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 is_livecd
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
do_rundebugshell() {
|
|
|
|
splashcmd verbose
|
|
|
|
good_msg 'Type "exit" to continue with normal bootup.'
|
|
|
|
[ -x /bin/sh ] && /bin/sh || /bin/ash
|
|
|
|
splashcmd quiet
|
|
|
|
}
|
|
|
|
|
|
|
|
rundebugshell() {
|
|
|
|
if [ -n "$DEBUG" ]
|
|
|
|
then
|
|
|
|
good_msg 'Starting debug shell as requested by "debug" option.'
|
|
|
|
good_msg "Stopping by: ${1}"
|
|
|
|
do_rundebugshell
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
resume_init() {
|
|
|
|
if [ -z "${REAL_RESUME}" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
if [ "${NORESUME}" = "1" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
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 -a -n "${device}" ] && \
|
|
|
|
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}"
|
|
|
|
}
|
|
|
|
|
|
|
|
livecd_init() {
|
|
|
|
good_msg "Making tmpfs for ${NEW_ROOT}"
|
|
|
|
mount -n -t tmpfs tmpfs "${NEW_ROOT}"
|
|
|
|
|
|
|
|
local dirs=
|
|
|
|
|
|
|
|
dirs="dev mnt proc run sys tmp mnt/livecd"
|
|
|
|
dirs="${dirs} mnt/key tmp/.initrd mnt/gentoo"
|
|
|
|
for i in ${dirs}; 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
|
|
|
|
|
|
|
|
# For SGI LiveCDs ...
|
|
|
|
if [ "${LOOPTYPE}" = "sgimips" ]; then
|
|
|
|
[ ! -e "${NEW_ROOT}/dev/sr0" ] && \
|
|
|
|
mknod "${NEW_ROOT}/dev/sr0" b 11 0
|
|
|
|
[ ! -e "${NEW_ROOT}/dev/loop0" ] && \
|
|
|
|
mknod "${NEW_ROOT}/dev/loop0" b 7 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Required for splash to work. Not an issue with the initrd as this
|
|
|
|
# device isn't created there and is not needed.
|
|
|
|
if [ -e /dev/tty1 ]; then
|
|
|
|
[ ! -e "${NEW_ROOT}/dev/tty1" ] && \
|
|
|
|
mknod "${NEW_ROOT}/dev/tty1" c 4 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! is_nfs && [ "${LOOPTYPE}" != "sgimips" ]; then
|
|
|
|
bootstrap_cd
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${REAL_ROOT}" = '' ]
|
|
|
|
then
|
|
|
|
warn_msg "No bootable medium found. Waiting for new devices..."
|
|
|
|
COUNTER=0
|
|
|
|
while [ ${COUNTER} -lt 3 ]; do
|
|
|
|
sleep 3
|
|
|
|
let COUNTER=${COUNTER}+1
|
|
|
|
done
|
|
|
|
sleep 1
|
|
|
|
bootstrap_cd
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ "${REAL_ROOT}" = '' ]
|
|
|
|
then
|
|
|
|
# leave stale mounts around, make possible to debug
|
|
|
|
bad_msg 'Could not find CD to boot, something else needed!'
|
|
|
|
CDROOT=0
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mounts_list() {
|
|
|
|
awk '
|
|
|
|
/^[[:blank:]]*#/ { next }
|
|
|
|
{ print $1 }
|
|
|
|
' ${NEW_ROOT}/etc/initramfs.mounts
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mount_fstype() {
|
|
|
|
[ -e "${NEW_ROOT}"/etc/fstab ] || return 1
|
|
|
|
awk -v fs="$1" '
|
|
|
|
/^[[:blank:]]*#/ { next }
|
|
|
|
$2 == fs { print $3 }
|
|
|
|
' ${NEW_ROOT}/etc/fstab
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mount_options() {
|
|
|
|
[ -e "${NEW_ROOT}"/etc/fstab ] || return 1
|
|
|
|
awk -v fs="$1" '
|
|
|
|
/^[[:blank:]]*#/ { next }
|
|
|
|
$2 == fs { print $4 }
|
|
|
|
' ${NEW_ROOT}/etc/fstab
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mount_device() {
|
|
|
|
[ -e "${NEW_ROOT}"/etc/fstab ] || return 1
|
|
|
|
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'
|
|
|
|
}
|
|
|
|
|
|
|
|
# Read /etc/initramfs.mounts from ${NEW_ROOT} and mount the
|
|
|
|
# listed filesystem mountpoints. For instance, /usr, which is
|
|
|
|
# required by udev & systemd.
|
|
|
|
ensure_initramfs_mounts() {
|
|
|
|
local fslist=
|
|
|
|
|
|
|
|
if [ -f "${NEW_ROOT}/etc/initramfs.mounts" ]; then
|
|
|
|
fslist="$(get_mounts_list)"
|
|
|
|
else
|
|
|
|
fslist="/usr"
|
|
|
|
fi
|
|
|
|
|
|
|
|
local dev= fstype= opts= mnt= cmd=
|
|
|
|
for fs in ${fslist}; do
|
|
|
|
|
|
|
|
mnt="${NEW_ROOT}${fs}"
|
|
|
|
if mountpoint -q "${mnt}"; then
|
|
|
|
good_msg "${fs} already mounted, skipping..."
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
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)"
|
|
|
|
opts="${opts},ro"
|
|
|
|
fi
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
rootdev_init() {
|
|
|
|
good_msg "Initializing root device..."
|
|
|
|
|
|
|
|
while true
|
|
|
|
do
|
|
|
|
local got_good_root=
|
|
|
|
while [ "${got_good_root}" != '1' ]
|
|
|
|
do
|
|
|
|
case "${REAL_ROOT}" in
|
|
|
|
LABEL=*|UUID=*)
|
|
|
|
|
|
|
|
ROOT_DEV=""
|
|
|
|
retval=1
|
|
|
|
|
|
|
|
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)
|
|
|
|
retval=$?
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ${retval} -ne 0 ]; then
|
|
|
|
ROOT_DEV=$(blkid -o device -l -t "${REAL_ROOT}")
|
|
|
|
retval=$?
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ${retval} -eq 0 ] && [ -n "${ROOT_DEV}" ]; then
|
|
|
|
good_msg "Detected real_root=${ROOT_DEV}"
|
|
|
|
REAL_ROOT="${ROOT_DEV}"
|
|
|
|
else
|
|
|
|
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.
|
|
|
|
prompt_user "REAL_ROOT" "root block device"
|
|
|
|
got_good_root=0
|
|
|
|
|
|
|
|
# Check for a block device or NFS
|
|
|
|
elif [ -b "${REAL_ROOT}" ] || is_nfs
|
|
|
|
then
|
|
|
|
got_good_root=1
|
|
|
|
|
|
|
|
else
|
|
|
|
bad_msg "Block device ${REAL_ROOT} is not a valid root device..."
|
|
|
|
REAL_ROOT=""
|
|
|
|
got_good_root=0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
if [ "${got_good_root}" = "1" ] && is_livecd && ! is_nfs
|
|
|
|
then
|
|
|
|
# CD already mounted; no further checks necessary
|
|
|
|
break
|
|
|
|
elif [ "${LOOPTYPE}" = "sgimips" ]
|
|
|
|
then
|
|
|
|
# sgimips mounts the livecd root partition directly
|
|
|
|
# there is no isofs filesystem to worry about
|
|
|
|
break
|
|
|
|
else
|
|
|
|
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 is_nfs; then
|
|
|
|
findnfsmount
|
|
|
|
else
|
|
|
|
# mount ro so fsck doesn't barf later
|
|
|
|
if [ "${REAL_ROOTFLAGS}" = '' ]; then
|
|
|
|
good_msg "Using mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE}"
|
|
|
|
mount -t ${ROOTFSTYPE} -o ${MOUNT_STATE} ${REAL_ROOT} ${NEW_ROOT}
|
|
|
|
else
|
|
|
|
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
|
|
|
|
# else not a good root and start over.
|
|
|
|
if [ "$?" = '0' ]
|
|
|
|
then
|
|
|
|
# now that the root filesystem is mounted, before
|
|
|
|
# checking the validity of ${NEW_ROOT} and ${REAL_INIT},
|
|
|
|
# ensure that ${NEW_ROOT}/etc/initramfs.mounts entries
|
|
|
|
# are mounted.
|
|
|
|
ensure_initramfs_mounts
|
|
|
|
|
|
|
|
# NFS does not need further checks here.
|
|
|
|
if is_nfs; then
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ ! -d "${NEW_ROOT}/dev" ]; then
|
|
|
|
_msg="The filesystem ${REAL_ROOT},"
|
|
|
|
_msg="${_msg} mounted at ${NEW_ROOT}"
|
|
|
|
_msg="${_msg} does not contain /dev"
|
|
|
|
_msg="${_msg}, init will likely fail..."
|
|
|
|
bad_msg "${_msg}"
|
|
|
|
fi
|
|
|
|
if [ ! -x "${NEW_ROOT}${REAL_INIT:-/sbin/init}" ]; then
|
|
|
|
_msg="The filesystem ${REAL_ROOT},"
|
|
|
|
_msg="${_msg} mounted at ${NEW_ROOT}"
|
|
|
|
_msg="${_msg} does not contain a valid"
|
|
|
|
_msg="${_msg} init=${REAL_INIT}"
|
|
|
|
bad_msg "${_msg}"
|
|
|
|
fi
|
|
|
|
break
|
|
|
|
else
|
|
|
|
bad_msg "Could not mount specified ROOT, try again"
|
|
|
|
got_good_root=0
|
|
|
|
REAL_ROOT=''
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|