This commit is contained in:
illiliti
2020-04-11 22:31:02 +03:00
parent de8603e784
commit b9137bf486
11 changed files with 789 additions and 1004 deletions

282
usr/share/tinyramfs/init Normal file → Executable file
View File

@@ -1,168 +1,236 @@
#!/sbin/busybox sh
#!/bin/sh -ef
#
# tiny init script
# tiny init
panic() {
panic()
{
printf "panic >> %s\n" "$1"
# TODO fix job control
sh
# see https://busybox.net/FAQ.html#job_control
setsid sh -c "exec sh <> /dev/${console:-console} 2>&1" || sh
}
parse_cmdline() {
read -r cmdline < /proc/cmdline
set -f && set +f -- $cmdline
findfs()
{
value=0; device=
for line in "$@"; do
value="${line##*=}"
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
case "${line%%=*}" in
debug) debug="$value" ;;
init) init="$value" ;;
root) root="$value" ;;
root.type) root_type="$value" ;;
root.opts) root_opts="$value" ;;
lvm) lvm="$value" ;;
lvm.name) lvm_name="$value" ;;
lvm.group) lvm_group="$value" ;;
lvm.args) lvm_args="$value" ;;
luks) luks="$value" ;;
luks.root) luks_root="$value" ;;
luks.name) luks_name="$value" ;;
luks.discard) luks_discard="$value" ;;
luks.args) luks_args="$value" ;;
# TODO implement
#lvm.discard) ;;
#lvm.config) ;;
#luks.header) ;;
#luks.keyfile) ;;
esac
# avoid race condition
while [ ! -e "$device" ]; do
value=$(( value + 1 ))
[ "$value" = 15 ] && panic "failed to lookup partition"
sleep 1
done
}
prepare_environment() {
/sbin/busybox --install -s
prepare_environment()
{
. /etc/config
. /config || panic "failed to source 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"
# fix for ubase mount
:> /etc/fstab
mount -t proc -o nosuid,noexec,nodev proc /proc
mount -t sysfs -o nosuid,noexec,nodev sys /sys
mount -t tmpfs -o mode=0755,nosuid,nodev run /run
mount -t devtmpfs -o mode=0755,noexec,nosuid dev /dev
mkdir -pm 0755 /run/cryptsetup /run/lvm /dev/pts /dev/shm
mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts
mount -t tmpfs -o mode=1777,noexec,nosuid,nodev shm /dev/shm
mount -t devtmpfs -o nosuid,noexec,mode=0755 dev /dev
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
trap 'panic "something went wrong"' EXIT
}
setup_devmgr() {
parse_cmdline()
{
[ "$break" = cmdline ] && panic "break before parse cmdline"
read -r cmdline < /proc/cmdline
for line in $cmdline; do
case "$line" in
debug | debug=1)
set -x
;;
*.*)
# TODO implement backward compatibilty with dracut, mkinitcpio, etc
: no operation
;;
*=*)
export "$line"
;;
*)
export "${line}=1"
;;
esac
done
}
setup_devmgr()
{
[ "$break" = devmgr ] && panic "break before setup device manager"
case "$devmgr" in
udev)
udevd -d -N never
udevadm trigger -c add -t subsystems
udevadm trigger -c add -t devices
udevadm settle
;;
;;
mdev)
mdev -df &
mdev -df 2> /dev/null & mdev_pid="$!"
find /sys -name modalias -type f -exec sort -u {} + |
xargs modprobe -ba
;;
[ "$monolith" != 1 ] &&
{
set -- $(find /sys -name modalias -type f -exec sort -u {} +)
modprobe -a "$@" 2> /dev/null
}
;;
mdevd)
mdevd &
mdevd 2> /dev/null & mdevd_pid="$!"
mdevd-coldplug
;;
;;
esac
}
findfs_sh() {
value="${1##*=}"
unlock_luks()
{
[ "$break" = luks ] && panic "break before unlock LUKS"
case "${1%%=*}" in
LABEL) device="/dev/disk/by-label/${value}" ;;
UUID) device="/dev/disk/by-uuid/${value}" ;;
PARTUUID) device="/dev/disk/by-partuuid/${value}" ;;
/dev/*) device="$1" ;;
esac
{ IFS=,; set -- $luks_opts; IFS="$OLD_IFS"; }
# avoid race condition
while [ ! -e "$device" ]; do
sleep 0.5
[ "$increment" ] || increment=0
increment=$(( increment + 1 ))
[ "$increment" = 10 ] && panic "failed to lookup partition"
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
printf "%s\n" "$device"
findfs "$luks_root"
set -- "--disable-locks" "$luks_key" "$luks_discard" "$luks_header" "$device" "${luks_name:-luks-${device##*/}}"
cryptsetup open $@ || panic "failed to unlock LUKS"
}
unlock_luks() {
[ "$luks_discard" = 1 ] && luks_args="--allow-discards $luks_args"
[ -f /root/luks_header ] && luks_args="--header=/root/luks_header $luks_args"
[ -f /root/luks_keyfile ] && luks_args="--key-file=/root/luks_keyfile $luks_args"
trigger_lvm()
{
[ "$break" = lvm ] && panic "break before trigger LVM"
cryptsetup $luks_args \
luksOpen \
$(findfs_sh "$luks_root") \
${luks_name:-luks_root} ||
panic "failed to unlock luks container"
}
{ 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
set -- "--sysinit" "-qq" "-ay" "$lvm_discard"
trigger_lvm() {
if [ "$lvm_group" ] && [ "$lvm_name" ]; then
lvm lvchange $lvm_args --sysinit -q -a y "${lvm_group}/${lvm_name}" > /dev/null
lvchange $@ "${lvm_group}${lvm_name}"
elif [ "$lvm_group" ]; then
lvm vgchange $lvm_args --sysinit -q -a y "$lvm_group" > /dev/null
vgchange $@ "$lvm_group"
elif [ "$lvm_tag" ]; then
lvchange $@ "$lvm_tag"
else
lvm vgchange $lvm_args --sysinit -q -a y > /dev/null
vgchange $@
fi
}
mount_rootfs() {
mount ${root_type:+-t $root_type} \
${root_opts:+-o $root_opts} \
$(findfs_sh "$root") \
/mnt/root ||
panic "failed to mount rootfs"
mount_root()
{
[ "$break" = root ] && panic "break before mount root"
findfs "$root"
set -- "${root_type:+-t $root_type}" "${root_opts:+-o $root_opts}" "$device" "/mnt/root"
mount $@ || panic "failed to mount root"
}
cleanup() {
cleanup()
{
[ "$break" = cleanup ] && panic "break before cleanup"
case "$devmgr" in
udev) udevadm control -e ;;
mdev) killall mdev ;;
mdevd) killall mdevd ;;
mdev) kill "$mdev_pid" ;;
mdevd) kill "$mdevd_pid" ;;
esac
umount /dev /sys /proc
# temporary workaround until util-linux mount implements 'mount -o move'
# 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
}
boot_system() {
exec switch_root \
/mnt/root \
${init:-/sbin/init} ||
panic "failed to boot system"
boot_system()
{
[ "$break" = boot ] && panic "break before boot system"
set -- "/mnt/root" "${init:-/sbin/init}"
exec switch_root $@ 2> /dev/null || panic "failed to boot system"
}
prepare_environment
parse_cmdline
[ "$debug" = 1 ] && set -x
setup_devmgr
# int main()
{
prepare_environment
parse_cmdline
setup_devmgr
# TODO handle situations when LUKS on LVM
[ "$luks" = 1 ] &&
command -v cryptsetup > /dev/null 2>&1 && unlock_luks
[ "$luks" = 1 ] && unlock_luks
[ "$lvm" = 1 ] && trigger_lvm
[ "$lvm" = 1 ] &&
command -v lvm > /dev/null 2>&1 && trigger_lvm
mount_rootfs
[ "$debug" = 1 ] && panic "dropping to shell"
cleanup
boot_system
mount_root
cleanup
boot_system
}