From: Steffen Nurpmeso <steffen@sdaoden.eu>
To: "Michael Kjörling" <e5655f30a07f@ewoof.net>
Cc: tuhs@tuhs.org
Subject: [TUHS] Re: Unix install & "standalone" package
Date: Sun, 10 Sep 2023 00:43:12 +0200 [thread overview]
Message-ID: <20230909224312.gGToQ%steffen@sdaoden.eu> (raw)
In-Reply-To: <20230908233854.Xni_j%steffen@sdaoden.eu>
[-- Attachment #1: Type: text/plain, Size: 7275 bytes --]
Steffen Nurpmeso wrote in
<20230908233854.Xni_j%steffen@sdaoden.eu>:
|Michael Kjörling wrote in
| <f948d06c-14f4-40bd-8e32-4db1c5b1dd21@home.arpa>:
||On 5 Sep 2023 17:53 +0200, from steffen@sdaoden.eu (Steffen Nurpmeso):
...
||> Of course i am no real Linux expert but only a do-it-yourself guy.
||
||If your need is restricted to a highly specific use case and you are
||trying to keep it as small as possible, then it should be possible to
...
Actually maybe someone may find it funny, even though it is
neither historic nor very sophisticated. Let me post it.
In the end it takes some time to get there.
I would expect almost all of you will not be interested in the
lengthy rest of this mail.
Ciao, and a nice Sunday i wish from Germany!
All you need are statically linked busybox (and cryptsetup with
encryption), and a kernel with EFI_STUB on the EFI partition, so
it can be booted directly. The distribution kernels i have
(ArchLinux, AlpineLinux) have it enabled; if your EFI is large
enough you could simply copy it and all its masses of modules to
EFI.
Otherwise the kernel needs all the firmware and modules to boot
and to access all filesystems where the real stuff is. My own
kernel has a lot of things statically built-in, but it can load
more via modules (stage2 uses "the same" kernel later, and does).
Kernels on stage2 need kexec, i have
CONFIG_KEXEC=y
CONFIG_KEXEC_FILE=y
CONFIG_ARCH_HAS_KEXEC_PURGATORY=y
# CONFIG_KEXEC_SIG is not set
CONFIG_KEXEC_CORE=y
-s1.sh and -s2.sh are docu-commented at the top; they can also be
used to create the necessary environment. If i recall correctly
cd /boot
sh linit-init-s2.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP
mount EFI-PARTITION
cd EFI-PARTITION
sh linit-init-s1.sh PATH-TO-BUSYBOX PATH-TO-CRYPTSETUP
This only creates files and directories etc, and beat me if it
does any harm otherwise.
I use a specific naming scheme, the script reacts in particular
on -old and -new to select sensible defaults.
#?0|kent:/boot# ll ideapad*.efi
-rwxr-xr-x 1 root root 10112672 Aug 26 18:44 ideapad-stage1.efi*
-rw-r--r-- 1 root root 10120512 Sep 2 19:52 ideapad-6_1.efi
-rw-r--r-- 1 root root 10120512 Sep 9 18:18 ideapad-6_1-old.efi
-rw-r--r-- 1 root root 10121376 Sep 9 18:18 ideapad-6_1-new.efi
That very kernel (series) is in fact shared in between several
computers of a similar series, kent is the one i write this on:
#?1|kent:/boot# v kent.sh
#!/busybox.static sh
#@ kent, step 1., via EFI.
PART_ROOT=/dev/nvme0n1p?
ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
PART_ROOT1=/dev/nvme0n1p8
ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
INIT_S2=/boot/kent-2.sh
. /linux-init-s1.sh
#?0|kent:/boot# v kent-2.sh
#@ kent, stage 2
KERNEL_ID=ideapad
^ restrict kernel selection for kexec:
^ [ "${k##*$KERNEL_ID-*.efi}" != "$k" ] || continue
PART_SWAP=/dev/nvme0n1p6
SWAP_INPUT=y
^ you can have additional interactive random for swap encryption
^ (it is a lie i use that in practice)
INITRD_PATH=/boot/.kent.initrd
KEXEC_ARGS="--append=\"rtw88_pci.disable_aspm=1 rc.hostname=kent\""
FILE_CHECK='kent-direct.sh kent.sh ideapad-stage1.efi'
SWITCH_ROOT=media/initrd
Stage 2 config file is sourced automatically, so no need to source
linux-init-s2.sh yourself (stage 2 uses switch_root).
I also have a direct boot, but have not used it for long:
#?0|kent:~# v /boot/kent-direct.sh
#!/busybox.static sh
#@ kent-direct, sole step 1., via EFI.
PART_ROOT=/dev/nvme0n1p8
ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
PART_ROOT1=/dev/nvme0n1p8
ROOT_DECRYPT1='-t btrfs -o defaults,subvol=/crux/kent/root.old'
PART_SWAP=/dev/nvme0n1p6
PIVOT_OLDROOT=media/initrd
. /linux-init-s1.sh
This does not use kexec, but only pivot_root's to the decrypted
filesystem, starting sbin/init there. The kernel from EFI
continues to run.
It is pretty cool how i now can drive several computers easily
simply by creating a shell script with some variable assignments.
In fact the filesystem is shared in between multiple computers
(with only selective partitions being truly unique, but still
backed up everywhere), and all those text configs are in /boot.
Only the VFAT EFI partition is truly system-specific (ie, in that
it only holds the stage1 config file for $HOSTNAME).
I like that very much, and hope Linux continues to be so flexible.
(Not that one day you need systemd-early to get into Linux to get
to systemd-later, or something.)
The EFI boot is driven via efibootmgr(8) and has config like
#@ /root/hosts/self/efiboot
d=/dev/nvme0n1p1
maxno=1
b1=0x01 L1=kent l1=ideapad-stage1
u1='root='${d}' rootfstype=vfat init=/kent.sh'
driven by /root/bin/efiboot.sh (shortened):
#!/bin/sh
: ${HOSTNAME:=$(uname -n)}
: ${DBG:=}
if [ -f /root/hosts/${HOSTNAME}/efiboot ]; then
. /root/hosts/${HOSTNAME}/efiboot
else
echo >&2 "MISS /root/hosts/${HOSTNAME}/efiboot"
exit 1
fi
if [ "$1" = create ]; then
obo=$(efibootmgr | grep -E ^BootOrder: | sed -E 's/^BootOrder:[[:space:]]*//')
if [ -z "$obo" ]; then
echo >&2 'Cannot determine previous boot order'
exit 1
fi
nbo= i=1
while [ $i -le $maxno ]; do
eval ${DBG} efibootmgr -c -b \$b$i -L \\\"\$L$i\\\" -d \$d$i -l \\\"\$l$i.efi\\\" -u \\\"\$u$i\\\" #>/dev/null
[ -n "$nbo" ] && nbo=$nbo,
eval nbo=\$nbo\$b$i
i=$((i + 1))
done
${DBG} efibootmgr -o $nbo,$obo #> /dev/null
elif [ "$1" = delete ]; then
i=1
while [ $i -le $maxno ]; do
eval ${DBG} efibootmgr -B -b \$b$i #>/dev/null
i=$((i + 1))
done
else
echo >&2 'Synsopsis: efiboot.sh create|delete'
exit 1
fi
${DBG} efibootmgr -v -u
This is of course git managed, so i can distribute it easily.
(Further even, the entire ideapad series configurations differ in
only 193 lines, and most of those are the different SSH keys.
The rest are different device names, ie network, display, volume
etc, disk partitions, host names.)
I am pretty lucky i found a way to manage my systems like this.
I have several git branches in root.git, linux.kconfig, bin,
iwd.network, and one for each computer. I can then "git merge"
selectively together what is necessary. For example my web
vserver only needs bin and its own configuration, whereas the
laptops also need iwd.network. Etc etc. Like this every computer
only knows the selective minimum. The full git repo is on an
encrypted volume stored away.
And it is not Puppet or Ansible or any of those programs, it is
nothing but git and its branches.
But now i really left manually driven cryptsetup by far.
Ciao!
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
[-- Attachment #2: linux-init-s1.sh --]
[-- Type: application/x-sh, Size: 4596 bytes --]
#@ /linux-init-s1.sh, simple Linux init, stage 1.
#@ To be sourced from a kernel command line init=SCRIPT like:
#@
#@ #!/busybox.static sh
#@ #@ For kent
#@
#@ PART_ROOT=/dev/nvme0n1p8
#@ ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux/kent/root'
#@ PART_SWAP=/dev/nvme0n1p6
#@ INIT_S2=boot/kent-2.sh
#@
#@ . /linux-init-s1.sh
#@
#@ Alternatively call AS ROOT and FROM WITHIN directory that boots like
#@ sh linux-init-s1.sh PATH_TO_BUSYBOX PATH_TO_CRYPTSETUP
#@ and is expected to be mounted as / on system start, for init purposes.
# Non-empty and we run mdev -s very first (value passed to it via ARGV)
: ${MDEV_RUN:=}
# Unless ROOT_DECRYPT (only partition then) this can be mount spec, like
# PART_ROOT='-t btrfs -o defaults,subvol=/crux/kent/root'
[ $# -eq 0 ] &&
: ${PART_ROOT:?"Need a usable \$PART_ROOT"}
# Non-empty and we decrypt ROOT; _it_ should be mount spec then
: ${ROOT_DECRYPT:=}
# It is possible to specify multiple PART_ROOT[/ROOT_DECRYPT] tuples by
# giving PART_ROOT1, 2, 3... A dialog for choosing one to use then appears
# Non-empty and we create encrypted swap from the given partition
: ${PART_SWAP:=}
# Non-empty and we ask for more random bytes for swap encryption
: ${SWAP_INPUT:=}
# Non-empty and we give up to the stage 2 -s2.sh that is expected to live
# in [/dev/mapper/p_root]/boot. ONLY WITH $ROOT_DECRYPT!
# The value is the config file of stage 2 as an _absolute_ path within the
# newly mounted root.
: ${INIT_S2:=}
# Were we move old root to when doing pivot_root(8) in non-$INIT_S2 cases
: ${PIVOT_OLDROOT:=media/efi}
BB=busybox.static
CS=cryptsetup.static
# -- >8 -- 8< --
xroot() { # {{{
bb=./$BB cs=./$CS
slept= # May want to sleep to pass by kernel async console output
xbase_mounts "$bb" # (First for completeness sake [not needed])
#
PART_SUFFIX=.0
if [ -n "$PART_ROOT1" ]; then
# Sleep a bit and hope kernel async console output passed by then
[ -z "$slept" ] && $bb sleep 3
slept=y
while :; do
echo
echo '. Multiple $PART_ROOT[/$ROOT_DECRYPT] encountered:'
echo " [0] PART_ROOT=$PART_ROOT"
[ -n "$ROOT_DECRYPT" ] && echo " ROOT_DECRYPT=$ROOT_DECRYPT"
ri=1
while :; do
eval rx="\$PART_ROOT$ri"
[ -z "$rx" ] && break
echo " [$ri] ..ROOT$ri=$rx"
eval rx="\$ROOT_DECRYPT$ri"
[ -n "$rx" ] && echo " ..CRYPT$ri=$rx"
ri=$((ri + 1))
done
rmsg= rrt=
if (echo y | read -t 1 chck) >/dev/null 2>&1; then
rmsg=' (10 seconds until, or empty input for default)'
rrt='-t 10'
fi
printf '. Please choose $PART_ROOT'"$rmsg"'? '
read $rrt PART_SUFFIX
if [ $? -ne 0 ] || [ -z "$PART_SUFFIX" ] || [ "$PART_SUFFIX" = 0 ]; then
PART_SUFFIX=.0
echo
break
elif [ "${PART_SUFFIX##*[^0-9]}" != "$PART_SUFFIX" ]; then
echo >&2 '! Invalid input'
continue
fi
eval ri=\$PART_ROOT$PART_SUFFIX
if [ -z "$ri" ]; then
echo >&2 '! No such PART_ROOT: '$PART_SUFFIX
else
PART_ROOT=$ri
eval ROOT_DECRYPT=\$ROOT_DECRYPT$PART_SUFFIX
PART_SUFFIX=.$PART_SUFFIX
echo
break
fi
done
fi
#
if [ -n "$ROOT_DECRYPT" ]; then
[ -z "$slept" ] && $bb sleep 3
slept=y
while :; do
printf '. Please set free $PART_ROOT: '
$bb stty -echo
read ROOT_PASS
$bb stty echo
printf "%s" "$ROOT_PASS" | $cs open $PART_ROOT p_root --key-file - && break
xconfirm 'Cannot cryptsetup open '"$PART_ROOT"', try again' || x 1
done
$bb mount $ROOT_DECRYPT /dev/mapper/p_root mnt || x 2
if [ -n "$INIT_S2" ]; then
echo '. Going $INIT_S2='"$INIT_S2"
cd mnt || x 3
boot/$BB mount --bind ../dev dev || x 10
boot/$BB mount --bind ../sys sys || x 11
boot/$BB mount --bind ../proc proc || x 12
boot/$BB mount --bind ../run run || x 13
exec boot/$BB chroot . /boot/$BB sh \
/boot/linux-init-s2.sh --stage1 "$INIT_S2" \
"$PART_SUFFIX" "$PART_ROOT" \
"$ROOT_DECRYPT" "$ROOT_PASS" ||
x 'Cannot go $INIT_S2'
fi
else
echo '. Mounting $PART_ROOT'
$bb mount $PART_ROOT mnt || x 2
fi
xswap $bb $cs
echo '. About to pivot_root'
cd mnt || x 3
bb=boot/$bb
$bb pivot_root . $PIVOT_OLDROOT || x 4
$bb mount -o move $PIVOT_OLDROOT/dev dev || x 10
$bb mount -o move $PIVOT_OLDROOT/sys sys || x 11
$bb mount -o move $PIVOT_OLDROOT/proc proc || x 12
$bb mount -o move $PIVOT_OLDROOT/run run || x 13
echo '. Going sbin/init'
$bb stty isig
exec $bb chroot . sbin/init || x 'Cannot sbin/init'
} # }}}
if [ $# -ne 0 ]; then
. $($1 dirname "$0")/linux-init-lib.sh
xsetup "$1" "$2"
else
. $(./$BB dirname "$0")/linux-init-lib.sh
xroot
fi
exit 127
# s-sht-mode
[-- Attachment #3: linux-init-s2.sh --]
[-- Type: application/x-sh, Size: 7186 bytes --]
#@ /linux-init-s2.sh, simple Linux init, optional stage 2, called from stage 1.
#@ Requires $BB, $CS, as below, and these funs, on EFI / as well as new /boot/.
#@
#@ #@ For kent, stage 2
#@
#@ [KERNEL_ID=ideapad] - if set, only $KERNEL_ID-*.efi kernels are examined
#@ PART_ROOT=/dev/nvme0n1p8
#@ ROOT_DECRYPT='-t btrfs -o defaults,subvol=/crux-3.6/kent/root'
#@ PART_SWAP=/dev/nvme0n1p6
#@ INITRD_PATH=boot/.s2.initrd
#@ SWITCH_ROOT=media/initrd
#@
#@ Alternatively call AS ROOT and FROM WITHIN directory that boots like
#@ sh linux-init-s2.sh PATH_TO_BUSYBOX PATH_TO_CRYPTSETUP
#@ for init purposes.
# Identical to stage 1.
: ${MDEV_RUN:=}
#: ${PART_ROOT:=} via stage 1
#: ${ROOT_DECRYPT:=} via stage 1 (ditto ROOT_PASS)
: ${PART_SWAP:=}
: ${SWAP_INPUT:=}
# If non-empty, we try to load the given initrd (relative to root) instead of
# newly creating it; also, we will try to save it there if we had to create it
# Will get PART_SUFFIX of chosen PART_ROOT/ROOT_DECRYPT tuple!
: ${INITRD_PATH:=}
# Further arguments when kexec(8)ing the new kernel
: ${KEXEC_ARGS:=}
: ${KEXEC_EXE:=usr/sbin/kexec}
# Running in the kexec(8) kernel, we may apply some file comparisons.
# If set it is a list of space separated files which must exist in /boot as
# well as $FILE_CHECK_PARTITION (most likely the same as $SWITCH_ROOT), that is
# temporarily mounted if it is not yet.
# The files $BB, $CS, linux-init-{lib,s1}.sh are implied
: ${FILE_CHECK:=}
: ${FILE_CHECK_PARTITION:=media/efi}
: ${FILE_CHECK_MOUNT_ARGS:=-n -t vfat /dev/nvme0n1p1}
# Where we move old root to when doing switch_root(8)
: ${SWITCH_ROOT:=media/initrd}
BB=busybox.static
CS=cryptsetup.static
# -- >8 -- 8< --
xkexec() { # $1=config file; assumes we are in / and boot/ "has it" {{{
conf=$1
# Find the possible kernels to boot
set -- boot/*.efi
ki=1 kdef= knew=
for k
do
if [ -n "$KERNEL_ID" ]; then
[ "${k##*$KERNEL_ID-*.efi}" != "$k" ] || continue
fi
if [ "${k##*-new.efi}" = "$k" ] && [ "${k##*-old.efi}" = "$k" ] && [ "${k##*-stage1.efi}" = "$k" ]; then
#[ -z "$kdef" ] && kdef=$k
kdef=$k
fi
if [ -z "$knew" ] && [ "${k##*-new.efi}" != "$k" ]; then
knew=$k
fi
eval k$ki=$k
ki=$((ki + 1))
done
# Let user choose one
trap 'x "Got signal"' INT QUIT TERM
echo '+ trapping INT/QUIT/TERM to start a shell'
k= k0=-
while [ -z "$k" ]; do
echo
echo '. Available kernels:'
echo ' [0] Edit $KEXEC_ARGS'
kj=1
while [ $kj -lt $ki ]; do
eval echo "\" [$kj] \$k$kj\""
kj=$((kj + 1))
done
echo
if [ -n "$knew" ] && xconfirm 'Use the new kernel ('"$knew"')?'; then
k=$knew
else
kmsg= krt=
if [ -n "$kdef" ] && (echo y | read -t 1 chck) >/dev/null 2>&1; then
kmsg=' (10 seconds until, or empty input for '"$kdef"')'
krt='-t 10'
fi
printf '. Please choose kernel'"$kmsg"'? '
read $krt kx
if [ $? -ne 0 ] || [ -z "$kx" ]; then
echo
k=$kdef
elif [ "${kx##*[^0-9]}" != "$kx" ]; then
echo >&2 '! Invalid input'
continue
fi
eval k=\$k$kx
if [ -z "$k" ]; then
echo >&2 '! No such kernel'
elif [ "$k" = - ]; then
printf "%s\n" "$KEXEC_ARGS" > run/.kexec
echo '# Only first line counts. Care for quoting! :wq' run/.kexec
boot/$BB vi run/.kexec
k=$KEXEC_ARGS
read KEXEC_ARGS < run/.kexec
boot/$BB rm -f run/.kexec
xconfirm "New KEXEC_ARGS=$KEXEC_ARGS" || KEXEC_ARGS=$k
k=
fi
fi
done
# Create or reuse a temporary initrd that contains the password
if [ -n "$INITRD_PATH" ] && [ -f "$INITRD_PATH$PART_SUFFIX" ] &&
boot/$BB cp "$INITRD_PATH$PART_SUFFIX" run/.initrd; then
echo '. Reusing initrd '"$INITRD_PATH$PART_SUFFIX"
else
echo '. Creating initrd'
boot/$BB mount -o remount,exec run
(
set -e
boot/$BB mkdir run/x
cd run/x
( xsetup2 "../../boot/$BB" "../../boot/$CS" )
e=$?
[ $e -ne 0 ] && exit $e
./$BB mknod dev/console c 5 1 # redundant
echo "#!/$BB sh" > ./init
./$BB cat "$conf" >> ./init
echo "PART_ROOT='$PART_ROOT'" >> ./init
echo "ROOT_DECRYPT='$ROOT_DECRYPT'" >> ./init
echo "ROOT_PASS='$ROOT_PASS'" >> ./init
echo '. /linux-init-s2.sh' >> ./init
./$BB chmod 0755 ./init
{
# Microcode update must be uncompressed and first
[ -f ../../boot/early-ucode.cpio ] && ./$BB cat ../../boot/early-ucode.cpio
# Followed by (possibly compressed) normal initrd
./$BB find . | ./$BB cpio -H newc -o | ./$BB gzip -9 -n
} > ../.initrd
) || x 'Failed to create run/.initrd'
boot/$BB mount -o remount,noexec run
if [ -n "$INITRD_PATH" ]; then
echo '. Saving initrd to '"$INITRD_PATH$PART_SUFFIX"
boot/$BB cp run/.initrd "$INITRD_PATH$PART_SUFFIX"
boot/$BB chmod 0600 "$INITRD_PATH$PART_SUFFIX"
fi
fi
KEXEC_ARGS="$KEXEC_ARGS --initrd=run/.initrd"
echo ". $KEXEC_EXE -l $k $KEXEC_ARGS"
eval $KEXEC_EXE -l $k $KEXEC_ARGS || x 'Cannot invoke '"$KEXEC_EXE"' -l'
echo ". $KEXE_EXE -e"
exec $KEXEC_EXE -e || x 'Cannot invoke '"$KEXEC_EXE"' -e'
} # }}}
xfilecheck() { # $1=$BB; assumes we are in /mnt (_next_ root) {{{
[ -z "$FILE_CHECK" ] && return
echo '. Checking file equalities'
umountpart=
if xhavemnt "$1" "$FILE_CHECK_PARTITION"; then :; else
umountpart=y
$1 mount $FILE_CHECK_MOUNT_ARGS "$FILE_CHECK_PARTITION" || x 'Cannot mount '"$FILE_CHECK_PARTITION"
fi
err=
$1 cmp -s "$1" "$FILE_CHECK_PARTITION"/$BB || err="$BB"
$1 cmp -s boot/$CS "$FILE_CHECK_PARTITION"/$CS || err="$err $CS"
$1 cmp -s boot/linux-init-lib.sh "$FILE_CHECK_PARTITION"/linux-init-lib.sh || err="$err init-lib.sh"
$1 cmp -s boot/linux-init-s1.sh "$FILE_CHECK_PARTITION"/linux-init-s1.sh || err="$err init-s1.sh"
if [ -f boot/early-ucode.cpio ] && [ -f "$FILE_CHECK_PARTITION"/early-ucode.cpio ]; then
$1 cmp -s boot/early-ucode.cpio "$FILE_CHECK_PARTITION"/early-ucode.cpio || err="$err early-ucode.cpio"
fi
for f in $FILE_CHECK; do
if [ -f "boot/$f" ] && [ -f "$FILE_CHECK_PARTITION/$f" ]; then
$1 cmp -s "boot/$f" "$FILE_CHECK_PARTITION/$f" || err="$err $f"
else
err="$err (MISS: $f)"
fi
done
[ -n "$umountpart" ] && $1 umount "$FILE_CHECK_PARTITION"
if [ -z "$err" ]; then
echo ' . Files successfully checked'
else
echo >&2 '! BOOT: $FILE_CHECK errors: '$err
echo '! BOOT: $FILE_CHECK errors: '$err >> etc/motd
$1 sleep 10
fi
} # }}}
xroot() { # {{{
# On initrd rootfs
bb=./$BB cs=./$CS
xbase_mounts "$bb"
echo '. Setting free $PART_ROOT'
printf "%s" "$ROOT_PASS" | $cs open $PART_ROOT p_root --key-file - || x 'Cannot cryptsetup open '"$PART_ROOT"
$bb mount $ROOT_DECRYPT /dev/mapper/p_root mnt || x 2
bb=mnt/boot/$BB
cs=mnt/boot/$CS
xswap $bb $cs
cd mnt || x 3
bb=boot/$BB
cs=boot/$CS
xfilecheck $bb
echo '. Going switch_root sbin/init'
$bb stty isig
# -c dev/console
exec $bb switch_root . sbin/init 2>&1 || x 'Cannot switch_root'
} # }}}
if [ "$1" = --stage1 ]; then
cnf=$2
PART_SUFFIX=$3
PART_ROOT=$4
ROOT_DECRYPT=$5
ROOT_PASS=$6
[ -f "$cnf" ] || x 'Cannot find $INIT_S2: '"$cnf"
. "$cnf"
. /boot/linux-init-lib.sh
xkexec "$cnf"
elif [ $# -eq 2 ]; then
. $($1 dirname "$0")/linux-init-lib.sh
xsetup2 "$1" "$2" -
else
. /linux-init-lib.sh
xroot
fi
exit 127
# s-sht-mode
[-- Attachment #4: linux-init-lib.sh --]
[-- Type: application/x-sh, Size: 3646 bytes --]
#@ linux-init-lib.sh, helpers for simple init stage 1 and 2; will be sourced.
# misc {{{
x() {
echo >&2 'ERROR ('"$*"')! Going shell'
[ -x ./$BB ] && exec ./$BB sh
[ -x /$BB ] && exec /$BB sh
[ -x /boot/$BB ] && exec /boot/$BB sh
[ -x /bin/sh ] && exec /bin/sh
exit 100
}
xconfirm() {
printf -- '. '"$*"' [Yy/else]? '
read answer
case $answer in
[Yy]*) return 0;;
*) return 1;;
esac
}
_mpx= _mp=
xhavemnt() { # $1=$BB $2=file
if [ "$2" = dev ]; then
[ -e /dev/console ] && [ -e /dev/null ] && [ -e /dev/zero ]
return $?
elif [ "$2" = proc ]; then
[ -e /proc/1 ] && [ -e /proc/self ] && [ -e /proc/uptime ]
return $?
elif [ "$2" = sys ]; then
[ -e /sys/kernel ] && [ -e /sys/block ] && [ -e /sys/fs ]
return $?
fi
if [ -z "$_mpx" ]; then
_mpx=y
$1 mountpoint -q / >/dev/null 2>&1 && _mp=y
fi
if [ -n "$_mp" ]; then
$1 mountpoint -q "$2" >/dev/null 2>&1
return $?
elif [ -f /proc/mounts ]; then
$1 grep -q ' '"$2"' ' /proc/mounts >/dev/null 2>&1
return $?
fi
return 1
}
_xrand=
xrand() {
_xrand=$(( (($RANDOM << 20) | ($RANDOM << 10) | ($RANDOM % 0x3FF)) ^ \
(($RANDOM << 20) | ($RANDOM << 10) | ($RANDOM % 0x3FF))))
}
# }}}
xbase_mounts() { # {{{ $1=$BB [uses $MDEV_RUN; calls stty -isig]
echo '. Checking /{dev,sys,proc,run}'
xhavemnt $1 dev || $1 mount -n -t devtmpfs -o mode=0755,exec,nosuid,noatime none dev
xhavemnt $1 sys || $1 mount -n -t sysfs none sys
xhavemnt $1 proc || $1 mount -n -t proc none proc
xhavemnt $1 run || $1 mount -n -t tmpfs -o mode=0755,noexec,nosuid,nodev none run
#[ -e /sys/firmware/efi ] &&
#mount -t efivarfs efivarfs /sys/firmware/efi/efivars -o nosuid,nodev,noexec
$1 stty -isig
if [ -n "$MDEV_RUN" ]; then
echo '. About to run mdev -s, waiting for some more settlement'
$1 sleep 8
$1 mdev -s $MDEV_RUN
fi
} # }}}
xsetup_base() { # $1=$BB $2=$CS [$3=no mdev stuff if set] {{{
$1 cp -f "$1" ./$BB
./$BB chmod 0700 ./$BB
./$BB cp -f "$2" ./$CS
./$BB chmod 0700 ./$CS
./$BB cp -f "$0" .
./$BB cp -f $(./$BB dirname "$0")/linux-init-lib.sh ./linux-init-lib.sh
if [ $# -ne 3 ]; then
# Prepare for $MDEV_RUN, too!
./$BB mkdir etc bin dev mnt proc run sys $mdir
./$BB cp ./$BB bin/sh
./$BB chmod 0700 bin/sh
echo ".* 0:0 660 @/$BB sh /etc/mdev.sh" > etc/mdev.conf
./$BB cat > etc/mdev.sh <<-_EOT
#@ /etc/mdev.sh for ./mdev.conf
run() {
if [ "\$ACTION" = add ]; then
case "\$SUBSYSTEM" in
block) block;;
*) ;;
esac
fi
exit
}
block() {
[ -n "\$MDEV" ] || return
[ -d /dev/disk ] || /$BB mkdir -p /dev/disk/by-uuid
uuid=\$(/$BB blkid "\$MDEV" \| /$BB sed -Ee "s/.*UUID=\"([^\"]+)\".*/\1/")
[ -n "\$uuid" ] || return
/$BB ln -s ../../"\$MDEV" /dev/disk/by-uuid/"\$uuid"
}
run
_EOT
./$BB chmod 0700 etc/mdev.sh
fi
echo '! Plus kernel, init=SCRIPT, to be placed here'
}
xsetup() {
xsetup_base "$@"
exit
}
xsetup2() {
xsetup_base "$@"
# For $FILE_CHECK
./$BB cp -f $(./$BB dirname "$0")/linux-init-s1.sh ./linux-init-s1.sh
exit
} # }}}
xswap() { # $1=$BB $2=$CS {{{
[ -z "$PART_SWAP" ] && return
echo '. Encrypted swap'
rand=
if [ -n "$SWAP_INPUT" ]; then
echo ' ... please type a line of randoms'
$1 stty -echo >/dev/null 2>&1
read rand
$1 stty echo >/dev/null 2>&1
else
xrand
rand=$_xrand
fi
xrand
xr1=$_xrand
xrand
xr2=$_xrand
xrand
xr3=$_xrand
xrand
xr4=$_xrand
xrand
xr5=$_xrand
echo "$xr1$rand$xr2$xr3$rand$xr4$xr5" |
$2 open --type plain --cipher aes --key-size 256 --hash sha256 $PART_SWAP p_swap --key-file - &&
$1 mkswap /dev/mapper/p_swap
} # }}}
# s-sht-mode
next prev parent reply other threads:[~2023-09-10 1:23 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-04 14:44 [TUHS] " Norman Wilson
2023-09-04 14:55 ` [TUHS] " Vincenzo Nicosia
2023-09-04 17:20 ` Warner Losh
2023-09-04 19:05 ` Clem Cole
2023-09-05 17:03 ` Paul Winalski
2023-09-05 18:02 ` Clem Cole
2023-09-04 19:59 ` Theodore Ts'o
2023-09-04 23:51 ` Warner Losh
2023-09-04 17:18 ` Warner Losh
2023-09-04 22:10 ` Steffen Nurpmeso
2023-09-05 15:53 ` Steffen Nurpmeso
2023-09-06 17:50 ` Warner Losh
2023-09-07 0:11 ` Steffen Nurpmeso
2023-09-07 16:05 ` Warner Losh
2023-09-08 14:58 ` Theodore Ts'o
2023-09-08 13:56 ` Michael Kjörling
2023-09-08 23:38 ` Steffen Nurpmeso
2023-09-09 22:43 ` Steffen Nurpmeso [this message]
2023-09-11 4:10 ` Theodore Ts'o
2023-09-11 22:05 ` Steffen Nurpmeso
2023-09-05 1:07 ` Jonathan Gray
-- strict thread matches above, loose matches on Subject: below --
2023-09-04 9:57 [TUHS] " Paul Ruizendaal via TUHS
2023-09-04 14:53 ` [TUHS] " emanuel stiebler
2023-09-04 17:07 ` Warner Losh
2023-09-04 18:21 ` Dan Cross
2023-09-05 11:15 ` Paul Ruizendaal via TUHS
2023-09-05 14:15 ` Clem Cole
2023-09-05 17:03 ` Warner Losh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230909224312.gGToQ%steffen@sdaoden.eu \
--to=steffen@sdaoden.eu \
--cc=e5655f30a07f@ewoof.net \
--cc=tuhs@tuhs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).