--- /dev/null
+#!/bin/bash
+
+set -eE -o pipefail
+trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?" >&2' ERR
+
+#set -x
+
+usage() {
+ cat <<EOF
+Usage: ${0##*/} [OPTION] [HOST]
+If grub var set, act like pxe rom and pxe-kexec to faiserver
+
+-f|--force do kexec if we can reach faiserver
+-h|--help Print help and exit.
+
+Note: Uses GNU getopt options parsing style
+EOF
+ exit $1
+}
+
+
+
+# Keep it short so we don't delay too much wnen we don't have networking.
+# In practice, on my home network, on an x200, it took 15 seconds, so
+# give it an extra 10 seconds, which seems fairly short as I write this.
+NETWORK_TIMOUT_SECS=25
+did_fai_check=false
+
+m() { printf "%s\n" "$*"; "$@"; }
+
+try-kexec() {
+ deadline=$(( `date +%s` + NETWORK_TIMOUT_SECS ))
+ while ! timeout -s 9 3 nc -zu $faiserver 69; do
+ if (( `date +%s` > deadline )); then
+ echo "fai-check: hit $NETWORK_TIMOUT_SECS s tftp server timeout"
+ return 0
+ fi
+ sleep 1
+ done
+ m pxe-kexec -n --ignore-whitelist -l fai-generated $faiserver ||:
+}
+
+force=false
+case $1 in
+ -h|--help)
+ usage
+ ;;
+ -f|--force)
+ force=true
+ shift
+ ;;
+esac
+
+faiserver=${1:-faiserver.b8.nz}
+
+
+if $force; then
+ try-kexec
+ exit
+fi
+
+# on one machine, I could do this:
+# dmidecode -t system | grep -F "Version: ThinkPad X200"
+# however, on another, the version field just says invalid data.
+# todo: figure out some better way to check if we are on
+# an x200.
+
+if ! dmidecode | grep -i thinkpad &>/dev/null; then
+ echo "not x200, exiting"
+ exit 0
+fi
+
+first=true
+for dev in $(btrfs fi show / | sed -rn 's#^\s*devid\s.*\s([^0-9 ]+)\S+$#\1#p' \
+ |sort); do
+ echo dev=$dev
+ found=false
+ # Decide which is my grub_ext partition. see partition.DEFAULT file
+ # for details. currently it is 4
+ for (( i=4; i<=7; i++ )); do
+ if [[ $(blockdev --getsize64 ${dev}$i) == 8388608 ]]; then
+ grub_extn=${dev}$i
+ found=true
+ echo grub_extn=$grub_extn
+ break
+ fi
+ done
+ if ! $found; then
+ echo "$0: error: failed to find grub_ext partition."
+ exit 1
+ fi
+ m mount $grub_extn /mnt
+ if $first; then
+ if [[ -e /mnt/grubenv ]]; then
+ m grub-editenv /mnt/grubenv list
+ source <(grub-editenv /mnt/grubenv list)
+ fi
+ first=false
+ # we could just as well check if last_boot != /debianbullseye_bootstrap
+ # the intent with this one is just a little clearer.
+ if [[ $did_fai_check == true ]]; then
+ m grub-editenv /mnt/grubenv set did_fai_check=os_true
+ # our service does not wait for network-online.target,
+ # because it will wait for too long when we don't have a network
+ # connection. So, we wait for 10 seconds.
+ # ref: https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
+ try-kexec ||:
+ fi
+ else
+ # we make sure there is only 1 grubenv,
+ # so grub can just find the first one, in whatever order
+ # if looks at them, which may not be the same as us.
+ # If the disk dies, we just lose the default boot option,
+ # we will have to do manual steps to replace it anyways.
+ m rm -f /mnt/gruvenv
+ fi
+ m umount /mnt
+done
+
+# the check for last_boot is not needed afaik, just sanity check.
+case $did_fai_check in
+ true|os_true)
+ if [[ $last_boot != /debian*_bootstrap ]]; then
+ # no need to reboot if we actually want to boot into this os.
+ echo "last_boot=$last_boot not debian*_bootstrap, rebooting"
+ reboot
+ fi
+esac