tinyramfs/init

267 lines
5.6 KiB
Plaintext
Raw Normal View History

2020-04-12 01:01:02 +05:30
#!/bin/sh -ef
2020-01-30 20:10:13 +05:30
#
2020-04-12 01:01:02 +05:30
# tiny init
#
# word splitting is safe by design
# shellcheck disable=2068,2046,2086
#
# false positive
# shellcheck disable=2154,2163,1091
2020-01-05 23:31:39 +05:30
2020-04-21 20:05:55 +05:30
print()
{
printf "%b %s\n" "${2:-\033[1;37m>>\033[m}" "$1"
shell
}
panic()
{
print "$1" "\033[1;31m!!\033[m" >&2
shell
}
2020-02-24 13:49:38 +05:30
shell()
{
2020-04-12 01:01:02 +05:30
# see https://busybox.net/FAQ.html#job_control
2020-04-18 20:42:24 +05:30
setsid sh -c "exec sh <> /dev/${console:-tty1} 2>&1" || sh
2020-01-30 20:10:13 +05:30
}
2020-01-28 20:43:42 +05:30
2020-04-12 01:01:02 +05:30
findfs()
{
value=0; device=
case "${1%%=*}" in
/dev/*)
device="$1"
;;
UUID)
device="/dev/disk/by-uuid/${1##*=}"
;;
LABEL)
device="/dev/disk/by-label/${1##*=}"
;;
PARTUUID)
device="/dev/disk/by-partuuid/${1##*=}"
;;
esac
# avoid race condition
while [ ! -e "$device" ]; do
2020-04-21 20:05:55 +05:30
[ "$value" = 30 ] && panic "failed to lookup partition"
value=$(( value + 1 )); sleep 1
2020-02-21 14:27:07 +05:30
done
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
prepare_environment()
{
. /etc/config
export \
SHELL=/bin/sh \
TERM=linux \
HOME=/root \
PATH=/bin:/sbin:/usr/bin:/usr/sbin \
PS1="# " \
LC_ALL=C \
LANG=C \
OLD_IFS="$IFS"
2020-03-08 08:59:14 +05:30
2020-04-12 01:01:02 +05:30
# fix for ubase mount
:> /etc/fstab
2020-03-08 08:59:14 +05:30
mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sys /sys
2020-04-12 01:01:02 +05:30
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
2020-03-08 08:59:14 +05:30
ln -s /proc/self/fd /dev/fd
ln -s /proc/self/fd/0 /dev/stdin
ln -s /proc/self/fd/1 /dev/stdout
ln -s /proc/self/fd/2 /dev/stderr
2020-04-12 01:01:02 +05:30
trap 'panic "something went wrong"' EXIT
2020-04-17 23:11:54 +05:30
2020-04-18 21:15:24 +05:30
# false positive
# shellcheck disable=2015
2020-04-18 20:42:24 +05:30
[ "$modules" ] && modprobe -a "$modules" 2> /dev/null ||:
2020-04-12 01:01:02 +05:30
}
parse_cmdline()
{
read -r cmdline < /proc/cmdline
for line in $cmdline; do case "$line" in
debug | debug=1)
set -x
;;
2020-04-21 20:05:55 +05:30
rootfstype=*)
root_type="$line"
;;
rootflags=*)
root_opts="$line"
;;
ro | rw)
rorw="-o $line"
;;
*.*)
# TODO implement backward compatibilty with dracut, mkinitcpio, etc
: no operation
;;
*=*)
export "$line"
;;
*)
export "${line}=1"
;;
esac; done
2020-01-30 20:10:13 +05:30
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
setup_devmgr()
{
2020-04-21 20:05:55 +05:30
[ "$break" = devmgr ] && print "break before setup device manager"
2020-04-12 01:01:02 +05:30
2020-02-26 01:13:25 +05:30
case "$devmgr" in
udev)
2020-03-08 04:44:59 +05:30
udevd -d -N never
2020-02-26 01:13:25 +05:30
udevadm trigger -c add -t subsystems
udevadm trigger -c add -t devices
udevadm settle
2020-04-12 01:01:02 +05:30
;;
2020-02-26 01:13:25 +05:30
mdev)
2020-04-12 01:01:02 +05:30
mdev -df 2> /dev/null & mdev_pid="$!"
[ "$monolith" != 1 ] && {
2020-04-12 01:01:02 +05:30
set -- $(find /sys -name modalias -type f -exec sort -u {} +)
2020-04-18 20:42:24 +05:30
modprobe -a "$@" 2> /dev/null ||:
2020-04-12 01:01:02 +05:30
}
;;
2020-02-26 01:13:25 +05:30
mdevd)
2020-04-12 01:01:02 +05:30
mdevd 2> /dev/null & mdevd_pid="$!"
2020-02-26 01:13:25 +05:30
mdevd-coldplug
2020-04-12 01:01:02 +05:30
;;
2020-02-26 01:13:25 +05:30
esac
2020-01-30 20:10:13 +05:30
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
unlock_luks()
{
2020-04-21 20:05:55 +05:30
[ "$break" = luks ] && print "break before unlock LUKS"
2020-02-26 01:13:25 +05:30
2020-04-12 01:01:02 +05:30
{ IFS=,; set -- $luks_opts; IFS="$OLD_IFS"; }
2020-02-16 01:03:13 +05:30
for opt; do case "$opt" in
discard | discard=1)
luks_discard="--allow-discards"
;;
header=*)
luks_header="--${opt}"
;;
name=*)
luks_name="${opt##*=}"
;;
key=*)
luks_key="-d ${opt##*=}"
;;
esac; done
2020-02-16 01:03:13 +05:30
2020-04-12 01:01:02 +05:30
findfs "$luks_root"
set -- \
"--disable-locks" \
2020-04-17 23:11:54 +05:30
"$luks_key" "$luks_header" \
"$luks_discard" "$device" \
"${luks_name:-luks-${device##*/}}"
2020-04-12 01:01:02 +05:30
cryptsetup open $@ || panic "failed to unlock LUKS"
}
2020-04-12 01:01:02 +05:30
trigger_lvm()
{
2020-04-21 20:05:55 +05:30
[ "$break" = lvm ] && print "break before trigger LVM"
2020-04-12 01:01:02 +05:30
{ IFS=,; set -- $lvm_opts; IFS="$OLD_IFS"; }
for opt; do case "$opt" in
discard | discard=1)
lvm_discard="--config=devices{issue_discards=1}"
;;
config=0)
:> /etc/lvm/lvm.conf
;;
group=*)
lvm_group="${opt##*=}"
;;
name=*)
lvm_name="/${opt##*=}"
;;
tag=*)
lvm_tag="@${opt##*=}"
;;
esac; done
2020-04-12 01:01:02 +05:30
set -- "--sysinit" "-qq" "-ay" "$lvm_discard"
2020-01-25 16:57:02 +05:30
2020-02-21 14:27:07 +05:30
if [ "$lvm_group" ] && [ "$lvm_name" ]; then
2020-04-12 01:01:02 +05:30
lvchange $@ "${lvm_group}${lvm_name}"
2020-02-21 14:27:07 +05:30
elif [ "$lvm_group" ]; then
2020-04-12 01:01:02 +05:30
vgchange $@ "$lvm_group"
elif [ "$lvm_tag" ]; then
lvchange $@ "$lvm_tag"
2020-02-21 14:27:07 +05:30
else
2020-04-12 01:01:02 +05:30
vgchange $@
2020-02-21 14:27:07 +05:30
fi
2020-01-28 20:43:42 +05:30
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
mount_root()
{
2020-04-21 20:05:55 +05:30
[ "$break" = root ] && print "break before mount root"
2020-04-12 01:01:02 +05:30
findfs "$root"
set -- \
"${root_type:+-t $root_type}" \
"${rorw:--o ro}${root_opts:+,$root_opts}" \
"$device" "/mnt/root"
2020-04-12 01:01:02 +05:30
mount $@ || panic "failed to mount root"
2020-01-30 20:10:13 +05:30
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
cleanup()
{
2020-04-21 20:05:55 +05:30
[ "$break" = cleanup ] && print "break before cleanup"
2020-04-12 01:01:02 +05:30
case "$devmgr" in
2020-02-26 01:13:25 +05:30
udev) udevadm control -e ;;
2020-04-12 01:01:02 +05:30
mdev) kill "$mdev_pid" ;;
mdevd) kill "$mdevd_pid" ;;
esac
# temporary workaround until util-linux release a new version
2020-04-12 01:01:02 +05:30
# see https://github.com/karelzak/util-linux/issues/997
for dir in dev sys proc; do
mount -o move "$dir" "/mnt/root/${dir}" || mount --move "$dir" "/mnt/root/${dir}"
done
2020-01-30 20:10:13 +05:30
}
2020-01-05 23:31:39 +05:30
2020-04-12 01:01:02 +05:30
boot_system()
{
2020-04-21 20:05:55 +05:30
[ "$break" = boot ] && print "break before boot system"
2020-01-30 20:10:13 +05:30
2020-04-12 01:01:02 +05:30
set -- "/mnt/root" "${init:-/sbin/init}"
exec switch_root $@ 2> /dev/null || panic "failed to boot system"
}
2020-01-30 20:58:03 +05:30
2020-04-12 01:01:02 +05:30
# int main()
{
prepare_environment
parse_cmdline
setup_devmgr
2020-02-26 01:13:25 +05:30
# trigger lvm twice to handle both LUKS on LVM and LVM on LUKS
[ "$lvm" = 1 ] && trigger_lvm
2020-04-12 01:01:02 +05:30
[ "$luks" = 1 ] && unlock_luks
[ "$lvm" = 1 ] && trigger_lvm
2020-02-26 01:13:25 +05:30
2020-04-12 01:01:02 +05:30
mount_root
cleanup
boot_system
}