2020-06-28 09:28:57 +05:30
|
|
|
#!/bin/sh
|
2020-01-30 20:10:13 +05:30
|
|
|
#
|
2021-05-10 17:05:34 +05:30
|
|
|
# Tiny init
|
2020-04-15 22:20:45 +05:30
|
|
|
#
|
2021-05-10 17:05:34 +05:30
|
|
|
# https://www.shellcheck.net/wiki/SC2154
|
2020-07-03 21:19:09 +05:30
|
|
|
# shellcheck disable=2154
|
2020-01-05 23:31:39 +05:30
|
|
|
|
2020-04-21 20:05:55 +05:30
|
|
|
print()
|
|
|
|
{
|
2020-05-07 17:36:34 +05:30
|
|
|
printf "%b %s\n" "${2:-"\033[1;37m>>\033[m"}" "$1"
|
2020-04-21 20:05:55 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
panic()
|
|
|
|
{
|
2020-05-07 17:36:34 +05:30
|
|
|
print "${1:-unexpected error occurred}" \
|
2021-05-11 15:36:58 +05:30
|
|
|
"\033[1;31m!!\033[m" >&2
|
2021-05-10 17:05:34 +05:30
|
|
|
|
|
|
|
sh
|
2021-05-11 15:36:58 +05:30
|
|
|
}
|
2020-01-28 20:43:42 +05:30
|
|
|
|
2020-06-02 16:56:42 +05:30
|
|
|
resolve_device()
|
2020-04-12 01:01:02 +05:30
|
|
|
{
|
2020-06-28 09:28:57 +05:30
|
|
|
count=0; device="$1"
|
2020-04-12 01:01:02 +05:30
|
|
|
|
2020-09-10 22:11:12 +05:30
|
|
|
case "${device%%=*}" in
|
2020-06-28 09:28:57 +05:30
|
|
|
UUID) device="/dev/disk/by-uuid/${device#*=}" ;;
|
|
|
|
LABEL) device="/dev/disk/by-label/${device#*=}" ;;
|
|
|
|
PARTUUID) device="/dev/disk/by-partuuid/${device#*=}" ;;
|
2020-09-10 22:11:12 +05:30
|
|
|
/dev/*) ;;
|
|
|
|
*) return 0 ;;
|
2020-04-12 01:01:02 +05:30
|
|
|
esac
|
|
|
|
|
2021-05-10 17:05:34 +05:30
|
|
|
# Race condition may occur if device manager is not yet initialized device.
|
|
|
|
# To fix this, we simply waiting until device is available. If device
|
|
|
|
# didn't appear in specified time, we panic.
|
2021-05-10 17:10:38 +05:30
|
|
|
while :; do
|
|
|
|
if [ -b "$device" ]; then
|
|
|
|
return 0
|
|
|
|
elif [ "$((count += 1))" = "${rootdelay:=30}" ]; then
|
2020-05-07 17:36:34 +05:30
|
|
|
break
|
2021-05-10 17:05:34 +05:30
|
|
|
else
|
|
|
|
sleep 1
|
|
|
|
fi
|
2021-05-10 17:10:38 +05:30
|
|
|
done
|
|
|
|
|
|
|
|
panic "failed to lookup partition"
|
2020-06-28 09:28:57 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
run_hook()
|
|
|
|
{
|
2020-09-11 01:23:39 +05:30
|
|
|
type="$1"
|
2020-06-28 09:28:57 +05:30
|
|
|
|
2021-05-10 17:05:34 +05:30
|
|
|
# Run hooks if any exist.
|
|
|
|
#
|
|
|
|
# https://www.shellcheck.net/wiki/SC1090
|
2020-07-03 21:19:09 +05:30
|
|
|
# shellcheck disable=1090
|
2020-06-28 09:28:57 +05:30
|
|
|
for hook in $hooks; do
|
2020-09-11 01:23:39 +05:30
|
|
|
[ -f "/usr/share/tinyramfs/hooks/${hook}/${hook}.${type}" ] || continue
|
|
|
|
. "/usr/share/tinyramfs/hooks/${hook}/${hook}.${type}"
|
2020-05-26 19:14:20 +05:30
|
|
|
done
|
2020-02-21 14:27:07 +05:30
|
|
|
}
|
2020-01-05 23:31:39 +05:30
|
|
|
|
2020-04-12 01:01:02 +05:30
|
|
|
prepare_environment()
|
|
|
|
{
|
2021-05-10 17:05:34 +05:30
|
|
|
# https://www.shellcheck.net/wiki/SC1091
|
2020-07-03 21:19:09 +05:30
|
|
|
# shellcheck disable=1091
|
2020-05-07 17:36:34 +05:30
|
|
|
. /etc/tinyramfs/config
|
2020-04-12 01:01:02 +05:30
|
|
|
|
|
|
|
export \
|
2020-05-19 09:59:40 +05:30
|
|
|
PATH=/bin TERM=linux SHELL=/bin/sh \
|
2020-06-28 09:28:57 +05:30
|
|
|
LANG=C LC_ALL=C PS1="# " HOME=/root
|
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-05-07 17:36:34 +05:30
|
|
|
mount -t tmpfs -o nosuid,nodev,mode=0755 run /run
|
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
|
|
|
|
2020-05-07 17:36:34 +05:30
|
|
|
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-12 01:01:02 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
parse_cmdline()
|
|
|
|
{
|
|
|
|
read -r cmdline < /proc/cmdline
|
|
|
|
|
2020-07-05 13:41:39 +05:30
|
|
|
for line in $cmdline; do case "$line" in
|
|
|
|
rootfstype=*) root_type="${line#*=}" ;;
|
|
|
|
rootflags=*) root_opts="${line#*=}" ;;
|
|
|
|
debug=1) set -x ;;
|
2021-05-11 15:34:02 +05:30
|
|
|
ro | rw) rorw="$line" ;;
|
2020-07-05 13:41:39 +05:30
|
|
|
--*) init_args="${cmdline#*-- }"; break ;;
|
|
|
|
*=*) command export "$line" ;;
|
|
|
|
*) command export "${line}=1" ;;
|
2020-06-28 09:28:57 +05:30
|
|
|
esac 2> /dev/null || :; 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
|
|
|
mount_root()
|
|
|
|
{
|
2020-05-19 09:59:40 +05:30
|
|
|
[ "$break" = root ] && { print "break before mount_root()"; sh; }
|
2020-04-12 01:01:02 +05:30
|
|
|
|
2020-06-02 16:56:42 +05:30
|
|
|
resolve_device "$root"
|
2020-04-12 01:01:02 +05:30
|
|
|
|
2021-05-10 17:05:34 +05:30
|
|
|
# https://www.shellcheck.net/wiki/SC2086
|
|
|
|
# shellcheck disable=2086
|
|
|
|
mount \
|
2021-05-11 15:34:02 +05:30
|
|
|
-o "${rorw:-ro}${root_opts:+,$root_opts}" ${root_type:+-t $root_type} \
|
2021-05-10 17:05:34 +05:30
|
|
|
-- "$device" /mnt/root || panic "failed to mount root"
|
2020-01-30 20:10:13 +05:30
|
|
|
}
|
2020-01-05 23:31:39 +05:30
|
|
|
|
2020-05-26 19:14:20 +05:30
|
|
|
boot_system()
|
2020-04-12 01:01:02 +05:30
|
|
|
{
|
2020-05-26 19:14:20 +05:30
|
|
|
[ "$break" = boot ] && { print "break before boot_system()"; sh; }
|
2020-04-12 01:01:02 +05:30
|
|
|
|
2020-05-19 09:59:40 +05:30
|
|
|
for dir in run dev sys proc; do
|
2020-07-26 09:01:20 +05:30
|
|
|
mount -o move "$dir" "/mnt/root/${dir}"
|
|
|
|
done
|
2020-01-05 23:31:39 +05:30
|
|
|
|
2021-05-10 17:05:34 +05:30
|
|
|
# POSIX 'exec' has no '-c' flag to execute command with empty environment.
|
|
|
|
# Using 'env -i' instead to prevent leaking exported variables.
|
|
|
|
#
|
|
|
|
# Some implementations of 'switch_root' doesn't conform to POSIX utility
|
|
|
|
# guidelines and doesn't support '--'. This means that we can't guarantee
|
|
|
|
# safety of init_args.
|
|
|
|
# shellcheck disable=2086
|
|
|
|
exec \
|
|
|
|
env -i TERM=linux PATH=/bin:/sbin:/usr/bin:/usr/sbin \
|
|
|
|
switch_root /mnt/root "${init-/sbin/init}" $init_args ||
|
|
|
|
panic "failed to boot system"
|
2020-04-12 01:01:02 +05:30
|
|
|
}
|
2020-01-30 20:58:03 +05:30
|
|
|
|
2021-05-10 17:05:34 +05:30
|
|
|
# Exit if command fails and disable globbing.
|
|
|
|
set -ef
|
|
|
|
|
|
|
|
# Run emergency shell if init unexpectedly exiting due to error.
|
|
|
|
trap panic EXIT
|
|
|
|
|
|
|
|
# TODO display fancy colored status info
|
2020-09-11 01:23:39 +05:30
|
|
|
|
|
|
|
prepare_environment
|
|
|
|
parse_cmdline
|
|
|
|
run_hook init
|
|
|
|
mount_root
|
|
|
|
run_hook init.late
|
|
|
|
boot_system
|