diff --git a/dracut-kdump-emergency.service b/dracut-kdump-emergency.service new file mode 100644 index 0000000..a64610c --- /dev/null +++ b/dracut-kdump-emergency.service @@ -0,0 +1,27 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This service will be placed in kdump initramfs and replace both the systemd +# emergency service and dracut emergency shell. IOW, any emergency will be +# kick this service and in turn isolating to kdump error handler. + +[Unit] +Description=Kdump Emergency +DefaultDependencies=no + +[Service] +ExecStart=systemctl --no-block isolate kdump-error-handler.service +Type=oneshot +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/dracut-kdump-error-handler.service b/dracut-kdump-error-handler.service new file mode 100644 index 0000000..13090be --- /dev/null +++ b/dracut-kdump-error-handler.service @@ -0,0 +1,34 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# This service will run the real kdump error handler code. Executing the +# default action configured in kdump.conf + +[Unit] +Description=Kdump Error Handler +DefaultDependencies=no +After=systemd-vconsole-setup.service +Wants=systemd-vconsole-setup.service +AllowIsolate=yes + +[Service] +Environment=HOME=/ +Environment=DRACUT_SYSTEMD=1 +Environment=NEWROOT=/sysroot +WorkingDirectory=/ +ExecStart=/bin/kdump-error-handler.sh +ExecStopPost=-/usr/bin/systemctl --fail --no-block default +Type=oneshot +StandardInput=tty-force +StandardOutput=inherit +StandardError=inherit +KillMode=process +IgnoreSIGPIPE=no + +# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash +# terminates cleanly. +KillSignal=SIGHUP diff --git a/dracut-kdump-error-handler.sh b/dracut-kdump-error-handler.sh new file mode 100755 index 0000000..2f0f1d1 --- /dev/null +++ b/dracut-kdump-error-handler.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. /lib/kdump-lib-initramfs.sh + +set -o pipefail +export PATH=$PATH:$KDUMP_SCRIPT_DIR + +get_kdump_confs +do_default_action +do_final_action diff --git a/dracut-kdump.sh b/dracut-kdump.sh index a2bfa05..83c1e96 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -9,10 +9,6 @@ exec &> /dev/console . /lib/dracut-lib.sh . /lib/kdump-lib-initramfs.sh -if [ -f "$initdir/lib/dracut/no-emergency-shell" ]; then - rm -f -- $initdir/lib/dracut/no-emergency-shell -fi - set -o pipefail DUMP_RETVAL=0 diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 758420b..9e73f53 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -563,7 +563,6 @@ kdump_install_random_seed() { install() { kdump_install_conf - >"$initdir/lib/dracut/no-emergency-shell" if is_ssh_dump_target; then kdump_install_random_seed @@ -581,6 +580,12 @@ install() { inst_hook pre-pivot 9999 "$moddir/kdump.sh" inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh" + inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh" + inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service" + # Replace existing emergency service + cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service" + # Also redirect dracut-emergency to kdump error handler + ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service" # Check for all the devices and if any device is iscsi, bring up iscsi # target. Ideally all this should be pushed into dracut iscsi module diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index 9118b64..1517712 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -1,6 +1,5 @@ # These variables and functions are useful in 2nd kernel -. /lib/dracut-lib.sh . /lib/kdump-lib.sh KDUMP_PATH="/var/crash" @@ -23,6 +22,7 @@ NEWROOT="/sysroot" get_kdump_confs() { local config_opt config_val + local user_specified_cc while read config_opt config_val; do @@ -34,6 +34,7 @@ get_kdump_confs() ;; core_collector) [ -n "$config_val" ] && CORE_COLLECTOR="$config_val" + user_specified_cc=yes ;; sshkey) if [ -f "$config_val" ]; then @@ -55,7 +56,7 @@ get_kdump_confs() default) case $config_val in shell) - DEFAULT_ACTION="_emergency_shell kdump" + DEFAULT_ACTION="kdump_emergency_shell" ;; reboot) DEFAULT_ACTION="do_umount; reboot -f" @@ -67,12 +68,19 @@ get_kdump_confs() DEFAULT_ACTION="do_umount; poweroff -f" ;; dump_to_rootfs) - DEFAULT_ACTION="dump_fs $NEWROOT" + DEFAULT_ACTION="dump_to_rootfs" ;; esac ;; esac done < $KDUMP_CONF + + if is_ssh_dump_target || is_raw_dump_target; then + if [ -z "$user_specified_cc" ]; then + CORE_COLLECTOR="$CORE_COLLECTOR -F" + fi + fi + } # dump_fs @@ -127,6 +135,24 @@ save_vmcore_dmesg_fs() { fi } +dump_to_rootfs() +{ + + echo "Kdump: trying to bring up rootfs device" + systemctl start dracut-initqueue + echo "Kdump: waiting for rootfs mount, will timeout after 90 seconds" + systemctl start sysroot.mount + + dump_fs $NEWROOT +} + +kdump_emergency_shell() +{ + echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile + /bin/dracut-emergency + rm -f /etc/profile +} + do_umount() { umount -Rf $NEWROOT @@ -134,7 +160,7 @@ do_umount() do_default_action() { - wait_for_loginit + echo "Kdump: Executing default action $DEFAULT_ACTION" eval $DEFAULT_ACTION } diff --git a/kexec-tools.spec b/kexec-tools.spec index b55a7f1..7d64852 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -36,6 +36,9 @@ Source24: kdump-lib-initramfs.sh Source100: dracut-kdump.sh Source101: dracut-module-setup.sh Source102: dracut-monitor_dd_progress +Source103: dracut-kdump-error-handler.sh +Source104: dracut-kdump-emergency.service +Source105: dracut-kdump-error-handler.service Requires(post): systemd-units Requires(preun): systemd-units @@ -210,7 +213,9 @@ mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpba cp %{SOURCE100} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}} cp %{SOURCE101} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}} cp %{SOURCE102} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE102}} - +cp %{SOURCE103} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE103}} +cp %{SOURCE104} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE104}} +cp %{SOURCE105} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE105}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}}