#!/bin/sh set -eu log() { echo "[init] $*" >&2 } panic() { echo "initramfs panic: $*" >&2 exec sh } mount_or_panic() { mount "$@" || panic "mount failed: $*" } mount_retry() { dev="$1" target="$2" fstype="$3" opts="$4" i=0 while :; do if mount -o "$opts" -t "$fstype" "$dev" "$target"; then return 0 fi i=$((i + 1)) [ "$i" -ge 50 ] && panic "Timed out mounting $dev on $target" sleep 0.2 done } wait_for_path() { path="$1" i=0 while [ ! -e "$path" ]; do i=$((i + 1)) [ "$i" -ge 50 ] && panic "Timed out waiting for $path" sleep 0.2 done } mkdir -p /dev /proc /sys /run mount_or_panic -t devtmpfs devtmpfs /dev mount_or_panic -t proc proc /proc mount_or_panic -t sysfs sysfs /sys mount_or_panic -t tmpfs tmpfs /run echo 1 > /proc/sys/kernel/printk mkdir -p /dev/pts mount_or_panic -t devpts devpts /dev/pts # Optional early fan kick. Do not fail boot if this path is not ready yet. if [ -w /sys/class/hwmon/hwmon0/pwm1 ]; then echo 100 > /sys/class/hwmon/hwmon0/pwm1 || true fi log "Booting kernel took $(cut -d' ' -f1 /proc/uptime) seconds." . /etc/build-info || panic "failed to source /etc/build-info" ROOT_DEV="" DATA_DEV="" for arg in $(cat /proc/cmdline); do case "$arg" in root=*) ROOT_DEV="${arg#root=}" ;; data=*) DATA_DEV="${arg#data=}" ;; esac done [ -n "$ROOT_DEV" ] || { log "No root= specified in cmdline" exec sh } [ -n "$DATA_DEV" ] || { log "No data= specified in cmdline" exec sh } wait_for_path "$DATA_DEV" e2fsck -p "$DATA_DEV" || { echo "Auto fsck failed, forcing repair" e2fsck -y "$DATA_DEV" || panic "fsck failed on $DATA_DEV" } mkdir -p /newroot mount_retry "$ROOT_DEV" /newroot ext4 ro mount_retry "$DATA_DEV" /newroot/data ext4 rw mount_or_panic --bind /newroot/data/var /newroot/var mount_or_panic -t overlay overlay \ -o lowerdir=/newroot/etc,upperdir=/newroot/data/etc-overlay/upper,workdir=/newroot/data/etc-overlay/work \ /newroot/etc mount_or_panic --move /dev /newroot/dev mount_or_panic --move /proc /newroot/proc mount_or_panic --move /sys /newroot/sys mount_or_panic --move /run /newroot/run log "Switching root to $ROOT_DEV" exec switch_root /newroot /sbin/init panic "switch_root returned unexpectedly"