mirror of
git://slackware.nl/current.git
synced 2025-01-15 15:41:54 +01:00
231 lines
7.6 KiB
Text
231 lines
7.6 KiB
Text
|
#!/bin/ash
|
||
|
#
|
||
|
# /init: init script to load kernel modules from an initramfs
|
||
|
# This requires that your kernel supports initramfs!!!
|
||
|
#
|
||
|
# Copyright 2004 Slackware Linux, Inc., Concord, CA, USA
|
||
|
# Copyright 2007, 2008 Patrick J. Volkerding, Sebeka, MN, USA
|
||
|
# All rights reserved.
|
||
|
#
|
||
|
# Redistribution and use of this script, with or without modification, is
|
||
|
# permitted provided that the following conditions are met:
|
||
|
#
|
||
|
# 1. Redistributions of this script must retain the above copyright
|
||
|
# notice, this list of conditions and the following disclaimer.
|
||
|
#
|
||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||
|
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||
|
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||
|
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
|
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
|
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||
|
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
|
||
|
|
||
|
# With a generic kernel, you need to load the modules needed to mount the
|
||
|
# root partition. This might mean a SCSI, RAID, or other drive controller
|
||
|
# module, as well as the module to support the root filesystem. Once the
|
||
|
# root partition is mounted all the other modules will be available so you
|
||
|
# don't need to load them here.
|
||
|
#
|
||
|
# Config files used by this script:
|
||
|
#
|
||
|
# /rootdev Contains the name of the root device, such as: /dev/hda1
|
||
|
#
|
||
|
# /rootfs Contains the root filesystem type, such as: xfs
|
||
|
#
|
||
|
# /initrd-name Contains the name of the initrd file.
|
||
|
#
|
||
|
# Optional:
|
||
|
# /load_kernel_modules A script that uses insmod to load the desired
|
||
|
# modules. If this file is not present, all the modules
|
||
|
# in /lib/modules/`uname -r`/ will be loaded in the usual
|
||
|
# sorted order. If you need to load the modules in a
|
||
|
# certain order, or if the modules need extra options,
|
||
|
# then use a load_kernel_modules script.
|
||
|
#
|
||
|
# There's an example in here. To actually use it, you'll
|
||
|
# need to make it executable:
|
||
|
#
|
||
|
# chmod 755 load_kernel_modules
|
||
|
|
||
|
INITRD=`cat /initrd-name`
|
||
|
ROOTDEV=`cat /rootdev`
|
||
|
ROOTFS=`cat /rootfs`
|
||
|
LUKSDEV=`cat /luksdev`
|
||
|
RESUMEDEV=`cat /resumedev`
|
||
|
WAIT=`cat /wait-for-root`
|
||
|
KEYMAP=`cat /keymap`
|
||
|
|
||
|
# Mount /proc and /sys:
|
||
|
mount -n proc /proc -t proc
|
||
|
mount -n sysfs /sys -t sysfs
|
||
|
|
||
|
# Parse command line
|
||
|
for ARG in `cat /proc/cmdline`; do
|
||
|
case $ARG in
|
||
|
rescue)
|
||
|
RESCUE=1
|
||
|
;;
|
||
|
root=/dev/*)
|
||
|
ROOTDEV=`echo $ARG | cut -f2 -d=`
|
||
|
;;
|
||
|
rootfs=*)
|
||
|
ROOTFS=`echo $ARG | cut -f2 -d=`
|
||
|
;;
|
||
|
luksdev=/dev/*)
|
||
|
LUKSDEV=`echo $ARG | cut -f2 -d=`
|
||
|
;;
|
||
|
waitforroot=*)
|
||
|
WAIT=`echo $ARG | cut -f2 -d=`
|
||
|
;;
|
||
|
root=LABEL=*)
|
||
|
ROOTDEV=`echo $ARG | cut -f2- -d=`
|
||
|
;;
|
||
|
resume=*)
|
||
|
RESUMEDEV=`echo $ARG | cut -f2 -d=`
|
||
|
;;
|
||
|
0|1|2|3|4|5|6)
|
||
|
RUNLEVEL=$ARG
|
||
|
;;
|
||
|
esac
|
||
|
done
|
||
|
|
||
|
# Load kernel modules:
|
||
|
if [ ! -d /lib/modules/`uname -r` ]; then
|
||
|
echo "No kernel modules found for Linux `uname -r`."
|
||
|
elif [ -x ./load_kernel_modules ]; then # use load_kernel_modules script:
|
||
|
echo "${INITRD}: Loading kernel modules from initrd image:"
|
||
|
. ./load_kernel_modules
|
||
|
else # load modules (if any) in order:
|
||
|
if ls /lib/modules/`uname -r`/*.*o 1> /dev/null 2> /dev/null ; then
|
||
|
echo "${INITRD}: Loading kernel modules from initrd image:"
|
||
|
for module in /lib/modules/`uname -r`/*.*o ; do
|
||
|
insmod $module
|
||
|
done
|
||
|
unset module
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# Sometimes the devices needs extra time to be available.
|
||
|
# root on USB are good example of that.
|
||
|
sleep $WAIT
|
||
|
|
||
|
# If udevd is available, use it to generate block devices
|
||
|
# else use mdev to read sysfs and generate the needed devices
|
||
|
if [ -x /sbin/udevd -a -x /sbin/udevadm ]; then
|
||
|
/sbin/udevd --daemon
|
||
|
/sbin/udevadm trigger --subsystem-match=block
|
||
|
/sbin/udevadm settle --timeout=10
|
||
|
else
|
||
|
mdev -s
|
||
|
fi
|
||
|
|
||
|
# Load a custom keyboard mapping:
|
||
|
if [ -n "$KEYMAP" ]; then
|
||
|
echo "${INITRD}: Loading '$KEYMAP' keyboard mapping:"
|
||
|
tar xzOf /etc/keymaps.tar.gz ${KEYMAP}.bmap | loadkmap
|
||
|
fi
|
||
|
|
||
|
if [ "$RESCUE" = "" ]; then
|
||
|
# Initialize RAID:
|
||
|
if [ -x /sbin/mdadm ]; then
|
||
|
/sbin/mdadm -E -s >/etc/mdadm.conf
|
||
|
/sbin/mdadm -A -s
|
||
|
fi
|
||
|
|
||
|
# Find root device if a label was given:
|
||
|
if echo $ROOTDEV | grep -q "LABEL=" ; then
|
||
|
ROOTDEV=`findfs $ROOTDEV`
|
||
|
fi
|
||
|
|
||
|
# Make encrypted root partition available:
|
||
|
# The useable device will be under /dev/mapper/
|
||
|
# Three scenarios for the commandline exist:
|
||
|
# 1- ROOTDEV is on a LUKS volume, and LUKSDEV is a real block device
|
||
|
# 2- ROOTDEV is on a LVM volume, and LUKSDEV is a real block device
|
||
|
# 3- ROOTDEV is on a LUKS volume, and LUKSDEV is on a LVM volume
|
||
|
# Case (3) will have to wait until we initialize the LVM.
|
||
|
# Test if ROOTDEV is "/dev/someting" or just "something" - the first means
|
||
|
# ROOTDEV is on a LVM volume (scenario 2); we don't need to rewrite ROOTDEV.
|
||
|
# The second means that ROOTDEV is on a LUKS volume (scenario 1).
|
||
|
CRYPTDEV=""
|
||
|
if [ -x /sbin/cryptsetup ]; then
|
||
|
# If we find a LUKS device now, it is on a real block device:
|
||
|
if /sbin/cryptsetup isLuks ${LUKSDEV} 1>/dev/null 2>/dev/null ; then
|
||
|
CRYPTDEV=$(basename $ROOTDEV)
|
||
|
echo "Unlocking LUKS crypt volume '${CRYPTDEV}' on device '$LUKSDEV':"
|
||
|
/sbin/cryptsetup luksOpen ${LUKSDEV} $CRYPTDEV </dev/systty >/dev/systty 2>&1
|
||
|
if [ "$CRYPTDEV" == "$ROOTDEV" ]; then # scenario 1
|
||
|
ROOTDEV="/dev/mapper/${CRYPTDEV}"
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# Initialize LVM:
|
||
|
if [ -x /sbin/vgscan ]; then
|
||
|
/sbin/vgscan --mknodes --ignorelockingfailure
|
||
|
sleep 10
|
||
|
/sbin/vgchange -ay --ignorelockingfailure
|
||
|
fi
|
||
|
|
||
|
# Make encrypted root partition available (scenario 3):
|
||
|
# We have to handle cases here where the LUKS volume is created on a LV
|
||
|
if [ -x /sbin/cryptsetup ]; then
|
||
|
if /sbin/cryptsetup isLuks ${LUKSDEV} 1>/dev/null 2>/dev/null ; then
|
||
|
# Only act if we could not open the LUKS device before (i.e. is on a LV):
|
||
|
if [ "x$CRYPTDEV" == "x" ]; then
|
||
|
echo "Unlocking LUKS crypt volume '${ROOTDEV}' on device '$LUKSDEV':"
|
||
|
/sbin/cryptsetup luksOpen ${LUKSDEV} $ROOTDEV </dev/systty >/dev/systty 2>&1
|
||
|
ROOTDEV="/dev/mapper/${ROOTDEV}"
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# Resume state from swap
|
||
|
if [ "$RESUMEDEV" != "" ]; then
|
||
|
if ls -l $RESUMEDEV | grep -q "^l" ; then
|
||
|
RESUMEDEV=`ls -l $RESUMEDEV | awk '{ print $NF }'`
|
||
|
fi
|
||
|
echo "Trying to resume from $RESUMEDEV"
|
||
|
RESMAJMIN=`ls -l $RESUMEDEV | tr , : | awk '{ print $5$6 }'`
|
||
|
echo $RESMAJMIN > /sys/power/resume
|
||
|
fi
|
||
|
|
||
|
# Switch to real root partition:
|
||
|
echo 0x0100 > /proc/sys/kernel/real-root-dev
|
||
|
mount -o ro -t $ROOTFS $ROOTDEV /mnt
|
||
|
|
||
|
if [ ! -r /mnt/sbin/init ]; then
|
||
|
echo "ERROR: No /sbin/init found on rootdev (or not mounted). Trouble ahead."
|
||
|
echo " You can try to fix it. Type 'exit' when things are done."
|
||
|
echo
|
||
|
/bin/sh
|
||
|
fi
|
||
|
else
|
||
|
echo "RESCUE mode"
|
||
|
echo
|
||
|
echo " You can try to fix or rescue your system now. If you want"
|
||
|
echo " to boot into your fixed system, mount your root filesystem"
|
||
|
echo " read-only under /mnt:"
|
||
|
echo
|
||
|
echo " # mount -o ro -t filesystem root_device /mnt"
|
||
|
echo
|
||
|
echo " Type 'exit' when things are done."
|
||
|
echo
|
||
|
/bin/sh
|
||
|
fi
|
||
|
|
||
|
if ps axc | grep -q udevd ; then
|
||
|
killall udevd
|
||
|
fi
|
||
|
|
||
|
unset ERR
|
||
|
umount /proc
|
||
|
umount /sys
|
||
|
echo "${INITRD}: exiting"
|
||
|
exec switch_root /mnt /sbin/init $RUNLEVEL
|