221 lines
6.4 KiB
Plaintext
Executable File
221 lines
6.4 KiB
Plaintext
Executable File
# 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 $(</proc/cmdline); do egrep "^${1}|^${1}=.*" <<<${i}|cut -f2 -d=; done
|
|
return ${?}
|
|
}
|
|
d()
|
|
{
|
|
grepCmdLine debug >/dev/null 2>&1
|
|
return ${?}
|
|
}
|
|
m()
|
|
{
|
|
case "${1}" in
|
|
q) printf '%s' "[Question]: ${2}";;
|
|
a) printf '%s' "[Answer]: ${2}";;
|
|
A) printf '%s' "[Action]: ${2}";;
|
|
i) printf '%s' "[Info]: ${2}";;
|
|
w) printf '%s' "[Warning]: ${2}";;
|
|
e) printf '%s' "[Error]: ${2}";;
|
|
f) printf '%s' "[Fatal]: ${2}";;
|
|
*) printf '%s' "${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 <<eot >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
|
|
}
|