#!/bin/sh PATH=/bin /bin/busybox --install busybox sleep 1 busybox mount -t proc proc /proc busybox mount -t sysfs sysfs /sys busybox mount -t devtmpfs none /dev root_sfs="" root="" overlay_dev="" singleuser=0 for param in `cat /proc/cmdline`; do case $param in root=*) root="${param##root=}" ;; root_sfs=*) root_sfs="${param##root_sfs=}" ;; overlay_dev=*) overlay_dev="${param##overlay_dev=}" ;; single*) singleuser=1 ;; esac done if [ -z "${root}" ]; then echo "No root drive specified!" exec /bin/busybox sh fi if [ -z "${root_sfs}" ]; then echo "No squashfs image specified!" exec /bin/busybox sh fi while [ ! -e ${root} ]; do echo "Waiting for root" busybox sleep 1 done # file system setup overlay_mount() { local lower=/newroot/${1} local upper=/newroot/${2} local work=/newroot/${2}_work local target=/newroot/${3} mount -t overlay overlay -olowerdir=${lower},upperdir=${upper},workdir=${work} ${target} } bind_mount() { mount --bind /newroot/${1} /newroot/${2} } setup_vfs() { local root=${1} mount -t proc proc $root/proc mount -t sysfs sysfs $root/sys mount -t devtmpfs none $root/dev # setup /dev [ -e $root/dev/fd ] || ln -snf /proc/self/fd $root/dev/fd [ -e $root/dev/stdin ] || ln -snf /proc/self/fd/0 $root/dev/stdin [ -e $root/dev/stdout ] || ln -snf /proc/self/fd/1 $root/dev/stdout [ -e $root/dev/stderr ] || ln -snf /proc/self/fd/2 $root/dev/stderr [ -e $root/proc/kcore ] && ln -snf /proc/kcore $root/dev/core for x in \ "mqueue dev/mqueue 1777 ,nodev mqueue" \ "devpts dev/pts 0755 ,gid=5,mode=0620 devpts" \ "tmpfs dev/shm 1777 ,nodev,mode=1777 shm" \ ; do set -- $x grep -Eq "[[:space:]]+$1$" /proc/filesystems || continue if [ ! -d "$root/$2" ]; then mkdir -m $3 -p "$root/$2" >/dev/null 2>&1 || \ echo "Could not create $root/$2!" fi if [ -d "$root/$2" ]; then mount -t $1 -o noexec,nosuid$4 $5 "$root/$2" fi done # set up additional mounts in /proc and /sys for x in \ "sys/kernel/security securityfs nodev,noexec,nosuid" \ "sys/kernel/config configfs nodev,noexec,nosuid" \ "sys/fs/fuse/connections fusectl nodev,noexec,nosuid" \ "sys/firmware/efi/efivars efivarfs ro" \ "proc/sys/fs/binfmt_misc binfmt_misc nodev,noexec,nosuid" \ ; do set -- $x if [ -d "$root/$1" ]; then if grep -qs $2 "$root/proc/filesystems"; then echo "Mounting $2 filesystem" mount -n -t $2 -o $3 $2 "$root/$1" fi fi done unset -v x } mount ${root} /images if [ ! -e /images/${root_sfs} ]; then echo "${root_sfs} not found!" exec /bin/busybox sh exit 1 fi mount -t squashfs /images/${root_sfs} /newroot setup_vfs "/newroot" mount -t tmpfs none /newroot/tmp mount -t tmpfs none /newroot/var mount -t tmpfs none /newroot/run chmod 755 /newroot/var mkdir -p /newroot/run/log/journal mkdir -p /newroot/var/log/fsck mkdir -p /newroot/var/log/nginx mkdir -p /newroot/var/log/mpd mkdir -p /newroot/var/spool/ mkdir -p /newroot/var/lib/ mkdir -p /newroot/var/tmp ln -s /run /newroot/var/run ln -s /run/lock /newroot/var/lock if [ ! -z "$overlay_dev" ]; then while [ ! -e ${overlay_dev} ]; do echo "Waiting for overlay device" busybox sleep 1 done mount ${overlay_dev} /newroot/cfg/overlay overlay_mount "cfg/preserve/etc" "cfg/overlay/etc" "etc" overlay_mount "cfg/preserve/var_lib" "cfg/overlay/var_lib" "var/lib" overlay_mount "cfg/preserve/root" "cfg/overlay/root" "root" else bind_mount "cfg/preserve/etc" "etc" bind_mount "cfg/preserve/var_lib" "var/lib" bind_mount "cfg/preserve/root" "root" fi # cleanup mounts umount -l /images umount -l /dev umount /sys umount /proc if [ "$singleuser" == "1" ]; then unset -v singleuser overlay_dev root root_sfs exec /bin/busybox switch_root /newroot /bin/bash fi unset -v singleuser overlay_dev root root_sfs exec /bin/busybox switch_root /newroot /bin/init