aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'defaults/linuxrc')
-rw-r--r--defaults/linuxrc73
1 files changed, 51 insertions, 22 deletions
diff --git a/defaults/linuxrc b/defaults/linuxrc
index 8356aea..ebed7d8 100644
--- a/defaults/linuxrc
+++ b/defaults/linuxrc
@@ -289,6 +289,24 @@ do
fi
unset tmp_disabled
;;
+ gk.emergency=*)
+ tmp_action=${x#*=}
+ case "${tmp_action}" in
+ reboot)
+ GK_EMERGENCY_ACTION="reboot -f"
+ ;;
+ poweroff)
+ GK_EMERGENCY_ACTION="poweroff -f"
+ ;;
+ halt)
+ GK_EMERGENCY_ACTION="halt -f"
+ ;;
+ *)
+ warn_msg "'${x}' is an unsupported emergency action -- ignored!"
+ ;;
+ esac
+ unset tmp_action
+ ;;
gk.hw.load-all=*)
tmp_disabled=${x#*=}
if is_true "${tmp_disabled}"
@@ -1341,28 +1359,39 @@ fi
# init_opts is set in the environment by the kernel when it parses the command line
init=${REAL_INIT:-/sbin/init}
-if ! mountpoint "${CHROOT}" 1>/dev/null 2>&1
-then
- bad_msg "${CHROOT} was not a mountpoint"
-elif chroot "${CHROOT}" test ! -x /${init#/}
-then
- bad_msg "init=${init} does not exist in the rootfs!"
-elif [ $$ != 1 ]
-then
- bad_msg "PID was not 1! switch_root would fail"
-else
- good_msg "Switching to real root: switch_root ${CHROOT} ${init} ${init_opts}"
- exec switch_root "${CHROOT}" "${init}" ${init_opts}
-fi
-# If we get here, something bad has happened
-splash 'verbose'
+while true
+do
+ # switch_root can only be called from PID 1;
+ # So stay in loop as long as user is able
+ # to fix the problem.
-bad_msg "A fatal error has occured since ${init} did not"
-bad_msg "boot correctly. Trying to open a shell ..."
+ if ! mountpoint "${CHROOT}" 1>/dev/null 2>&1
+ then
+ bad_msg "${CHROOT} is not a mountpoint; Was root device (${REAL_ROOT}) not mounted?"
+ elif ! chroot "${CHROOT}" test -x /${init#/} 1>/dev/null 2>&1
+ then
+ mounted_root_device=$(mountpoint -n /newroot 2>/dev/null | awk '{ print $1 }')
+ bad_msg "init (${init}) not found in mounted root device (${mounted_root_device})!"
+ else
+ break
+ fi
+
+ run_emergency_shell
+ if ! is_userinteraction_allowed
+ then
+ ${GK_EMERGENCY_ACTION} || exit 1
+ fi
+done
-exec /bin/bash
-exec /bin/sh
-exec /bin/ash
-exec /bin/dash
-exec sh
+good_msg "Switching to real root: switch_root ${CHROOT} ${init} ${init_opts}"
+exec switch_root "${CHROOT}" "${init}" ${init_opts}
+
+# If we reached here, something went very badly wrong in the initramfs.
+# However, spawning a rescue shell at this point would not help anymore:
+# 1) We have to assume that switch_root has already messed with
+# initramfs (i.e. we probably have no /dev anymore).
+# 2) Any shell we would spawn would become child of PID 1 which would
+# prevent user from calling switch_root once the user believes the
+# problem was fixed.
+${GK_EMERGENCY_ACTION} || exit 1