#!/sbin/busybox sh # # tiny init script panic() { printf "panic >> %s\n" "$1" # TODO fix job control sh -l } parse_cmdline() { # turn output into list set -- $(cat /proc/cmdline) for line in "$@"; do value="${line##*=}" 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.conf) ;; #luks_header) ;; #luks_keyfile) ;; esac done } mount_pseudofs() { mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none /dev } setup_devmgr() { case "$devmgr" in udev) udevd -d udevadm trigger -c add -t subsystems udevadm trigger -c add -t devices udevadm settle ;; mdev) uevent mdev & mdev -s for device in /sys/bus/usb/devices/*; do case "${device##*/}" in [0-9]*-[0-9]*) printf add > "${device}/uevent" ;; esac done find /sys -name modalias -type f -exec sort -u {} + | xargs modprobe -b > /dev/null 2>&1 ;; mdevd) mdevd & mdevd-coldplug ;; *) panic "devmgr option broken" ;; esac } findfs_sh() { value="${1##*=}" 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" ;; *) panic "findfs option broken" ;; esac # avoid race condition while [ ! -e "$device" ]; do sleep 0.5 [ "$increment" ] || increment=0 increment=$(( increment + 1 )) [ "$increment" = 10 ] && panic "failed to lookup partition" done printf "%s\n" "$device" } unlock_luks() { [ "$luks_discard" = 1 ] && luks_args="--allow-discards $luks_args" cryptsetup $luks_args luksOpen $(findfs_sh "$luks_root") ${luks_name:-luks_root} || panic "failed to unlock luks container" } trigger_lvm() { if [ "$lvm_group" ] && [ "$lvm_name" ]; then lvm lvchange $lvm_args --sysinit -q -a y "${lvm_group}/${lvm_name}" > /dev/null elif [ "$lvm_group" ]; then lvm vgchange $lvm_args --sysinit -q -a y "$lvm_group" > /dev/null else lvm vgchange $lvm_args --sysinit -q -a y > /dev/null fi } mount_rootfs() { mount ${root_type:+-t $root_type} ${root_opts:+-o $root_opts} $(findfs_sh "$root") /mnt/root || panic "failed to mount rootfs" } cleanup() { case "$devmgr" in udev) udevadm control -e ;; mdev) killall uevent ;; mdevd) killall mdevd ;; esac # unmount pseudofs's umount /dev /sys /proc } boot_system() { exec switch_root /mnt/root ${init:-/sbin/init} || panic "failed to boot system" } /sbin/busybox --install -s . /config || panic "failed to source config" mount_pseudofs parse_cmdline [ "$debug" = 1 ] && set -x setup_devmgr # TODO handle situations when LUKS on LVM [ "$luks" = 1 ] && command -v cryptsetup > /dev/null 2>&1 && unlock_luks [ "$lvm" = 1 ] && command -v lvm > /dev/null 2>&1 && trigger_lvm mount_rootfs [ "$debug" = 1 ] && panic "dropping to shell" cleanup boot_system