mirror of
https://github.com/LibreELEC/LibreELEC.tv.git
synced 2025-07-31 14:37:59 +00:00
Merge pull request #324 from ackalker/busybox-initramfs-init
initramfs init: enhancement / redesign proposal, this fixes #60 as well
This commit is contained in:
commit
3b0c4c8189
@ -21,16 +21,14 @@
|
||||
# http://www.gnu.org/copyleft/gpl.html
|
||||
################################################################################
|
||||
|
||||
MODULE_DIR=/lib/modules
|
||||
UPDATE_DIR=/storage/.update
|
||||
|
||||
IMAGE_SYSTEM="SYSTEM"
|
||||
IMAGE_KERNEL="KERNEL"
|
||||
REBOOT="0"
|
||||
|
||||
# defaults for booting from an nbd root
|
||||
NBD_ROOT_SERVER="192.168.1.1"
|
||||
NBD_ROOT_PORT="2000"
|
||||
NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
NBD_DEVS="0"
|
||||
|
||||
# mount all needed special filesystems
|
||||
/bin/busybox mount -t devtmpfs none /dev
|
||||
@ -62,22 +60,11 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
fastboot)
|
||||
FASTBOOT=yes
|
||||
;;
|
||||
netboot)
|
||||
NETBOOT=yes
|
||||
overlay)
|
||||
OVERLAY=yes
|
||||
;;
|
||||
nbdroot=*)
|
||||
nbdroot="${arg#nbdroot=}"
|
||||
NBD_ROOT_SERVER=$( echo "${nbdroot}" | /bin/busybox sed 's/:.*//')
|
||||
NBD_ROOT_PORT=$( echo "${nbdroot}" | /bin/busybox sed 's/.*://')
|
||||
;;
|
||||
nbdserver=*)
|
||||
NBD_ROOT_SERVER="${arg#nbdserver=}"
|
||||
;;
|
||||
nbdport=*)
|
||||
NBD_ROOT_PORT="${arg#nbdport=}"
|
||||
;;
|
||||
nfsoverlay=*)
|
||||
NFS_OVERLAY="${arg#nfsoverlay=}"
|
||||
break=*)
|
||||
BREAK="${arg#*=}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@ -86,16 +73,19 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
IONICE="/bin/busybox ionice -c 1 -n 0"
|
||||
fi
|
||||
|
||||
if test "$DEBUG" = "yes"; then
|
||||
exec 3>&1
|
||||
else
|
||||
exec 3>/dev/null
|
||||
fi
|
||||
SILENT_OUT=3
|
||||
|
||||
progress() {
|
||||
if test "$PROGRESS" = "yes"; then
|
||||
echo "### $1 ###"
|
||||
fi
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "Error Code: $1 that means: $2"
|
||||
}
|
||||
|
||||
debug_shell() {
|
||||
echo "### Starting debugging shell... type exit to quit ###"
|
||||
|
||||
@ -105,29 +95,105 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
/bin/busybox sh </dev/tty1 >/dev/tty1 2>&1
|
||||
}
|
||||
|
||||
error() {
|
||||
# Display fatal error message
|
||||
# $1:action which caused error, $2:message
|
||||
echo "*** Error in $BOOT_STEP: $1: $2 ***"
|
||||
if [ -z "$DEBUG" ]; then
|
||||
/bin/busybox halt
|
||||
else
|
||||
debug_shell
|
||||
fi
|
||||
}
|
||||
|
||||
break_after() {
|
||||
# Start debug shell after boot step $1
|
||||
case $BREAK in
|
||||
all|*$1*)
|
||||
debug_shell
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Mount handlers
|
||||
# All handlers take the following parameters:
|
||||
# $1:target, $2:mountpoint, $3:mount options, [$4:fs type]
|
||||
|
||||
mount_common() {
|
||||
# Common mount handler, handles block devices and filesystem images
|
||||
MOUNT_OPTIONS="-o $3"
|
||||
[ -n "$4" ] && MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS"
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
ERR_ENV=1
|
||||
|
||||
$IONICE /bin/busybox mount $MOUNT_OPTIONS $1 $2 >&$SILENT_OUT 2>&1
|
||||
[ "$?" -eq "0" ] && ERR_ENV=0 && break
|
||||
|
||||
/bin/busybox usleep 1000000
|
||||
done
|
||||
[ "$ERR_ENV" -ne "0" ] && error "mount_common" "Could not mount $1"
|
||||
}
|
||||
|
||||
mount_cifs() {
|
||||
# Mount CIFS (Samba) share
|
||||
CIFS_SHARE="${1%%,*}"
|
||||
CIFS_OPTIONS="${1#*,}"
|
||||
[ "$CIFS_OPTIONS" = "$1" ] && CIFS_OPTIONS=
|
||||
|
||||
mount_common "$CIFS_SHARE" "$2" "$3,$CIFS_OPTIONS" "cifs"
|
||||
}
|
||||
|
||||
mount_nbd() {
|
||||
# Mount NBD device
|
||||
NBD_SERVER="${1%%:*}"
|
||||
NBD_PORT="${1#*:}"
|
||||
NBD_DEV="/dev/nbd$NBD_DEVS"
|
||||
|
||||
$IONICE /bin/busybox nbd-client $NBD_SERVER $NBD_PORT $NBD_DEV >&$SILENT_OUT 2>&1 || \
|
||||
error "nbd-client" "Could not connect to NBD server $1"
|
||||
|
||||
mount_common "$NBD_DEV" "$2" "$3" "$4"
|
||||
|
||||
NBD_DEVS=$(( ${NBD_DEVS} + 1 ))
|
||||
}
|
||||
|
||||
mount_nfs() {
|
||||
# Mount NFS export
|
||||
NFS_OPTIONS="nolock,retrans=10"
|
||||
|
||||
mount_common "$1" "$2" "$3,$NFS_OPTIONS" "nfs"
|
||||
}
|
||||
|
||||
mount_part() {
|
||||
# progress "check filesystem $1 ..."
|
||||
# /sbin/fsck -M -T -a $1 > /dev/null 2>&1
|
||||
# Mount a local or network filesystem
|
||||
# $1:[TYPE=]target, $2:mountpoint, $3:mount options, [$4:fs type]
|
||||
progress "mount filesystem $1 ..."
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
ERR_ENV=1
|
||||
MOUNT_OPTIONS="-o $3 $1 $2"
|
||||
|
||||
if [ -n "$4" ]; then
|
||||
MOUNT_OPTIONS="-t $4 $MOUNT_OPTIONS"
|
||||
fi
|
||||
|
||||
progress "mount filesystem $1 ..."
|
||||
$IONICE /bin/busybox mount $MOUNT_OPTIONS > /dev/null 2>&1
|
||||
[ "$?" -eq "0" ] && ERR_ENV=0 && break
|
||||
|
||||
/bin/busybox usleep 1000000
|
||||
done
|
||||
[ "$ERR_ENV" -ne "0" ] && error "INIT_4" "Could not mount $1" && debug_shell
|
||||
MOUNT_TARGET="${1#*=}"
|
||||
case $1 in
|
||||
LABEL=*|UUID=*|/*)
|
||||
MOUNT_CMD="mount_common"
|
||||
MOUNT_TARGET="$1"
|
||||
;;
|
||||
CIFS=*|SMB=*)
|
||||
MOUNT_CMD="mount_cifs"
|
||||
;;
|
||||
NBD=*)
|
||||
MOUNT_CMD="mount_nbd"
|
||||
;;
|
||||
NFS=*)
|
||||
MOUNT_CMD="mount_nfs"
|
||||
;;
|
||||
*)
|
||||
error "mount_part" "Unknown filesystem $1"
|
||||
;;
|
||||
esac
|
||||
$MOUNT_CMD "$MOUNT_TARGET" "$2" "$3" "$4"
|
||||
}
|
||||
|
||||
update() {
|
||||
if [ -f "$UPDATE_DIR/$2" ]; then
|
||||
if [ -f "$UPDATE_DIR/$2" -a -f "$3" ]; then
|
||||
echo "updating $1..."
|
||||
$IONICE /bin/busybox mount -o remount,rw /flash
|
||||
$IONICE /bin/busybox mv $UPDATE_DIR/$2 $3
|
||||
@ -149,88 +215,105 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
|
||||
if [ "$FS_TYPE" = "\"hfs\"" -o "$FS_TYPE" = "\"hfsplus\"" ]; then
|
||||
progress "check filesystem $DEVICE [$FS_TYPE]..."
|
||||
/bin/fsck_hfs -r -y $DEVICE > /dev/null 2>&1
|
||||
/bin/fsck_hfs -r -y $DEVICE >&$SILENT_OUT 2>&1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
mount_nbd() {
|
||||
retry_nr=0
|
||||
retry_delay=20
|
||||
OVERLAY_DIR=`cat /sys/class/net/eth0/address | /bin/busybox tr -d :`
|
||||
load_modules() {
|
||||
progress "Loading kernel modules"
|
||||
|
||||
while [ ${retry_nr} -lt ${retry_delay} ] && [ ! -e /sysroot/sbin/init ]; do
|
||||
[ ${retry_nr} -gt 0 ] && \
|
||||
$IONICE /bin/busybox nbd-client $NBD_ROOT_SERVER $NBD_ROOT_PORT /dev/nbd0 && \
|
||||
mount_part "/dev/nbd0" "/sysroot" "ro" "squashfs"
|
||||
|
||||
retry_nr=$(( ${retry_nr} + 1 ))
|
||||
|
||||
[ ! -e /sysroot/sbin/init ] && /bin/busybox usleep 1000000
|
||||
|
||||
[ ${retry_nr} -gt 0 ]
|
||||
[ ! -f "/etc/modules" ] && return
|
||||
for module in $(cat /etc/modules); do
|
||||
progress "Loading kernel module $module"
|
||||
/bin/busybox insmod "$MODULE_DIR/$module" || \
|
||||
error "load_modules" "Failed to load kernel module $module"
|
||||
done
|
||||
|
||||
if [ ! -e /sysroot/sbin/init ]; then
|
||||
error "INIT_2" "Could not mount NBD root from $NBD_ROOT_SERVER port $NBD_ROOT_PORT"
|
||||
debug_shell
|
||||
fi
|
||||
|
||||
mount_part "$NFS_OVERLAY" "/sysroot/storage" "rw,nolock,retrans=10" "nfs"
|
||||
|
||||
if [ ! -d /sysroot/storage/$OVERLAY_DIR ]; then
|
||||
mkdir /sysroot/storage/$OVERLAY_DIR
|
||||
fi
|
||||
|
||||
/bin/busybox umount /sysroot/storage
|
||||
mount_part "$NFS_OVERLAY/$OVERLAY_DIR" "/sysroot/storage" "rw,nolock" "nfs"
|
||||
}
|
||||
|
||||
mount_disk() {
|
||||
# deal with hfs partitions
|
||||
check_disks() {
|
||||
progress "Checking disks"
|
||||
|
||||
if [ -x /sbin/fsck_hfs ]; then
|
||||
# deal with hfs partitions
|
||||
hfsdiskprep
|
||||
fi
|
||||
}
|
||||
|
||||
mount_disks() {
|
||||
progress "Mounting disks"
|
||||
|
||||
mount_part "$boot" "/flash" "ro,noatime"
|
||||
|
||||
if [ -n "$disk" ]; then
|
||||
if [ -n "$OVERLAY" ]; then
|
||||
OVERLAY_DIR=`cat /sys/class/net/eth0/address | /bin/busybox tr -d :`
|
||||
|
||||
mount_part "$disk" "/storage" "rw,noatime"
|
||||
mkdir -p /storage/$OVERLAY_DIR
|
||||
/bin/busybox umount /storage
|
||||
|
||||
# split $disk into $target,$options so we can append $OVERLAY_DIR
|
||||
options="${disk#*,}"
|
||||
target="${disk%%,*}"
|
||||
if [ "$options" = "$disk" ]; then
|
||||
disk="$target/$OVERLAY_DIR"
|
||||
else
|
||||
disk="$target/$OVERLAY_DIR,$options"
|
||||
fi
|
||||
fi
|
||||
|
||||
mount_part "$disk" "/storage" "rw,noatime"
|
||||
|
||||
if [ -f "/flash/MACH_KERNEL" ]; then
|
||||
IMAGE_KERNEL="MACH_KERNEL"
|
||||
fi
|
||||
|
||||
update "Kernel" "$IMAGE_KERNEL" "/flash/$IMAGE_KERNEL"
|
||||
update "System" "$IMAGE_SYSTEM" "/flash/$IMAGE_SYSTEM"
|
||||
|
||||
if test "$REBOOT" -eq "1"; then
|
||||
echo "System reboots now..." && \
|
||||
/bin/busybox reboot
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
check_update() {
|
||||
progress "Checking for updates"
|
||||
|
||||
if [ -f "/flash/MACH_KERNEL" ]; then
|
||||
IMAGE_KERNEL="MACH_KERNEL"
|
||||
fi
|
||||
|
||||
update "Kernel" "$IMAGE_KERNEL" "/flash/$IMAGE_KERNEL"
|
||||
update "System" "$IMAGE_SYSTEM" "/flash/$IMAGE_SYSTEM"
|
||||
|
||||
if test "$REBOOT" -eq "1"; then
|
||||
echo "System reboots now..." && \
|
||||
/bin/busybox reboot
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_sysroot() {
|
||||
progress "Preparing system"
|
||||
|
||||
if [ -f "/flash/$IMAGE_SYSTEM" ]; then
|
||||
# /flash is filesystem with system image file
|
||||
mount_part "/flash/$IMAGE_SYSTEM" "/sysroot" "ro,loop"
|
||||
[ "$ERR_ENV" -ne "0" ] && debug_shell
|
||||
/bin/busybox mount --move /flash /sysroot/flash
|
||||
else
|
||||
error "INIT_2" "Could not find system."
|
||||
debug_shell
|
||||
# /flash is actual root filesystem
|
||||
/bin/busybox mount --move /flash /sysroot
|
||||
fi
|
||||
|
||||
# move /flash and /storage to /sysroot
|
||||
/bin/busybox mount --move /flash /sysroot/flash
|
||||
|
||||
if [ -n "$disk" ]; then
|
||||
/bin/busybox mount --move /storage /sysroot/storage
|
||||
fi
|
||||
|
||||
[ -f "/sysroot/sbin/init" ] || error "final_check" "Could not find system."
|
||||
}
|
||||
|
||||
if [ -z "$NETBOOT" ]; then
|
||||
mount_disk
|
||||
else
|
||||
mount_nbd
|
||||
fi
|
||||
# main boot sequence
|
||||
for BOOT_STEP in \
|
||||
load_modules \
|
||||
check_disks \
|
||||
mount_disks \
|
||||
check_update \
|
||||
prepare_sysroot; do
|
||||
$BOOT_STEP
|
||||
[ -n "$DEBUG" ] && break_after $BOOT_STEP
|
||||
done
|
||||
|
||||
BOOT_STEP=final
|
||||
|
||||
# move some special filesystems
|
||||
/bin/busybox mount --move /dev /sysroot/dev
|
||||
@ -240,5 +323,4 @@ NFS_OVERLAY="192.168.1.1:/var/lib/overlay"
|
||||
# switch to new sysroot and start real init
|
||||
exec /bin/busybox switch_root /sysroot /sbin/init
|
||||
|
||||
error "INIT_3" "Error in initramfs. Could not switch to new root"
|
||||
debug_shell
|
||||
error "switch_root" "Error in initramfs. Could not switch to new root"
|
||||
|
Loading…
x
Reference in New Issue
Block a user