Kdump service runs too late, so early crashes will have no chance
to get kdump kernel booting. A proposal is add a dracut module to
load pre-built kernel/initramfs for early kdump, one can provide
"rd.early-kdump" in grub commandline to enable, then the service
can load those files like original kdump, which is disabled by
default.
For the formal kdump service in real root init path, it can check
if the pre-built kernel/initramfs has been loaded. It has no
conflict with the early kdump, but the early kdump must work in
hostonly mode.
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
dracut-early-kdump-module-setup.sh | 17 ++++++
dracut-early-kdump.service | 26 ++++++++++
dracut-early-kdump.sh | 103 +++++++++++++++++++++++++++++++++++++
kexec-tools.spec | 10 ++++
4 files changed, 156 insertions(+)
create mode 100755 dracut-early-kdump-module-setup.sh
create mode 100644 dracut-early-kdump.service
create mode 100755 dracut-early-kdump.sh
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh
new file mode 100755
index 0000000..18099e9
--- /dev/null
+++ b/dracut-early-kdump-module-setup.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+#the function should only return 0 in hostonly mode
+check() {
+ return 0
+}
+
+depends() {
+ return 0
+}
+
+install() {
+ inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
+ inst_script "$moddir/early-kdump.sh" "/usr/bin/early-kdump"
+ inst_simple "$moddir/early-kdump.service"
"${systemdsystemunitdir}/early-kdump.service"
+ ln_r "${systemdsystemunitdir}/early-kdump.service"
"${systemdsystemunitdir}/initrd.target.wants/early-kdump.service"
+}
diff --git a/dracut-early-kdump.service b/dracut-early-kdump.service
new file mode 100644
index 0000000..ba927bf
--- /dev/null
+++ b/dracut-early-kdump.service
@@ -0,0 +1,26 @@
+# 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.
+
+# See systemd.special(7) for details
+
+[Unit]
+Description=early kdump
+DefaultDependencies=yes
+After=local-fs.target
+Before=initrd-fs.target
+Wants=initrd-root-device.target sysroot.mount initrd-root-fs.target
initrd-parse-etc.service
+
+[Service]
+Environment=DRACUT_SYSTEMD=1
+Type=oneshot
+ExecStart=/bin/early-kdump
+KillMode=process
+
+#Bash ignore SIGTERM, so we send SIGHUP instead, to ensure that bash
+#terminates cleanly.
+KillSignal=SIGHUP
+
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh
new file mode 100755
index 0000000..935f2a1
--- /dev/null
+++ b/dracut-early-kdump.sh
@@ -0,0 +1,103 @@
+#! /bin/sh
+
+KEXEC=/sbin/kexec
+standard_kexec_args="-p"
+
+#source lib and configure
+. /lib/dracut-lib.sh
+. /etc/sysconfig/kdump
+
+is_atomic()
+{
+ grep -q "ostree" /proc/cmdline
+}
+
+if [ -z "$KDUMP_BOOTDIR" ]; then
+ if ! is_atomic || [ "$(uname -m)" = "s390x" ]; then
+ KDUMP_BOOTDIR="/boot"
+ else
+ eval $(cat /proc/cmdline | grep "BOOT_IMAGE" | cut -d' ' -f1)
+ KDUMP_BOOTDIR="/boot"$(dirname $BOOT_IMAGE)
+ fi
+fi
+
+EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`kdump.img"
+EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-`uname -r`${KDUMP_IMG_EXT}"
+EARLY_KDUMP_CMDLINE=`cat /proc/cmdline | sed -e 's/crashkernel=[^ ]*//'`
+EARLY_KDUMP_CMDLINE="${EARLY_KDUMP_CMDLINE} ${KDUMP_COMMANDLINE_APPEND}"
+
+
+check_crash_mem_reserved()
+{
+ local mem_reserved
+
+ mem_reserved=$(cat /sys/kernel/kexec_crash_size)
+ if [ $mem_reserved -eq 0 ]; then
+ echo "No memory reserved for crash kernel"
+ return 1
+ fi
+
+ return 0
+}
+
+check_kdump_feasibility()
+{
+ if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
+ echo "Kdump is not supported on this kernel"
+ return 1
+ fi
+ check_crash_mem_reserved
+ return $?
+}
+
+check_earlykdump_loaded()
+{
+ local early_kdump_loaded
+ early_kdump_loaded=$(cat /sys/kernel/kexec_crash_loaded)
+ if [ $early_kdump_loaded -eq 0 ]; then
+ return 0
+ fi
+
+ return 1
+}
+
+early_kdump_load()
+{
+ check_kdump_feasibility
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ check_earlykdump_loaded
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ $KEXEC $standard_kexec_args \
+ --command-line="$EARLY_KDUMP_CMDLINE" \
+ --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL
+
+ if [ $? == 0 ]; then
+ echo "kexec: loaded early-kdump kernel"
+ return 0
+ else
+ echo "kexec: failed to load early-kdump kernel"
+ return 1
+ fi
+
+}
+
+setearlykdump()
+{
+ if getargbool 0 rd.early-kdump; then
+ echo "early-kdump is enabled."
+ early_kdump_load
+ else
+ echo "early-kdump is not enabled by default."
+ fi
+
+ return 0
+}
+
+setearlykdump
+
diff --git a/kexec-tools.spec b/kexec-tools.spec
index f04527c..61429a4 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -42,6 +42,9 @@ Source104: dracut-kdump-emergency.service
Source105: dracut-kdump-error-handler.service
Source106: dracut-kdump-capture.service
Source107: dracut-kdump-emergency.target
+Source108: dracut-early-kdump.sh
+Source109: dracut-early-kdump.service
+Source110: dracut-early-kdump-module-setup.sh
Requires(post): systemd-units
Requires(preun): systemd-units
@@ -194,6 +197,7 @@ make -C kdump-anaconda-addon install DESTDIR=$RPM_BUILD_ROOT
%find_lang kdump-anaconda-addon
%define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g')
+%define remove_dracut_early_kdump_prefix() %(echo -n %1|sed
's/.*dracut-early-kdump-//g')
# deal with dracut modules
mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase
@@ -207,6 +211,12 @@ cp %{SOURCE106}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpb
cp %{SOURCE107}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE107}}
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}}
+mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump
+cp %{SOURCE108}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix
%{SOURCE108}}
+cp %{SOURCE109}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix
%{SOURCE109}}
+cp %{SOURCE110}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix
%{SOURCE110}}
+chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix
%{SOURCE108}}
+chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix
%{SOURCE110}}
%define dracutlibdir %{_prefix}/lib/dracut
--
2.9.5