# shellcheck disable=SC2148 export PATH=".:/:/usr/sbin:/usr/bin:/sbin:/bin" export LD_LIBRARY_PATH="/lib:/lib/i386-linux-gnu:/lib64:/lib64/x86_64-linux-gnu:/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu:/usr/lib64/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu" export MEMORY="/memory" export MODULES="${MEMORY}/modules" export CHANGES_MNT="${MEMORY}/changes" export CHANGES="${CHANGES_MNT}/changes" export WORK="${CHANGES_MNT}/work" export UNION="${MEMORY}/union" export DATAMNT="${MEMORY}/data" export SYSTEM="${MEMORY}/system" export SHELL_IS_ENABLED=false grepCmdLine() { egrep -o "(^|[[:space:]])${1}=[^[:space:]]+" /proc/cmdline | tr -d " " | cut -d "=" -f 2- | tail -n 1 #for i in $(/dev/null 2>&1 return ${?} } m() { case "${1}" in q) echo -e "[Question]: ${2}";; A) echo -e "[Action]: ${2}";; i) echo -e "[Info]: ${2}";; w) echo -e "[Warning]: ${2}";; e) echo -e "[Error]: ${2}";; f) echo -e "[Fatal]: ${2}";; *) echo -e "${1}";; esac } rp() { local pid force [[ ${1} = f ]]&&force=true shift sh -c "${1}" >/dev/null 2>&1& pid="${!}" while :; do if [ -d /proc/${pid} ]; then [ ${force} ]&&echo -n "." d&&echo -n "." sleep 0.25 else break fi done return ${?} } isShellEnabled() { d&&m q "Is 'shell' bootloader variable set " if grepCmdLine shell; then d&&m a "Yes\n" sed -i "s/SHELL_IS_ENABLED=false/SHELL_IS_ENABLED=true/" /lib/functions m A "Reloading /lib/functions " if . /lib/functions; then m i "Done\n" else m f "Failed\n" emergencyShell fi else d&&m a "No\n" fi } isZramEnabled() { d&&m q "Is zram supported? " if [ -e /sys/block/zram0/disksize ]; then d&&m a "Yes\n" m A "Enabling zram " echo 536870912 >/sys/block/zram0/disksize if mkswap /dev/zram0 >/dev/null 2>&1;then m i "Done\n";else m w "Failed\n";fi if swapon /dev/zram0 >/dev/null 2>&1;then m i "Done\n";else m w "Failed\n";fi echo 100 >/proc/sys/vm/swappiness else d&&m i "No\n" fi } toRam() { d&&m q "Is 'toram' bootloader variable set and enought RAM space? " if grepCmdLine toram; a=${?}&&[[ "$(grep MemFree /proc/meminfo|awk '{print $2}')" -gt $(("$(du ${DATAMNT}|tail -n1|awk '{print $1}')"-"$(du ${DATAMNT}/changes|tail -n1|awk '{print $1}')")) ]]; then d&&m a "Yes\n" mkdir -p /tmp/data d&&m A "Copying to RAM " if progress f "tar -c -C ${DATAMNT} --exclude ./changes -f - . | tar -xf - -C /tmp/data";then dm i "Done\n";else m w "Failed\n";fi umount -f ${DATAMNT} >/dev/null 2>&1 [[ ${from} ]]&&umount -f ${DATAMNT} >/dev/null 2>&1 mv -f /tmp/data/* ${DATAMNT} >/dev/null 2>&1 rm -rf /tmp/data >/dev/null 2>&1 else d&&[[ "${a}" != "0" ]]&&m e "Not requested by bootloader or low RAM space!\n"||m w "Internal error? Trying tmpfs, so data after power-off will be erased permanently!\n" mount -o remount,rw ${DATAMNT} >/dev/null 2>&1||true fi } findData() { d&&m A "Searching ${DISTRO} in /dev -> " local data a data="$(grepCmdLine from)" for i in ${root:-$(blkid|cut -d: -f1||echo /dev/[hmnsv][dmrv][0-9a-z]*)}; do d&&m "${i#/dev/} " mount -o ro ${i} ${DATAMNT} >/dev/null 2>&1 sleep 0.5 [[ ${data} ]]&&mount ${DATAMNT}/${data} ${DATAMNT} >/dev/null 2>&1 if [[ -e ${DATAMNT}/.LlfMeta && -e ${DATAMNT}/os/system.sfs ]]; then d&&m i "\nFound ${DISTRO} in ${i}\n" if grepCmdLine fsck;then fsck ${i} >/dev/null 2>&1;else true;fi toRam mount ${DATAMNT}/os/system.sfs ${SYSTEM} >/dev/null 2>&1 sleep 0.5 break else umount -f ${DATAMNT} >/dev/null 2>&1 fi done if ! grep -q ${SYSTEM} /proc/mounts; then d&&m f "Can not find compatible distro!\n" emergencyShell fi } findModules() { d&&m A "Trying to mount modules from ${DATAMNT}/${DISTRO}/modules -> " if ls ${DATAMNT}/${DISTRO}/modules/*.sfs >/dev/null 2>&1; then for i in $(find ${DATAMNT}/${DISTRO}/modules -maxdepth 1 -type f -name "*.sfs"|sort); do mkdir -p ${MODULES}/$(basename ${i} .sfs) d&&m "$(basename ${i}) " mount ${i} ${MODULES}/$(basename ${i} .sfs) >/dev/null 2>&1 done d&&m i "Done\n" else d&&m w "Modules not found! Continuing...\n" fi } mountOverlay() { if grep -q ${MODULES} /proc/mounts; then mount -t overlay -o lowerdir=${SYSTEM}:$(find ${MODULES} -mindepth 1 -maxdepth 1 | tac | tr "\n" ":" | sed -r "s/:$//"),upperdir=${CHANGES},workdir=${WORK} overlay ${UNION} else mount -t overlay -o lowerdir=${SYSTEM},upperdir=${CHANGES},workdir=${WORK} overlay ${UNION} fi } persistentChanges() { if ! grepCmdLine perch&&grepCmdLine toram; then return ${?} fi local CHANGES T1 T2 EXISTS CHANGES=$DATAMNT/changes T1="$CHANGES/.empty" T2="$T1"2 d&&m A "Testing for RW access to persistent changes...\n" mkdir -p "$2" touch "$T1" 2>/dev/null&&rm -f "$T1" 2>/dev/null||d&&m w "Failed\n" d&&m A "Testing persistent changes for posix compatibility...\n" touch "$T1"&&ln -sf "$T1" "$T2" 2>/dev/null&&chmod +x "$T1" 2>/dev/null&&test -x "$T1"&&chmod -x "$T1" 2>/dev/null&&test ! -x "$T1"&&rm "$T1" "$T2" 2>/dev/null if [ $? -eq 0 ]; then d&&m A "Activating native persistent changes\n" mount --bind "$CHANGES" "$2" >/dev/null 2>&1 return ${?} else d&&m w "Failed\n" fi if [ -e "$CHANGES/changes.dat" ]; then d&&m A "Restoring persistent changes\n" EXISTS="true" else d&&m A "Creating new persistent changes\n" fi mount.dynfilefs -f "$CHANGES/changes.dat" -s 16000 -m "$2" -p 4000 >/dev/null 2>&1||d&&m e "Failed\n" [ "$EXISTS" ]||mke2fs -F -L "DATA" "$2/virtual.dat" >/dev/null 2>&1 grepCmdLine fsck&&fsck ${2}/virtual.dat >/dev/null 2>&1 mount "$2/virtual.dat" "$2" >/dev/null 2>&1 rm "$T1" "$T2" >/dev/null 2>&1 rmdir "$2/lost+found" >/dev/null 2>&1 } debugShell() { if [ "$SHELL_IS_ENABLED" = "true" ]; then echo -e "Debug shell!\nControl+D or 'exit' to contiunue boot.\n" setsid cttyhack bash fi } changeRoot() { cd "$1" umount -f /sys /proc cat <etc/fstab proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 overlay / overlay defaults 0 0 eot mkdir -p run mount -t tmpfs tmpfs run mkdir -p run/initramfs mount -o remount,ro overlay . pivot_root . run/initramfs exec chroot . init } emergencyShell() { exec >/dev/console >&1 2>&1 <&1 echo "Error: Please inspect '/llf.log' file" export PS1="RESCUE # " while :; do echo "Rescue shell!" setsid cttyhack bash done }