From 0897a20b845c387d8c297bf2d006568f2ca88db9 Mon Sep 17 00:00:00 2001 From: Francis Lam Date: Sat, 22 Jul 2017 14:57:46 -0400 Subject: [PATCH] Ensure recovery for failed default boot Should close #223 Added reboot and poweroff scripts using /proc/sysrq-trigger Also cleaned up the boot loop in generic-init --- initrd/bin/generic-init | 9 ++++++--- initrd/bin/kexec-select-boot | 28 +++++++++++++++++----------- initrd/bin/poweroff | 10 ++++++++++ initrd/bin/reboot | 10 ++++++++++ 4 files changed, 43 insertions(+), 14 deletions(-) create mode 100755 initrd/bin/poweroff create mode 100755 initrd/bin/reboot diff --git a/initrd/bin/generic-init b/initrd/bin/generic-init index aae646c7..c0808e48 100755 --- a/initrd/bin/generic-init +++ b/initrd/bin/generic-init @@ -30,7 +30,7 @@ while true; do recovery "User requested recovery shell" fi - if [ "$totp_confim" = "n" ]; then + if [ "$totp_confirm" = "n" ]; then echo "" echo "To correct clock drift: 'date -s HH:MM:SS'" echo "and save it to the RTC: 'hwclock -w'" @@ -41,18 +41,21 @@ while true; do if [ "$totp_confirm" = "u" ]; then exec /bin/usb-init + continue fi if [ "$totp_confirm" = "m" ]; then # Try to select a kernel from the menu mount_boot kexec-select-boot -m -b /boot -c "grub.cfg" + continue fi - if [ "$totp_confirm" = "y" -o "$totp_confirm" != " " ]; then + if [ "$totp_confirm" = "y" -o -n "$totp_confirm" ]; then # Try to boot the default mount_boot - kexec-select-boot -b /boot -c "grub.cfg" + kexec-select-boot -b /boot -c "grub.cfg" \ + || recovery "Failed default boot" fi done diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 52114bca..034890bb 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -11,6 +11,7 @@ unique="n" valid_hash="n" valid_global_hash="n" valid_rollback="n" +force_menu="n" while getopts "b:d:p:a:r:c:uim" arg; do case $arg in b) bootdir="$OPTARG" ;; @@ -20,7 +21,7 @@ while getopts "b:d:p:a:r:c:uim" arg; do r) remove="$OPTARG" ;; c) config="$OPTARG" ;; u) unique="y" ;; - m) show_menu="y" ;; + m) force_menu="y" ;; i) valid_hash="y"; valid_rollback="y" ;; esac done @@ -153,6 +154,7 @@ save_default_option() { echo "+++ Saved defaults to device" sleep 2 default_failed="n" + force_menu="n" return else echo "Failed to save defaults" @@ -172,9 +174,7 @@ default_select() { expectedoption=`cat $TMP_DEFAULT_FILE` option=`head -n $default_index $TMP_MENU_FILE | tail -1` if [ "$option" != "$expectedoption" ]; then - warn "!!! Boot entry has changed - please set a new default" - sleep 5 - return + die "!!! Boot entry has changed - please set a new default" fi parse_option @@ -185,7 +185,7 @@ default_select() { echo "+++ Verified default boot hashes " valid_hash='y' else - die "$TMP_DEFAULT_HASH_FILE: default boot hash mismatch" + die "!!! $TMP_DEFAULT_HASH_FILE: default boot hash mismatch" fi echo "+++ Executing default boot for $name:" @@ -208,8 +208,15 @@ user_select() { done if [ "$option_confirm" = "d" ]; then - # reload settings to reflect new default - continue + if [ ! -r "$TMP_KEY_DEVICES" ]; then + # rerun primary boot loop to boot the new default option + continue + else + echo "+++ Rebooting to start the new default option" + sleep 2 + reboot \ + || die "!!! Failed to reboot system" + fi fi do_boot @@ -218,13 +225,11 @@ user_select() { do_boot() { if [ "$CONFIG_BOOT_REQ_ROLLBACK" = "y" -a "$valid_rollback" = "n" ]; then - warn "!!! Missing required rollback counter state" - return + die "!!! Missing required rollback counter state" fi if [ "$CONFIG_BOOT_REQ_HASH" = "y" -a "$valid_hash" = "n" ]; then - warn "!!! Missing required boot hashes" - return + die "!!! Missing required boot hashes" fi if [ -r "$TMP_KEY_DEVICES" ]; then @@ -286,6 +291,7 @@ while true; do fi if [ "$default_failed" != "y" \ + -a "$force_menu" = "n" \ -a -r "$TMP_DEFAULT_FILE" \ -a -r "$TMP_DEFAULT_HASH_FILE" ] \ ; then diff --git a/initrd/bin/poweroff b/initrd/bin/poweroff new file mode 100755 index 00000000..f7a0b123 --- /dev/null +++ b/initrd/bin/poweroff @@ -0,0 +1,10 @@ +#!/bin/sh + +# Sync all mounted filesystems +echo s > /proc/sysrq-trigger + +# Remount all mounted filesystems in read-only mode +echo u > /proc/sysrq-trigger + +# Shut off the system +echo o > /proc/sysrq-trigger diff --git a/initrd/bin/reboot b/initrd/bin/reboot new file mode 100755 index 00000000..aab0fd7d --- /dev/null +++ b/initrd/bin/reboot @@ -0,0 +1,10 @@ +#!/bin/sh + +# Sync all mounted filesystems +echo s > /proc/sysrq-trigger + +# Remount all mounted filesystems in read-only mode +echo u > /proc/sysrq-trigger + +# Immediately reboot the system, without unmounting or syncing filesystems +echo b > /proc/sysrq-trigger