595 lines
14 KiB
Bash
595 lines
14 KiB
Bash
#!/bin/sh
|
||
#
|
||
# Simple init script that should handle both
|
||
# livecd/livedisk, thinclient and hdd boot
|
||
#
|
||
|
||
PATH=/usr/sbin:/usr/bin:/sbin:/bin
|
||
INITRAMFSCONF="/etc/initramfs.conf"
|
||
|
||
ROOT_LINKS="bin sbin lib boot usr opt"
|
||
ROOT_TREES="etc root home var run"
|
||
TMPFS_DIRS="dev mnt mnt/cdrom mnt/livecd mnt/thin tmp sys proc media"
|
||
LOOPBACKFILE="/boot/pisi.sqfs"
|
||
|
||
NORESUME=0
|
||
LIVE=0
|
||
NFSROOT=0
|
||
QUIET=0
|
||
RAID_INCREMENTAL=1
|
||
RAID=0
|
||
LVM=0
|
||
COPYTORAM=0
|
||
SPLASH=0
|
||
WIPEMEM=0
|
||
|
||
HOTPLUG="/sbin/hotplug"
|
||
|
||
MNTDIR=""
|
||
FS_TYPE=""
|
||
INITRAMFS=""
|
||
ROOT_FLAGS=""
|
||
ROOT_DEVICE=""
|
||
ROOT_TARGET=""
|
||
RESUME_DEVICE=""
|
||
WIPEMEM_OPTS="-llv"
|
||
|
||
###########################
|
||
# Miscellaneous functions #
|
||
###########################
|
||
|
||
info() {
|
||
echo "<6>initramfs: $1" > /dev/kmsg
|
||
}
|
||
|
||
log_output() {
|
||
$@ | echo "<6>`sed 's#^\(.*\)$#initramfs:\1#g'`" > /dev/kmsg
|
||
}
|
||
|
||
fall2sh() {
|
||
# Kill any possible plymouth instances
|
||
test -x /bin/plymouth && /bin/plymouth quit &> /dev/null
|
||
kill -9 $(pidof plymouthd) &> /dev/null
|
||
|
||
echo "--> $*"
|
||
echo "Reboot with initramfs=shell(noprobe) to further debug the issue."
|
||
|
||
# Use a login shell for sourcing /etc/profile
|
||
/bin/sh -l
|
||
}
|
||
|
||
run_dhcpc() {
|
||
udhcpc -C -i eth0 -s /etc/udhcpc.script
|
||
}
|
||
|
||
##################
|
||
# Device probers #
|
||
##################
|
||
|
||
probe_devices() {
|
||
# Set hotplug helper for firmware loading
|
||
echo $HOTPLUG > /proc/sys/kernel/hotplug
|
||
|
||
if [ "x$1" = "x--with-kms" ]; then
|
||
probe_kms
|
||
test -x /bin/plymouth && /bin/plymouth show-splash
|
||
fi
|
||
|
||
probe_pci_devices
|
||
probe_virtio_devices
|
||
probe_usb_devices
|
||
|
||
# Unset hotplug helper
|
||
echo > /proc/sys/kernel/hotplug
|
||
|
||
[ "${RAID}" -eq "1" ] && probe_raid
|
||
[ "${LVM}" -eq "1" ] && probe_lvm
|
||
}
|
||
|
||
probe_kms() {
|
||
for device in /sys/bus/pci/devices/*/boot_vga; do
|
||
[ -f $device ] || continue
|
||
info "Loading KMS driver"
|
||
grep -q 1 $device && modprobe -bq `cat ${device%boot_vga}modalias`
|
||
done
|
||
if [ ! -c /dev/fb0 ]; then
|
||
echo "options uvesafb scroll=ywrap mtrr=0 nocrtc=1 mode_option=1024x768-32" > /etc/modprobe.d/uvesafb.conf
|
||
modprobe -bq uvesafb
|
||
fi
|
||
}
|
||
|
||
probe_pci_devices() {
|
||
info "Probing PCI devices"
|
||
local MODULES=""
|
||
for module in /sys/bus/pci/devices/*/modalias; do
|
||
[ -f $module ] || continue
|
||
MODULES="$MODULES $(cat $module)"
|
||
done
|
||
modprobe -bqa $MODULES
|
||
}
|
||
|
||
probe_usb_devices() {
|
||
info "Probing USB devices"
|
||
local MODULES=""
|
||
for module in /sys/bus/usb/devices/*/modalias; do
|
||
[ -f $module ] || continue
|
||
MODULES="$MODULES $(cat $module)"
|
||
done
|
||
modprobe -bqa $MODULES
|
||
}
|
||
|
||
probe_raid() {
|
||
info "Probing RAID devices"
|
||
modprobe -bqa dm-mod raid0 raid1 raid10 raid456
|
||
if [ -x /sbin/mdadm ]
|
||
then
|
||
/sbin/mdadm --examine --scan > /etc/mdadm.conf
|
||
/sbin/mdadm -As
|
||
fi
|
||
}
|
||
|
||
probe_lvm() {
|
||
info "Probing LVM devices"
|
||
modprobe -qa dm-mod
|
||
if [ -x /sbin/lvm ]
|
||
then
|
||
/sbin/lvm vgscan --ignorelockingfailure &> /dev/null
|
||
/sbin/lvm vgchange -ay --sysinit --ignorelockingfailure &> /dev/null
|
||
/sbin/lvm vgmknodes --ignorelockingfailure &> /dev/null
|
||
fi
|
||
}
|
||
probe_virtio_devices() {
|
||
local MODULES=""
|
||
for module in /sys/bus/virtio/devices/*/modalias; do
|
||
[ -f $module ] || continue
|
||
MODULES="$MODULES $(cat $module)"
|
||
done
|
||
modprobe -bqa $MODULES
|
||
}
|
||
|
||
#################################
|
||
# Filesystem specific functions #
|
||
#################################
|
||
|
||
mount_rootfs() {
|
||
FS_TYPE=`disktype $ROOT_DEVICE | grep KERNELMODULE | awk '{print $2}'`
|
||
info "Mounting rootfs: $ROOT_DEVICE ($FS_TYPE)"
|
||
mount -r -t $FS_TYPE -n ${ROOT_FLAGS} ${ROOT_DEVICE} /newroot
|
||
}
|
||
|
||
find_live_mount() {
|
||
modprobe -bqa usb-storage udf
|
||
if [ "$#" -gt "0" ]
|
||
then
|
||
for x in $*
|
||
do
|
||
# this is used for non Linux fs detection
|
||
FS_TYPE=`disktype $1 | grep KERNELMODULE | awk '{print $2}'`
|
||
if [ -n "$FS_TYPE" -a -f /lib/modules/*/$FS_TYPE.ko ]
|
||
then
|
||
modprobe $FS_TYPE 1> /dev/null 2>&1
|
||
fi
|
||
|
||
mount -r ${x} /newroot/mnt/cdrom > /dev/null 2>&1
|
||
|
||
if [ "$?" = "0" ]
|
||
then
|
||
# Check for cdroot image
|
||
if [ -e /newroot/mnt/cdrom/${LOOPBACKFILE} ]
|
||
then
|
||
ROOT_DEVICE="/newroot${x}"
|
||
if [ "$COPYTORAM" == "1" ]
|
||
then
|
||
info "Copying Live Media files to RAM"
|
||
mkdir /newroot/mnt/cdromtemp
|
||
cp -af /newroot/mnt/cdrom/* /newroot/mnt/cdromtemp/
|
||
umount /newroot/mnt/cdrom
|
||
rmdir /newroot/mnt/cdrom
|
||
mv /newroot/mnt/cdromtemp /newroot/mnt/cdrom
|
||
fi
|
||
break
|
||
else
|
||
umount /newroot/mnt/cdrom
|
||
fi
|
||
fi
|
||
done
|
||
fi
|
||
}
|
||
|
||
manage_tmpfs() {
|
||
mount -t tmpfs tmpfs /newroot
|
||
|
||
for d in ${TMPFS_DIRS}; do
|
||
mkdir -p "/newroot/${d}"
|
||
done
|
||
}
|
||
|
||
mount_nfs() {
|
||
FS_LOCATION='mnt/thin'
|
||
|
||
# Change directory to /newroot
|
||
cd /newroot
|
||
|
||
# FIXME: busybox mount does not load automatically
|
||
modprobe -q nfs
|
||
|
||
# mount nfs
|
||
if [ -z "/etc/udhcpc.info" ]
|
||
then
|
||
fall2sh "/etc/udhcpc.info not found"
|
||
fi
|
||
|
||
. /etc/udhcpc.info
|
||
|
||
if [ -z "${ROOTPATH}" ]
|
||
then
|
||
fall2sh "NFS rootpath not found"
|
||
fi
|
||
|
||
echo "Mounting NFS from $ROOTPATH"
|
||
mount -o tcp,nolock,ro $ROOTPATH /newroot/mnt/thin
|
||
|
||
if [ "$?" != '0' ]
|
||
then
|
||
fall2sh "Could not nfs root"
|
||
fi
|
||
|
||
# Create necessary links
|
||
for x in ${ROOT_LINKS}; do
|
||
ln -s "${FS_LOCATION}/${x}" "${x}"
|
||
done
|
||
|
||
if [ -e "${FS_LOCATION}/lib32" ]
|
||
then
|
||
ln -s "${FS_LOCATION}/lib32" "lib32"
|
||
fi
|
||
|
||
# We need this for x86_64
|
||
ln -s "${FS_LOCATION}/lib" "lib64"
|
||
|
||
chmod 1777 tmp
|
||
(cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot)
|
||
|
||
# Needed for ltspfs mechanism
|
||
echo "$IP $HOSTNAME" >> /newroot/etc/hosts
|
||
}
|
||
|
||
mount_cdroot() {
|
||
FS_LOCATION="mnt/livecd"
|
||
|
||
# Change directory to /newroot
|
||
cd /newroot
|
||
|
||
# These are not loaded automatically
|
||
modprobe -q squashfs
|
||
|
||
# Loop type squashfs
|
||
mount -t squashfs -o loop,ro /newroot/mnt/cdrom/${LOOPBACKFILE} /newroot/mnt/livecd
|
||
|
||
if [ "$?" != "0" ]
|
||
then
|
||
fall2sh "Could not mount root image"
|
||
fi
|
||
|
||
# Create necessary links
|
||
for x in ${ROOT_LINKS}; do
|
||
ln -s "${FS_LOCATION}/${x}" "${x}"
|
||
done
|
||
|
||
if [ -e "${FS_LOCATION}/lib32" ]
|
||
then
|
||
ln -s "${FS_LOCATION}/lib32" "lib32"
|
||
fi
|
||
|
||
# We need this for x86_64
|
||
ln -s "${FS_LOCATION}/lib" "lib64"
|
||
|
||
chmod 1777 tmp
|
||
(cd /newroot/${FS_LOCATION}; cp -a ${ROOT_TREES} /newroot)
|
||
|
||
# FIXME: the device list is taken from udev, we can't rely on sys entries since pluggable means different
|
||
# in kernel world. Suggestions that do not include this kind of regexp mania are welcome
|
||
|
||
# for userspace applications
|
||
REAL_ROOT_TYPE=`echo "${ROOT_DEVICE}" | sed -e 's/^\/newroot\/dev\///' | grep -qE '^sr[0-9]*|^hd[a-z]|^pcd[0-9]|^xvd*' && echo "optical" || echo "harddisk"`
|
||
echo "${REAL_ROOT_TYPE}" > /newroot/run/pisilinux/livemedia
|
||
|
||
# this is needed for yali
|
||
MNTDIR=`grep \/mnt\/cdrom\ /proc/mounts|sed 's/\/newroot//g'`
|
||
echo "$MNTDIR" >> /newroot/etc/fstab
|
||
}
|
||
|
||
##############################
|
||
# Config and cmdline parsers #
|
||
##############################
|
||
|
||
# FIXME: maybe we should just source the file instead of parsing
|
||
# also consider merging conf parser and cmdline parser
|
||
parse_config() {
|
||
while read inputline;
|
||
do
|
||
case "${inputline}" in
|
||
raid=*)
|
||
RAID=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
lvm=*)
|
||
LVM=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
thin=*)
|
||
NFSROOT=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
root=*)
|
||
ROOT_TARGET=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
rootflags=*)
|
||
ROOT_FLAGS=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
liveroot=*)
|
||
# Installation or livecd, enable RAID by default
|
||
# to be able to read existing RAID installations
|
||
LIVE=1
|
||
RAID_INCREMENTAL=0
|
||
LIVEROOT=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
resume=*)
|
||
RESUME_DEVICE="${inputline#resume=}"
|
||
;;
|
||
noresume)
|
||
NORESUME=1
|
||
;;
|
||
copytoram)
|
||
COPYTORAM=1
|
||
;;
|
||
wipemem)
|
||
WIPEMEM=1
|
||
;;
|
||
wipememopts=*)
|
||
WIPEMEM=1
|
||
WIPEMEM_OPTS=$(echo $inputline|cut -f2- -d=)
|
||
;;
|
||
splash)
|
||
SPLASH=1
|
||
;;
|
||
init=*)
|
||
INIT="${inputline#INIT=}"
|
||
;;
|
||
esac
|
||
done < $INITRAMFSCONF
|
||
}
|
||
|
||
parse_cmdline() {
|
||
for x in `cat /proc/cmdline`; do
|
||
case "${x}" in
|
||
[0123456Ss])
|
||
# Normalize 'S' to 's'
|
||
LEVEL=`echo ${x}|tr A-Z a-z`
|
||
;;
|
||
mudur=*)
|
||
for m in `echo ${x}|cut -f2 -d=|sed 's/,/ /g'`; do
|
||
case "${m}" in
|
||
livecd)
|
||
LIVE=1
|
||
;;
|
||
livedisk)
|
||
LIVE=1
|
||
;;
|
||
raid)
|
||
RAID=1
|
||
;;
|
||
lvm)
|
||
LVM=1
|
||
;;
|
||
thin)
|
||
NFSROOT=1
|
||
;;
|
||
esac
|
||
done
|
||
;;
|
||
initramfs=*)
|
||
INITRAMFS=`echo ${x}|cut -f2- -d=`
|
||
;;
|
||
root=*)
|
||
ROOT_TARGET=`echo ${x}|cut -f2- -d=`
|
||
;;
|
||
rootflags=*)
|
||
ROOT_FLAGS="-o ${x#rootflags=}"
|
||
;;
|
||
liveroot=*)
|
||
LIVE=1
|
||
LIVEROOT=$(echo ${x}|cut -f2- -d=)
|
||
;;
|
||
resume=*)
|
||
RESUME_DEVICE="${x#resume=}"
|
||
;;
|
||
noresume)
|
||
NORESUME=1
|
||
;;
|
||
init=*)
|
||
INIT="${x#init=}"
|
||
;;
|
||
copytoram)
|
||
COPYTORAM=1
|
||
;;
|
||
wipemem)
|
||
WIPEMEM=1
|
||
;;
|
||
wipememopts=*)
|
||
WIPEMEM=1
|
||
WIPEMEM_OPTS=$(echo $x|cut -f2- -d=)
|
||
;;
|
||
splash)
|
||
SPLASH=1
|
||
;;
|
||
single)
|
||
LEVEL="s"
|
||
;;
|
||
quiet)
|
||
QUIET=1
|
||
;;
|
||
blacklist=*)
|
||
modules=${x#blacklist=}
|
||
for module in ${modules//,/ }; do
|
||
echo "blacklist $module" >> /etc/modprobe.d/cmdline.conf
|
||
done
|
||
;;
|
||
esac
|
||
done
|
||
|
||
if [ -f /etc/modprobe.d/cmdline.conf ]; then
|
||
cp /etc/modprobe.d/cmdline.conf /dev/.modprobe.initramfs.conf
|
||
fi
|
||
}
|
||
|
||
|
||
####################
|
||
# init starts here #
|
||
####################
|
||
|
||
info "Starting init on initramfs"
|
||
|
||
# Mount needed filesystems
|
||
mount -n -t proc proc /proc
|
||
mount -n -t sysfs sysfs /sys
|
||
# Added to start udev properly
|
||
#mkdir -m 0755 /run
|
||
#mount -t tmpfs tmpfs /run
|
||
|
||
# Prepare /dev (Needs kernel >= 2.6.32)
|
||
mount -t devtmpfs devtmpfs /dev
|
||
mkdir -m 0755 /dev/pts
|
||
mount -t devpts -o gid=5,mode=620 devpts /dev/pts
|
||
|
||
# First parse config file, then cmdline to allow overwriting internal config
|
||
if [ -f "$INITRAMFSCONF" ]
|
||
then
|
||
#. $INITRAMFSCONF
|
||
parse_config
|
||
fi
|
||
|
||
# Parse command line parameters
|
||
parse_cmdline
|
||
|
||
# Minimize printk log
|
||
test "x$QUIET" = "x1" && echo "1" > /proc/sys/kernel/printk
|
||
|
||
# Initialize plymouth daemon if found and splash is true
|
||
# Don't even launch plymouthd if we're in single-user mode
|
||
if [ "$LEVEL" != "s" -a "$SPLASH" = "1" -a -x /sbin/plymouthd ]; then
|
||
/sbin/plymouthd --attach-to-session
|
||
fi
|
||
|
||
# Handle initramfs= parameter
|
||
if [ "${INITRAMFS}" == "shellnoprobe" ]
|
||
then
|
||
fall2sh "Starting up a shell without probing"
|
||
elif [ "${INITRAMFS}" == "shell" ]
|
||
then
|
||
probe_devices --with-kms
|
||
fall2sh "Starting up a shell"
|
||
fi
|
||
|
||
if [ "${WIPEMEM}" = "1" ]
|
||
then
|
||
info "Wiping out memory, system will be shutdown after completion"
|
||
sdmem ${WIPEMEM_OPTS}
|
||
poweroff -f
|
||
fi
|
||
|
||
# Probe devices
|
||
probe_devices --with-kms
|
||
|
||
if [ -x /usr/sbin/resume -a -b "$RESUME_DEVICE" -a "x$NORESUME" != "x1" ]
|
||
then
|
||
if [ "x$SPLASH" == "x1" ]
|
||
then
|
||
SPLASHPARAM="-P splash=y"
|
||
else
|
||
SPLASHPARAM="-P splash=n"
|
||
fi
|
||
# FIXME: This will fail if resume= contains LABEL/UUID
|
||
info "Attempting to resume from hibernation"
|
||
/usr/sbin/resume $SPLASHPARAM $RESUME_DEVICE
|
||
fi
|
||
|
||
echo 0x0100 > /proc/sys/kernel/real-root-dev
|
||
|
||
if [ "${LIVE}" -eq "1" ]
|
||
then
|
||
ROOT_DEVICE=""
|
||
manage_tmpfs
|
||
|
||
# modprobe filesystems that are not in kernel, for live disks
|
||
modprobe -qa nls_cp857 nls_utf8 vfat
|
||
|
||
for i in `seq 50`
|
||
do
|
||
t=`findfs ${LIVEROOT} 2>/dev/null`
|
||
find_live_mount "$t"
|
||
|
||
if [ "${ROOT_DEVICE}" != "" ]
|
||
then
|
||
break
|
||
else
|
||
probe_devices
|
||
usleep 200000
|
||
fi
|
||
done
|
||
|
||
if [ "${ROOT_DEVICE}" == "" ]
|
||
then
|
||
fall2sh "Could not find mount media"
|
||
fi
|
||
|
||
mount_cdroot
|
||
|
||
elif [ "${NFSROOT}" -eq "1" ]
|
||
then
|
||
run_dhcpc
|
||
manage_tmpfs
|
||
mount_nfs
|
||
|
||
# set hostname for mudur
|
||
hostname $HOSTNAME
|
||
|
||
else
|
||
# Wait until ROOT_DEVICE appears
|
||
for i in `seq 50`
|
||
do
|
||
# let findfs handle all conversion
|
||
ROOT_DEVICE=`findfs ${ROOT_TARGET} 2>/dev/null`
|
||
|
||
if [ ! -b "${ROOT_DEVICE}" ]
|
||
then
|
||
probe_devices
|
||
usleep 200000
|
||
else
|
||
break
|
||
fi
|
||
done
|
||
if [ ! -b "${ROOT_DEVICE}" ]
|
||
then
|
||
fall2sh "Could not find boot device"
|
||
else
|
||
mount_rootfs
|
||
fi
|
||
fi
|
||
|
||
[ "${INIT}" == "" ] && INIT="/sbin/init";
|
||
|
||
# This stops /lib/udev/rules.d/65-md-incremental.rules from medling with mdraid sets.
|
||
[ "${RAID_INCREMENTAL}" -eq "0" ] && touch /dev/.in_sysinit
|
||
|
||
# Move mounts instead of umount/mount
|
||
mount --move /dev /newroot/dev
|
||
mount --move /proc /newroot/proc
|
||
mount --move /sys /newroot/sys
|
||
# Added to start udev properly
|
||
#mount --move /run /newroot/run
|
||
|
||
|
||
# And we start
|
||
info "Switching to the real root"
|
||
test -x /bin/plymouth && /bin/plymouth update-root-fs --new-root-dir=/newroot
|
||
exec /bin/switch_root -c /dev/console /newroot ${INIT} ${LEVEL}
|
||
|