#!/bin/bash
# Probe-Boot mit Rückfall (bashclub-be reboot, bashclub-os #11), Phase
# boot-sel: Hat early-setup einen Versuch eröffnet und ist das alte BE
# (bootfs) gewählt, startet dieser Hook stattdessen einmal das neue BE per
# kexec. Scheitert das, kehrt er zurück und ZFSBootMenu startet das alte BE.
#
# Kernel-Zeile des neuen BE für diesen einen Start ergänzt um:
#   panic=10                 Kernel-Panic → Neustart → Rückfall
#   modprobe.blacklist=<wd>  der Watchdog-Treiber hielte beim Laden den
#                            scharfgeschalteten Timer an; bashclub-be confirm
#   bashclub.probe_wd=<wd>   lädt ihn nach erfolgreichem Start
#   bashclub.probe=1
f=/run/bashclub-probe
[ -f "$f" ] || exit 0
IFS='|' read -r new old <"$f"
# Nur einmal, und nur wenn bootfs (das alte BE) gestartet würde: von Hand
# gewählte BEs und der Aufruf aus kexec_kernel unten bleiben unberührt
[ "$ZBM_SELECTED_BE" = "$old" ] || exit 0
rm -f "$f"
for src in /lib/profiling-lib.sh /etc/zfsbootmenu.conf /lib/kmsg-log-lib.sh /lib/zfsbootmenu-kcl.sh /lib/zfsbootmenu-core.sh; do
	# shellcheck disable=SC1090
	source "$src" >/dev/null 2>&1 || exit 0
done
echo "<4>bashclub-probe: starte $new statt $old" >/dev/kmsg
find_be_kernels "$new" >/dev/null 2>&1
sel="$(select_kernel "$new")" || { echo "<3>bashclub-probe: kein Kernel in $new" >/dev/kmsg; exit 0; }
# Watchdog-Treiber = Module, die das Kernmodul „watchdog“ nutzen (i6300esb
# registriert sich ohne Elterngerät, sysfs hilft dort nicht)
wd=$(awk '$1 == "watchdog" { sub(/,$/, "", $4); if ($4 != "-") print $4 }' /proc/modules)
kcl="$(load_be_cmdline "$new") panic=10 bashclub.probe=1${wd:+ modprobe.blacklist=$wd bashclub.probe_wd=$wd}"
echo "$kcl" | kcl_tokenize >"${BASE}/cmdline"
kexec_kernel "$sel"
rm -f "${BASE}/cmdline"
echo "<3>bashclub-probe: kexec von $new gescheitert, starte $old" >/dev/kmsg
exit 0
