tinyramfs/init

135 lines
3.3 KiB
Plaintext
Raw Normal View History

#!/bin/sh
2020-01-30 17:40:13 +03:00
#
2020-04-11 22:31:02 +03:00
# tiny init
#
2020-07-03 18:49:09 +03:00
# false positive
# shellcheck disable=2154
2020-01-05 21:01:39 +03:00
2020-04-21 17:35:55 +03:00
print()
{
printf "%b %s\n" "${2:-"\033[1;37m>>\033[m"}" "$1"
2020-04-21 17:35:55 +03:00
}
panic()
{
print "${1:-unexpected error occurred}" \
"\033[1;31m!!\033[m" >&2; sh
2020-01-30 17:40:13 +03:00
}
2020-01-28 18:13:42 +03:00
2020-06-02 14:26:42 +03:00
resolve_device()
2020-04-11 22:31:02 +03:00
{
count=0; device="$1"
2020-04-11 22:31:02 +03:00
case "${device%%=*}" in /dev/*) ;;
UUID) device="/dev/disk/by-uuid/${device#*=}" ;;
LABEL) device="/dev/disk/by-label/${device#*=}" ;;
PARTUUID) device="/dev/disk/by-partuuid/${device#*=}" ;;
2020-04-11 22:31:02 +03:00
esac
# prevent race condition
# XXX what the hell happens here?
# why this loop sometimes trigger panic if i remove '|| :'
2020-06-02 14:26:42 +03:00
while [ ! -b "$device" ]; do sleep 1
[ "$((count += 1))" = 30 ] && {
panic "failed to lookup partition"
break
}
done || :
}
run_hook()
{
type="$1"; hksdir=/usr/share/tinyramfs/hooks
# run hooks if any
2020-07-03 18:49:09 +03:00
# false positive
# shellcheck disable=1090
for hook in $hooks; do
[ -f "${hksdir}/${hook}/${hook}.${type}" ] || continue
. "${hksdir}/${hook}/${hook}.${type}"
2020-05-26 16:44:20 +03:00
done
2020-02-21 11:57:07 +03:00
}
2020-01-05 21:01:39 +03:00
2020-04-11 22:31:02 +03:00
prepare_environment()
{
2020-07-03 18:49:09 +03:00
# false positive
# shellcheck disable=1091
. /etc/tinyramfs/config
2020-04-11 22:31:02 +03:00
export \
PATH=/bin TERM=linux SHELL=/bin/sh \
LANG=C LC_ALL=C PS1="# " HOME=/root
2020-03-08 06:29:14 +03:00
mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sys /sys
mount -t tmpfs -o nosuid,nodev,mode=0755 run /run
2020-04-11 22:31:02 +03:00
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
2020-03-08 06:29:14 +03:00
ln -s /proc/self/fd /dev/fd
ln -s fd/0 /dev/stdin
ln -s fd/1 /dev/stdout
ln -s fd/2 /dev/stderr
2020-04-11 22:31:02 +03:00
}
parse_cmdline()
{
read -r cmdline < /proc/cmdline
2020-07-05 11:11:39 +03:00
for line in $cmdline; do case "$line" in
rootfstype=*) root_type="${line#*=}" ;;
rootflags=*) root_opts="${line#*=}" ;;
debug=1) set -x ;;
ro | rw) rorw="-o $line" ;;
--*) init_args="${cmdline#*-- }"; break ;;
*=*) command export "$line" ;;
*) command export "${line}=1" ;;
esac 2> /dev/null || :; done
2020-01-30 17:40:13 +03:00
}
2020-01-05 21:01:39 +03:00
2020-04-11 22:31:02 +03:00
mount_root()
{
[ "$break" = root ] && { print "break before mount_root()"; sh; }
2020-04-11 22:31:02 +03:00
2020-06-02 14:26:42 +03:00
resolve_device "$root"
2020-04-11 22:31:02 +03:00
set -- \
"${rorw:--o ro}${root_opts:+,$root_opts}" \
2020-05-26 16:44:20 +03:00
"${root_type:+-t $root_type}" "$device" "/mnt/root"
2020-07-03 18:49:09 +03:00
# word splitting is safe by design
# shellcheck disable=2068
2020-04-11 22:31:02 +03:00
mount $@ || panic "failed to mount root"
2020-01-30 17:40:13 +03:00
}
2020-01-05 21:01:39 +03:00
2020-05-26 16:44:20 +03:00
boot_system()
2020-04-11 22:31:02 +03:00
{
2020-05-26 16:44:20 +03:00
[ "$break" = boot ] && { print "break before boot_system()"; sh; }
2020-04-11 22:31:02 +03:00
for dir in run dev sys proc; do
2020-07-26 06:31:20 +03:00
mount -o move "$dir" "/mnt/root/${dir}"
done
2020-01-05 21:01:39 +03:00
2020-06-02 14:26:42 +03:00
set -- "/mnt/root" "${init:-/sbin/init}" "$init_args"
2020-01-30 17:40:13 +03:00
# POSIX exec has no -c flag to execute command with empty environment
2020-06-02 14:26:42 +03:00
# use 'env -i' to prevent leaking exported variables
2020-07-03 18:49:09 +03:00
# word splitting is safe by design
# shellcheck disable=2068
2020-07-15 21:50:47 +03:00
exec env -i TERM=linux PATH=/bin:/sbin:/usr/bin:/usr/sbin \
2020-06-02 14:26:42 +03:00
switch_root $@ || panic "failed to boot system"
2020-04-11 22:31:02 +03:00
}
2020-01-30 18:28:03 +03:00
2020-04-11 22:31:02 +03:00
# int main()
{
# enable exit on error and disable globbing
# trap EXIT signal
set -ef; trap panic EXIT
2020-04-11 22:31:02 +03:00
prepare_environment
parse_cmdline
run_hook init
2020-04-11 22:31:02 +03:00
mount_root
2020-07-27 11:32:22 +03:00
run_hook init.late
2020-04-11 22:31:02 +03:00
boot_system
}