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@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
I remember Kazuhito had similar idea about this, add him in CC. Also we may need consider some effects to fadump as well. Ccing Hari.
On 03/05/18 at 03:05pm, Lianbo Jiang wrote:
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@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 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org
Also cc Harald.
Still not sure if this can go dracut upstream, maybe stay in kexec-tools for the time being. But if we can remove distribution specific issue it will be doable?
On 03/05/18 at 03:56pm, Dave Young wrote:
I remember Kazuhito had similar idea about this, add him in CC. Also we may need consider some effects to fadump as well. Ccing Hari.
On 03/05/18 at 03:05pm, Lianbo Jiang wrote:
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.
It may be good to have a documentation about this for example: early-kdump.txt
This may assumed /boot/ being used, and dracut only bring up /boot when hostonly mode is used. If kdump BOOTDIR is different place then it would be good to add them with "--mount". Maybe always use "--mount" and do not depend on "hostonly"
Signed-off-by: Lianbo Jiang lijiang@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
+}
Should depend on "kexec" which is in shutdown module?
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
Since it uses the config file, it will be distribution dependent module. But it should be fine and as a minimum requirement for some basic variables eg. KDUMP_BOOTDIR.
- 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
This should not depend on root?
+[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 $?
+}
Shared functions to kdumpctl can be moved to kdump-lib.sh
+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
+}
Dracut internal module param documented in dracut.cmdline manpage, Maybe we can add a man page for early kdump specific before this is upstream dracut ready.
+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 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org
Thanks Dave
Thanks Dave, I will modify those problems and update documents according to your advice.
In addition, maybe we should also consider how to deal with the situation on i386/i686.
By the way, the following method will generate initramfs for early-kdump:
#dracut -H --mount /boot -v /boot/initramfs-`uname -r`.img --force
Lianbo 在 2018年03月05日 17:16, Dave Young 写道:
Also cc Harald.
Still not sure if this can go dracut upstream, maybe stay in kexec-tools for the time being. But if we can remove distribution specific issue it will be doable?
On 03/05/18 at 03:56pm, Dave Young wrote:
I remember Kazuhito had similar idea about this, add him in CC. Also we may need consider some effects to fadump as well. Ccing Hari.
On 03/05/18 at 03:05pm, Lianbo Jiang wrote:
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.
It may be good to have a documentation about this for example: early-kdump.txt
This may assumed /boot/ being used, and dracut only bring up /boot when hostonly mode is used. If kdump BOOTDIR is different place then it would be good to add them with "--mount". Maybe always use "--mount" and do not depend on "hostonly"
Signed-off-by: Lianbo Jiang lijiang@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
+}
Should depend on "kexec" which is in shutdown module?
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
Since it uses the config file, it will be distribution dependent module. But it should be fine and as a minimum requirement for some basic variables eg. KDUMP_BOOTDIR.
- 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
This should not depend on root?
+[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 $?
+}
Shared functions to kdumpctl can be moved to kdump-lib.sh
+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
+}
Dracut internal module param documented in dracut.cmdline manpage, Maybe we can add a man page for early kdump specific before this is upstream dracut ready.
+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 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org
Thanks Dave
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Signed-off-by: Lianbo Jiang lijiang@redhat.com --- dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +check() { + if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ] + then + return 1 + fi + return 0 +} + +depends() { + echo "base shutdown" + return 0 +} + +install() { + inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump" + inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec" + inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" + 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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 + +[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh + +KEXEC=/sbin/kexec +standard_kexec_args="-p" + +EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS="" + +#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump + +prepare_parameters() +{ + local cmdline id + + if [ -z "$EARLY_KDUMP_CMDLINE" ]; then + cmdline=$(cat /proc/cmdline) + else + cmdline=${EARLY_KDUMP_CMDLINE} + fi + + cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn) + cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE}) + + # Always remove "root=X", as we now explicitly generate all kinds + # of dump target mount information including root fs. + # + # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares + # about it(e.g. for debug purpose), then can pass "root=X" using + # KDUMP_COMMANDLINE_APPEND. + cmdline=$(remove_cmdline_param "$cmdline" root) + + # With the help of "--hostonly-cmdline", we can avoid some interitage. + cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe) + cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}" + id=$(get_bootcpu_apicid) + if [ ! -z ${id} ] ; then + cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id}) + fi + EARLY_KDUMP_CMDLINE=$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 + + #make early-kdump kernel string + if [ -z "$EARLY_KDUMP_KERNELVER" ]; then + EARLY_KDUMP_KERNELVER=`uname -r` + fi + EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}" + + #make early-kdump initrd string + EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img" +} + +early_kdump_load() +{ + check_kdump_feasibility + if [ $? -ne 0 ]; then + return 1 + fi + + if is_fadump_capable; then + echo "early kdump doesn't support fadump: [WARNING]" + return 1 + fi + + check_current_kdump_status + if [ $? == 0 ]; then + return 1 + fi + + prepare_parameters + + ARCH=`uname -m` + if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ] + then + need_64bit_headers + if [ $? == 1 ] + then + FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers` + if [ -n "$FOUND_ELF_ARGS" ] + then + echo -n "Warning: elf32-core-headers overrides correct elf64 setting" + echo + else + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers" + fi + else + FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers` + if [ -z "$FOUND_ELF_ARGS" ] + then + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers" + fi + fi + fi + + #secure boot + if is_secure_boot_enforced; then + echo "Secure Boot is enabled. Using kexec file based syscall." + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" + fi + + $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO + +Introduction + +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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump. + +How to configure early kdump: + +We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command: + + # yum install kexec-tools + +For early kdump, you should rebuild the initramfs like this: + # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force + +Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above. + +Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this: + + # journalctl -x|grep early-kdump + +Then, you will see some useful logs, for exapmles: + +1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel + +2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default. + +Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on. + +In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 } + +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_current_kdump_status() +{ + if [ ! -f /sys/kernel/kexec_crash_loaded ];then + echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" + return 1 + fi + + rc=`cat /sys/kernel/kexec_crash_loaded` + if [ $rc == 1 ]; then + return 0 + else + return 1 + fi +} + +# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{ + local cmdline=$1 + shift + + for arg in $@; do + cmdline=`echo $cmdline | \ + sed -e "s/\b$arg=[^ ]*//g" \ + -e "s/^$arg\b//g" \ + -e "s/[[:space:]]$arg\b//g" \ + -e "s/\s+/ /g"` + done + echo $cmdline +} + +# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{ + awk ' \ + BEGIN { CPU = "-1"; } \ + $1=="processor" && $2==":" { CPU = $NF; } \ + CPU=="0" && /^apicid/ { print $NF; } \ + ' \ + /proc/cpuinfo +} + +# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{ + local cmdline=$1 + local newstr=${cmdline/$2/""} + + # unchanged str implies argument wasn't there + if [ "$cmdline" == "$newstr" ]; then + cmdline="${cmdline} ${2}=${3}" + fi + + echo $cmdline +} + +# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{ + return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \ + print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` +} + +# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{ + local secure_boot_file setup_mode_file + local secure_boot_byte setup_mode_byte + + secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) + setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null) + + if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then + secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) + setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5) + + if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then + return 0 + fi + fi + + return 1 +} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{ - local cmdline=$1 - shift - - for arg in $@; do - cmdline=`echo $cmdline | \ - sed -e "s/\b$arg=[^ ]*//g" \ - -e "s/^$arg\b//g" \ - -e "s/[[:space:]]$arg\b//g" \ - -e "s/\s+/ /g"` - done - echo $cmdline -} - -# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{ - awk ' \ - BEGIN { CPU = "-1"; } \ - $1=="processor" && $2==":" { CPU = $NF; } \ - CPU=="0" && /^apicid/ { print $NF; } \ - ' \ - /proc/cpuinfo -} - -# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{ - local cmdline=$1 - local newstr=${cmdline/$2/""} - - # unchanged str implies argument wasn't there - if [ "$cmdline" == "$newstr" ]; then - cmdline="${cmdline} ${2}=${3}" - fi - - echo $cmdline -} - # This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{ - return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \ - print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` -} - # Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{ - if [ ! -f /sys/kernel/kexec_crash_loaded ];then - echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" - return 1 - fi - - rc=`cat /sys/kernel/kexec_crash_loaded` - if [ $rc == 1 ]; then - return 0 - else - return 1 - fi -} - check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{ - local secure_boot_file setup_mode_file - local secure_boot_byte setup_mode_byte - - secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) - setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null) - - if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then - secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) - setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5) - - if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then - return 0 - fi - fi - - return 1 -} - -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_fence_kdump_config() { local hostname=`hostname` diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs. + \fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
Also cc Hari
Thanks.
Lianbo 在 2018年03月09日 20:19, lijiang 写道:
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Signed-off-by: Lianbo Jiang lijiang@redhat.com
dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash
+check() {
- if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]
- then
return 1
- fi
- return 0
+}
+depends() {
- echo "base shutdown"
- return 0
+}
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
- inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec"
- inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
- 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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
+[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh
+KEXEC=/sbin/kexec +standard_kexec_args="-p"
+EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS=""
+#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump
+prepare_parameters() +{
- local cmdline id
- if [ -z "$EARLY_KDUMP_CMDLINE" ]; then
cmdline=$(cat /proc/cmdline)
- else
cmdline=${EARLY_KDUMP_CMDLINE}
- fi
- cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
- cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE})
- # Always remove "root=X", as we now explicitly generate all kinds
- # of dump target mount information including root fs.
- #
- # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
- # about it(e.g. for debug purpose), then can pass "root=X" using
- # KDUMP_COMMANDLINE_APPEND.
- cmdline=$(remove_cmdline_param "$cmdline" root)
- # With the help of "--hostonly-cmdline", we can avoid some interitage.
- cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
- cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
- id=$(get_bootcpu_apicid)
- if [ ! -z ${id} ] ; then
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
- fi
- EARLY_KDUMP_CMDLINE=$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
- #make early-kdump kernel string
- if [ -z "$EARLY_KDUMP_KERNELVER" ]; then
EARLY_KDUMP_KERNELVER=`uname -r`
- fi
- EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
- #make early-kdump initrd string
- EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img"
+}
+early_kdump_load() +{
- check_kdump_feasibility
- if [ $? -ne 0 ]; then
return 1
- fi
- if is_fadump_capable; then
echo "early kdump doesn't support fadump: [WARNING]"
return 1
- fi
- check_current_kdump_status
- if [ $? == 0 ]; then
return 1
- fi
- prepare_parameters
- ARCH=`uname -m`
- if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
- then
need_64bit_headers
if [ $? == 1 ]
then
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers`
if [ -n "$FOUND_ELF_ARGS" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
echo
else
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers"
fi
else
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers`
if [ -z "$FOUND_ELF_ARGS" ]
then
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers"
fi
fi
- fi
- #secure boot
- if is_secure_boot_enforced; then
echo "Secure Boot is enabled. Using kexec file based syscall."
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
- fi
- $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO
+Introduction
+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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump.
+How to configure early kdump:
+We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command:
- # yum install kexec-tools
+For early kdump, you should rebuild the initramfs like this:
- # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force
+Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above.
+Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this:
- # journalctl -x|grep early-kdump
+Then, you will see some useful logs, for exapmles:
+1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel
+2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default.
+Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on.
+In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 }
+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_current_kdump_status() +{
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
+}
+# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{
local cmdline=$1
shift
for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
done
echo $cmdline
+}
+# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{
- awk ' \
BEGIN { CPU = "-1"; } \
$1=="processor" && $2==":" { CPU = $NF; } \
CPU=="0" && /^apicid/ { print $NF; } \
' \
/proc/cpuinfo
+}
+# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{
local cmdline=$1
local newstr=${cmdline/$2/""}
# unchanged str implies argument wasn't there
if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
fi
echo $cmdline
+}
+# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
+}
+# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{
local secure_boot_file setup_mode_file
local secure_boot_byte setup_mode_byte
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
fi
return 1
+} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{
- local cmdline=$1
- shift
- for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
- done
- echo $cmdline
-}
-# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{
- awk ' \
- BEGIN { CPU = "-1"; } \
- $1=="processor" && $2==":" { CPU = $NF; } \
- CPU=="0" && /^apicid/ { print $NF; } \
- ' \
- /proc/cpuinfo
-}
-# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{
- local cmdline=$1
- local newstr=${cmdline/$2/""}
- # unchanged str implies argument wasn't there
- if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
- fi
- echo $cmdline
-}
# This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{
- return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
- print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
-}
# Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{
- if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
- fi
- rc=`cat /sys/kernel/kexec_crash_loaded`
- if [ $rc == 1 ]; then
return 0
- else
return 1
- fi
-}
check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{
- local secure_boot_file setup_mode_file
- local secure_boot_byte setup_mode_byte
- secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
- setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
- if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
- fi
- return 1
-}
-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_fence_kdump_config() { local hostname=`hostname` diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs.
\fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
Hello Lianbo,
On Friday 09 March 2018 05:49 PM, lijiang wrote:
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Basically, the kernel with fadump support would populate two nodes. /sys/kernel/fadump_enabled & /sys/kernel/fadump_registered. When /sys/kernel/fadump_enabled is set to '1' means, the user chose fadump over kdump. This script has to set /sys/kernel/fadump_registered to '1' (similar to kdump load) to register it.
Look at determine_dump_mode, check_dump_feasibility, start_fadump
These are all the functions you may need to extend support for fadump as we won't be bothering to rebuild initrd here..
See if you can add fadump support based on the info I provided. Else, I will add it once you patch is accepted.
Thanks Hari
Signed-off-by: Lianbo Jiang lijiang@redhat.com
dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash
+check() {
- if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]
- then
return 1
- fi
- return 0
+}
+depends() {
- echo "base shutdown"
- return 0
+}
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
- inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec"
- inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
- 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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
+[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh
+KEXEC=/sbin/kexec +standard_kexec_args="-p"
+EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS=""
+#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump
+prepare_parameters() +{
- local cmdline id
- if [ -z "$EARLY_KDUMP_CMDLINE" ]; then
cmdline=$(cat /proc/cmdline)
- else
cmdline=${EARLY_KDUMP_CMDLINE}
- fi
- cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
- cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE})
- # Always remove "root=X", as we now explicitly generate all kinds
- # of dump target mount information including root fs.
- #
- # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
- # about it(e.g. for debug purpose), then can pass "root=X" using
- # KDUMP_COMMANDLINE_APPEND.
- cmdline=$(remove_cmdline_param "$cmdline" root)
- # With the help of "--hostonly-cmdline", we can avoid some interitage.
- cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
- cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
- id=$(get_bootcpu_apicid)
- if [ ! -z ${id} ] ; then
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
- fi
- EARLY_KDUMP_CMDLINE=$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
- #make early-kdump kernel string
- if [ -z "$EARLY_KDUMP_KERNELVER" ]; then
EARLY_KDUMP_KERNELVER=`uname -r`
- fi
- EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
- #make early-kdump initrd string
- EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img"
+}
+early_kdump_load() +{
- check_kdump_feasibility
- if [ $? -ne 0 ]; then
return 1
- fi
- if is_fadump_capable; then
echo "early kdump doesn't support fadump: [WARNING]"
return 1
- fi
- check_current_kdump_status
- if [ $? == 0 ]; then
return 1
- fi
- prepare_parameters
- ARCH=`uname -m`
- if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
- then
need_64bit_headers
if [ $? == 1 ]
then
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers`
if [ -n "$FOUND_ELF_ARGS" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
echo
else
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers"
fi
else
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers`
if [ -z "$FOUND_ELF_ARGS" ]
then
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers"
fi
fi
- fi
- #secure boot
- if is_secure_boot_enforced; then
echo "Secure Boot is enabled. Using kexec file based syscall."
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
- fi
- $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO
+Introduction
+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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump.
+How to configure early kdump:
+We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command:
- # yum install kexec-tools
+For early kdump, you should rebuild the initramfs like this:
- # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force
+Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above.
+Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this:
- # journalctl -x|grep early-kdump
+Then, you will see some useful logs, for exapmles:
+1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel
+2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default.
+Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on.
+In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 }
+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_current_kdump_status() +{
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
+}
+# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{
local cmdline=$1
shift
for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
done
echo $cmdline
+}
+# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{
- awk ' \
BEGIN { CPU = "-1"; } \
$1=="processor" && $2==":" { CPU = $NF; } \
CPU=="0" && /^apicid/ { print $NF; } \
' \
/proc/cpuinfo
+}
+# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{
local cmdline=$1
local newstr=${cmdline/$2/""}
# unchanged str implies argument wasn't there
if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
fi
echo $cmdline
+}
+# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
+}
+# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{
local secure_boot_file setup_mode_file
local secure_boot_byte setup_mode_byte
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
fi
return 1
+} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{
- local cmdline=$1
- shift
- for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
- done
- echo $cmdline
-}
-# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{
- awk ' \
- BEGIN { CPU = "-1"; } \
- $1=="processor" && $2==":" { CPU = $NF; } \
- CPU=="0" && /^apicid/ { print $NF; } \
- ' \
- /proc/cpuinfo
-}
-# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{
- local cmdline=$1
- local newstr=${cmdline/$2/""}
- # unchanged str implies argument wasn't there
- if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
- fi
- echo $cmdline
-}
- # This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline()
@@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{
- return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
- print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
-}
- # Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel.
@@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{
- if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
- fi
- rc=`cat /sys/kernel/kexec_crash_loaded`
- if [ $rc == 1 ]; then
return 0
- else
return 1
- fi
-}
- check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
@@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{
- local secure_boot_file setup_mode_file
- local secure_boot_byte setup_mode_byte
- secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
- setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
- if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
- fi
- return 1
-}
-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_fence_kdump_config() { local hostname=`hostname`
diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs.
- \fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
在 2018年03月10日 04:24, Hari Bathini 写道:
Hello Lianbo,
On Friday 09 March 2018 05:49 PM, lijiang wrote:
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Basically, the kernel with fadump support would populate two nodes. /sys/kernel/fadump_enabled & /sys/kernel/fadump_registered. When /sys/kernel/fadump_enabled is set to '1' means, the user chose fadump over kdump. This script has to set /sys/kernel/fadump_registered to '1' (similar to kdump load) to register it.
Look at determine_dump_mode, check_dump_feasibility, start_fadump
These are all the functions you may need to extend support for fadump as we won't be bothering to rebuild initrd here..
See if you can add fadump support based on the info I provided. Else, I will add it once you patch is accepted.
Thanks Hari
Thanks Hari, Maybe it's suitable that you will add the fadump for early kdump in future, because the fadump needs to be verify, at present, I have no machine.
Lianbo
Signed-off-by: Lianbo Jiang lijiang@redhat.com
dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash
+check() { + if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ] + then + return 1 + fi + return 0 +}
+depends() { + echo "base shutdown" + return 0 +}
+install() { + inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump" + inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec" + inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" + 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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
+[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh
+KEXEC=/sbin/kexec +standard_kexec_args="-p"
+EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS=""
+#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump
+prepare_parameters() +{ + local cmdline id
+ if [ -z "$EARLY_KDUMP_CMDLINE" ]; then + cmdline=$(cat /proc/cmdline) + else + cmdline=${EARLY_KDUMP_CMDLINE} + fi
+ cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn) + cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE})
+ # Always remove "root=X", as we now explicitly generate all kinds + # of dump target mount information including root fs. + # + # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares + # about it(e.g. for debug purpose), then can pass "root=X" using + # KDUMP_COMMANDLINE_APPEND. + cmdline=$(remove_cmdline_param "$cmdline" root)
+ # With the help of "--hostonly-cmdline", we can avoid some interitage. + cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe) + cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}" + id=$(get_bootcpu_apicid) + if [ ! -z ${id} ] ; then + cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id}) + fi + EARLY_KDUMP_CMDLINE=$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
+ #make early-kdump kernel string + if [ -z "$EARLY_KDUMP_KERNELVER" ]; then + EARLY_KDUMP_KERNELVER=`uname -r` + fi + EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
+ #make early-kdump initrd string + EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img" +}
+early_kdump_load() +{ + check_kdump_feasibility + if [ $? -ne 0 ]; then + return 1 + fi
+ if is_fadump_capable; then + echo "early kdump doesn't support fadump: [WARNING]" + return 1 + fi
+ check_current_kdump_status + if [ $? == 0 ]; then + return 1 + fi
+ prepare_parameters
+ ARCH=`uname -m` + if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ] + then + need_64bit_headers + if [ $? == 1 ] + then + FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers` + if [ -n "$FOUND_ELF_ARGS" ] + then + echo -n "Warning: elf32-core-headers overrides correct elf64 setting" + echo + else + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers" + fi + else + FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers` + if [ -z "$FOUND_ELF_ARGS" ] + then + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers" + fi + fi + fi
+ #secure boot + if is_secure_boot_enforced; then + echo "Secure Boot is enabled. Using kexec file based syscall." + EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" + fi
+ $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO
+Introduction
+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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump.
+How to configure early kdump:
+We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command:
+ # yum install kexec-tools
+For early kdump, you should rebuild the initramfs like this: + # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force
+Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above.
+Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this:
+ # journalctl -x|grep early-kdump
+Then, you will see some useful logs, for exapmles:
+1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel
+2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default.
+Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on.
+In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 }
+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_current_kdump_status() +{ + if [ ! -f /sys/kernel/kexec_crash_loaded ];then + echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" + return 1 + fi
+ rc=`cat /sys/kernel/kexec_crash_loaded` + if [ $rc == 1 ]; then + return 0 + else + return 1 + fi +}
+# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{ + local cmdline=$1 + shift
+ for arg in $@; do + cmdline=`echo $cmdline | \ + sed -e "s/\b$arg=[^ ]*//g" \ + -e "s/^$arg\b//g" \ + -e "s/[[:space:]]$arg\b//g" \ + -e "s/\s+/ /g"` + done + echo $cmdline +}
+# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{ + awk ' \ + BEGIN { CPU = "-1"; } \ + $1=="processor" && $2==":" { CPU = $NF; } \ + CPU=="0" && /^apicid/ { print $NF; } \ + ' \ + /proc/cpuinfo +}
+# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{ + local cmdline=$1 + local newstr=${cmdline/$2/""}
+ # unchanged str implies argument wasn't there + if [ "$cmdline" == "$newstr" ]; then + cmdline="${cmdline} ${2}=${3}" + fi
+ echo $cmdline +}
+# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{ + return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \ + print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` +}
+# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{ + local secure_boot_file setup_mode_file + local secure_boot_byte setup_mode_byte
+ secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) + setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
+ if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then + secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) + setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
+ if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then + return 0 + fi + fi
+ return 1 +} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{ - local cmdline=$1 - shift
- for arg in $@; do - cmdline=`echo $cmdline | \ - sed -e "s/\b$arg=[^ ]*//g" \ - -e "s/^$arg\b//g" \ - -e "s/[[:space:]]$arg\b//g" \ - -e "s/\s+/ /g"` - done - echo $cmdline -}
-# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{ - awk ' \ - BEGIN { CPU = "-1"; } \ - $1=="processor" && $2==":" { CPU = $NF; } \ - CPU=="0" && /^apicid/ { print $NF; } \ - ' \ - /proc/cpuinfo -}
-# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{ - local cmdline=$1 - local newstr=${cmdline/$2/""}
- # unchanged str implies argument wasn't there - if [ "$cmdline" == "$newstr" ]; then - cmdline="${cmdline} ${2}=${3}" - fi
- echo $cmdline -}
# This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{ - return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \ - print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` -}
# Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{ - if [ ! -f /sys/kernel/kexec_crash_loaded ];then - echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel" - return 1 - fi
- rc=`cat /sys/kernel/kexec_crash_loaded` - if [ $rc == 1 ]; then - return 0 - else - return 1 - fi -}
check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{ - local secure_boot_file setup_mode_file - local secure_boot_byte setup_mode_byte
- secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) - setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
- if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then - secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) - setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
- if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then - return 0 - fi - fi
- return 1 -}
-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_fence_kdump_config() { local hostname=`hostname` diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs.
\fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
Hi Lianbo, Dave,
Thank you for ccing me, and sorry for my late response.
I think that ideally early kdump should execute kexec as early as possible and minimize the difference between normal and early kdump boot, because we don't know what will crash (e.g., when /boot is being mounted or some driver initialization for that) and what will prevent the crash.
So though this is just a thought, could it put the kernel/initramfs for kdump into the initramfs for boot without mounting /boot?
For example: 1. add something like KDUMP_EARLY="" to /etc/sysconfig/kdump 2. start kdump service - generate the initramfs for kdump if needed (as usual) - if the KDUMP_EARLY is "yes", then o install the early kdump dracut module with inst_simple for kernel/initramfs for kdump o rebuild initramfs for boot with early kdump ...
Of course, since the initramfs will become large, early kdump might be used only when debbuging for early crashes. And this might have many points to consider..
Thanks, Kazu
On 3/9/2018 7:19 AM, lijiang wrote:
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Signed-off-by: Lianbo Jiang lijiang@redhat.com
dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash
+check() {
- if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]
- then
return 1
- fi
- return 0
+}
+depends() {
- echo "base shutdown"
- return 0
+}
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
- inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec"
- inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
- 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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
+[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh
+KEXEC=/sbin/kexec +standard_kexec_args="-p"
+EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS=""
+#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump
+prepare_parameters() +{
- local cmdline id
- if [ -z "$EARLY_KDUMP_CMDLINE" ]; then
cmdline=$(cat /proc/cmdline)
- else
cmdline=${EARLY_KDUMP_CMDLINE}
- fi
- cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
- cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE})
- # Always remove "root=X", as we now explicitly generate all kinds
- # of dump target mount information including root fs.
- #
- # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
- # about it(e.g. for debug purpose), then can pass "root=X" using
- # KDUMP_COMMANDLINE_APPEND.
- cmdline=$(remove_cmdline_param "$cmdline" root)
- # With the help of "--hostonly-cmdline", we can avoid some interitage.
- cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
- cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
- id=$(get_bootcpu_apicid)
- if [ ! -z ${id} ] ; then
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
- fi
- EARLY_KDUMP_CMDLINE=$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
- #make early-kdump kernel string
- if [ -z "$EARLY_KDUMP_KERNELVER" ]; then
EARLY_KDUMP_KERNELVER=`uname -r`
- fi
- EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
- #make early-kdump initrd string
- EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img"
+}
+early_kdump_load() +{
- check_kdump_feasibility
- if [ $? -ne 0 ]; then
return 1
- fi
- if is_fadump_capable; then
echo "early kdump doesn't support fadump: [WARNING]"
return 1
- fi
- check_current_kdump_status
- if [ $? == 0 ]; then
return 1
- fi
- prepare_parameters
- ARCH=`uname -m`
- if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
- then
need_64bit_headers
if [ $? == 1 ]
then
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers`
if [ -n "$FOUND_ELF_ARGS" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
echo
else
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers"
fi
else
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers`
if [ -z "$FOUND_ELF_ARGS" ]
then
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers"
fi
fi
- fi
- #secure boot
- if is_secure_boot_enforced; then
echo "Secure Boot is enabled. Using kexec file based syscall."
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
- fi
- $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO
+Introduction
+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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump.
+How to configure early kdump:
+We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command:
- # yum install kexec-tools
+For early kdump, you should rebuild the initramfs like this:
- # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force
+Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above.
+Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this:
- # journalctl -x|grep early-kdump
+Then, you will see some useful logs, for exapmles:
+1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel
+2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default.
+Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on.
+In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 }
+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_current_kdump_status() +{
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
+}
+# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{
local cmdline=$1
shift
for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
done
echo $cmdline
+}
+# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{
- awk ' \
BEGIN { CPU = "-1"; } \
$1=="processor" && $2==":" { CPU = $NF; } \
CPU=="0" && /^apicid/ { print $NF; } \
' \
/proc/cpuinfo
+}
+# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{
local cmdline=$1
local newstr=${cmdline/$2/""}
# unchanged str implies argument wasn't there
if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
fi
echo $cmdline
+}
+# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
+}
+# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{
local secure_boot_file setup_mode_file
local secure_boot_byte setup_mode_byte
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
fi
return 1
+} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{
- local cmdline=$1
- shift
- for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
- done
- echo $cmdline
-}
-# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{
- awk ' \
- BEGIN { CPU = "-1"; } \
- $1=="processor" && $2==":" { CPU = $NF; } \
- CPU=="0" && /^apicid/ { print $NF; } \
- ' \
- /proc/cpuinfo
-}
-# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{
- local cmdline=$1
- local newstr=${cmdline/$2/""}
- # unchanged str implies argument wasn't there
- if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
- fi
- echo $cmdline
-}
# This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{
- return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
- print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
-}
# Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{
- if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
- fi
- rc=`cat /sys/kernel/kexec_crash_loaded`
- if [ $rc == 1 ]; then
return 0
- else
return 1
- fi
-}
check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{
- local secure_boot_file setup_mode_file
- local secure_boot_byte setup_mode_byte
- secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
- setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
- if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
- fi
- return 1
-}
-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_fence_kdump_config() { local hostname=`hostname` diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs.
\fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
在 2018年03月10日 05:46, Kazuhito Hagio 写道:
Hi Lianbo, Dave,
Thank you for ccing me, and sorry for my late response.
I think that ideally early kdump should execute kexec as early as possible and minimize the difference between normal and early kdump boot, because we don't know what will crash (e.g., when /boot is being mounted or some driver initialization for that) and what will prevent the crash.
So though this is just a thought, could it put the kernel/initramfs for kdump into the initramfs for boot without mounting /boot?
For example:
- add something like KDUMP_EARLY="" to /etc/sysconfig/kdump
- start kdump service
...
- generate the initramfs for kdump if needed (as usual)
- if the KDUMP_EARLY is "yes", then o install the early kdump dracut module with inst_simple for kernel/initramfs for kdump o rebuild initramfs for boot with early kdump
Of course, since the initramfs will become large, early kdump might be used only when debbuging for early crashes. And this might have many points to consider..
Thanks, Kazu
Thanks Kazu, I agree with you and have sent patch V2.
Lianbo
On 3/9/2018 7:19 AM, lijiang wrote:
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 and 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 whether the pre-built kernel and initramfs has been loaded. It has no conflict with the early kdump.
By the way, we move some common functions from kdumpctl to kdump-lib.sh. In addition, early kdump doesn't support fadump.
Signed-off-by: Lianbo Jiang lijiang@redhat.com
dracut-early-kdump-module-setup.sh | 23 +++++++ dracut-early-kdump.service | 24 +++++++ dracut-early-kdump.sh | 138 +++++++++++++++++++++++++++++++++++++ early-kdump-howto.txt | 51 ++++++++++++++ kdump-lib.sh | 123 +++++++++++++++++++++++++++++++++ kdumpctl | 123 --------------------------------- kexec-tools.spec | 13 ++++ mkdumprd.8 | 3 + 8 files changed, 375 insertions(+), 123 deletions(-) create mode 100755 dracut-early-kdump-module-setup.sh create mode 100644 dracut-early-kdump.service create mode 100755 dracut-early-kdump.sh create mode 100644 early-kdump-howto.txt
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh new file mode 100755 index 0000000..bc4d7dc --- /dev/null +++ b/dracut-early-kdump-module-setup.sh @@ -0,0 +1,23 @@ +#!/bin/bash
+check() {
- if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]
- then
return 1
- fi
- return 0
+}
+depends() {
- echo "base shutdown"
- return 0
+}
+install() {
- inst_simple "/etc/sysconfig/kdump" "/etc/sysconfig/kdump"
- inst_simple "/usr/sbin/kexec" "/usr/sbin/kexec"
- inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
- 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..0d3bc95 --- /dev/null +++ b/dracut-early-kdump.service @@ -0,0 +1,24 @@ +# 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
+[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..067ad5c --- /dev/null +++ b/dracut-early-kdump.sh @@ -0,0 +1,138 @@ +#! /bin/sh
+KEXEC=/sbin/kexec +standard_kexec_args="-p"
+EARLY_KDUMP_INITRD="" +EARLY_KDUMP_KERNEL="" +EARLY_KDUMP_CMDLINE="" +EARLY_KDUMP_KERNELVER="" +EARLY_KEXEC_ARGS=""
+#source lib and configure +. /lib/dracut-lib.sh +. /lib/kdump-lib.sh +. /etc/sysconfig/kdump
+prepare_parameters() +{
- local cmdline id
- if [ -z "$EARLY_KDUMP_CMDLINE" ]; then
cmdline=$(cat /proc/cmdline)
- else
cmdline=${EARLY_KDUMP_CMDLINE}
- fi
- cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
- cmdline=$(remove_cmdline_param "$cmdline" ${KDUMP_COMMANDLINE_REMOVE})
- # Always remove "root=X", as we now explicitly generate all kinds
- # of dump target mount information including root fs.
- #
- # We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
- # about it(e.g. for debug purpose), then can pass "root=X" using
- # KDUMP_COMMANDLINE_APPEND.
- cmdline=$(remove_cmdline_param "$cmdline" root)
- # With the help of "--hostonly-cmdline", we can avoid some interitage.
- cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
- cmdline="${cmdline} ${KDUMP_COMMANDLINE_APPEND}"
- id=$(get_bootcpu_apicid)
- if [ ! -z ${id} ] ; then
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
- fi
- EARLY_KDUMP_CMDLINE=$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
- #make early-kdump kernel string
- if [ -z "$EARLY_KDUMP_KERNELVER" ]; then
EARLY_KDUMP_KERNELVER=`uname -r`
- fi
- EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}"
- #make early-kdump initrd string
- EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img"
+}
+early_kdump_load() +{
- check_kdump_feasibility
- if [ $? -ne 0 ]; then
return 1
- fi
- if is_fadump_capable; then
echo "early kdump doesn't support fadump: [WARNING]"
return 1
- fi
- check_current_kdump_status
- if [ $? == 0 ]; then
return 1
- fi
- prepare_parameters
- ARCH=`uname -m`
- if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
- then
need_64bit_headers
if [ $? == 1 ]
then
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf32-core-headers`
if [ -n "$FOUND_ELF_ARGS" ]
then
echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
echo
else
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf64-core-headers"
fi
else
FOUND_ELF_ARGS=`echo $EARLY_KEXEC_ARGS | grep elf64-core-headers`
if [ -z "$FOUND_ELF_ARGS" ]
then
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS --elf32-core-headers"
fi
fi
- fi
- #secure boot
- if is_secure_boot_enforced; then
echo "Secure Boot is enabled. Using kexec file based syscall."
EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s"
- fi
- $KEXEC ${EARLY_KEXEC_ARGS} $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/early-kdump-howto.txt b/early-kdump-howto.txt new file mode 100644 index 0000000..b43610d --- /dev/null +++ b/early-kdump-howto.txt @@ -0,0 +1,51 @@ +Early Kdump HOWTO
+Introduction
+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 and +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 whether the +prebuilt kernel and initramfs have been loaded. It has no conflict with the early +kdump.
+How to configure early kdump:
+We assume if you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command:
- # yum install kexec-tools
+For early kdump, you should rebuild the initramfs like this:
- # dracut --mount /boot -v /boot/initramfs-`uname -r`.img --force
+Next up, we need to modify some boot parameters to enable early kdump, it's +very easy to append "rd.early-kdump" to your kernel boot parameters in grub. +After making said changes, reboot your system to take effect. Of course, if +you want to disable early kdump, you can simply remove "rd.early-kdump" from +kernel boot parameters in grub, and reboot system like above.
+Now that you've got some messages about early kdump, you can check whether early +kdump is successful like this:
- # journalctl -x|grep early-kdump
+Then, you will see some useful logs, for exapmles:
+1. if early kdump is successful. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: early-kdump is enabled. +Mar 09 09:57:56 localhost.localdomain early-kdump[477]: kexec: loaded early- +kdump kernel
+2. if early kdump is disabled. +Mar 09 10:02:47 localhost.localdomain early-kdump[474]: early-kdump is not en- +abled by default.
+Notes: +You will need to make sure that appropriate "/boot" to mount, if "/boot" mounting +fails it will refuse to go on.
+In addition, early kdump doesn't support fadump, maybe it will have this in future. diff --git a/kdump-lib.sh b/kdump-lib.sh index d981c4f..a1a7660 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -485,3 +485,126 @@ get_dracut_args_target() { echo $1 | grep "--mount" | sed "s/.*--mount .(.*)/\1/" | cut -d' ' -f1 }
+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_current_kdump_status() +{
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
fi
rc=`cat /sys/kernel/kexec_crash_loaded`
if [ $rc == 1 ]; then
return 0
else
return 1
fi
+}
+# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] +# Remove a list of kernel parameters from a given kernel cmdline and print the result. +# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. +remove_cmdline_param() +{
local cmdline=$1
shift
for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
done
echo $cmdline
+}
+# +# This function returns the "apicid" of the boot +# cpu (cpu 0) if present. +# +get_bootcpu_apicid() +{
- awk ' \
BEGIN { CPU = "-1"; } \
$1=="processor" && $2==":" { CPU = $NF; } \
CPU=="0" && /^apicid/ { print $NF; } \
' \
/proc/cpuinfo
+}
+# +# This function appends argument "$2=$3" to string ($1) if not already present. +# +append_cmdline() +{
local cmdline=$1
local newstr=${cmdline/$2/""}
# unchanged str implies argument wasn't there
if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
fi
echo $cmdline
+}
+# This function check iomem and determines if we have more than +# 4GB of ram available. Returns 1 if we do, 0 if we dont +need_64bit_headers() +{
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
+}
+# Check if secure boot is being enforced. +# +# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and +# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four +# bytes are the attributes associated with the variable and can safely be +# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot +# is 1 and SetupMode is 0, then secure boot is being enforced. +# +# Assume efivars is mounted at /sys/firmware/efi/efivars. +is_secure_boot_enforced() +{
local secure_boot_file setup_mode_file
local secure_boot_byte setup_mode_byte
secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
fi
return 1
+} diff --git a/kdumpctl b/kdumpctl index 4280e7e..1d25d07 100755 --- a/kdumpctl +++ b/kdumpctl @@ -62,54 +62,6 @@ determine_dump_mode() fi }
-# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>] -# Remove a list of kernel parameters from a given kernel cmdline and print the result. -# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists. -remove_cmdline_param() -{
- local cmdline=$1
- shift
- for arg in $@; do
cmdline=`echo $cmdline | \
sed -e "s/\b$arg=[^ ]*//g" \
-e "s/^$arg\b//g" \
-e "s/[[:space:]]$arg\b//g" \
-e "s/\s\+/ /g"`
- done
- echo $cmdline
-}
-# -# This function returns the "apicid" of the boot -# cpu (cpu 0) if present. -# -get_bootcpu_apicid() -{
- awk ' \
- BEGIN { CPU = "-1"; } \
- $1=="processor" && $2==":" { CPU = $NF; } \
- CPU=="0" && /^apicid/ { print $NF; } \
- ' \
- /proc/cpuinfo
-}
-# -# This function appends argument "$2=$3" to string ($1) if not already present. -# -append_cmdline() -{
- local cmdline=$1
- local newstr=${cmdline/$2/""}
- # unchanged str implies argument wasn't there
- if [ "$cmdline" == "$newstr" ]; then
cmdline="${cmdline} ${2}=${3}"
- fi
- echo $cmdline
-}
# This function performs a series of edits on the command line. # Store the final result in global $KDUMP_COMMANDLINE. prepare_cmdline() @@ -686,14 +638,6 @@ check_rebuild() return $? }
-# This function check iomem and determines if we have more than -# 4GB of ram available. Returns 1 if we do, 0 if we dont -need_64bit_headers() -{
- return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
- print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
-}
# Load the kdump kernel specified in /etc/sysconfig/kdump # If none is specified, try to load a kdump kernel with the same version # as the currently running kernel. @@ -850,21 +794,6 @@ check_current_fadump_status() return 1 }
-check_current_kdump_status() -{
- if [ ! -f /sys/kernel/kexec_crash_loaded ];then
echo "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
return 1
- fi
- rc=`cat /sys/kernel/kexec_crash_loaded`
- if [ $rc == 1 ]; then
return 0
- else
return 1
- fi
-}
check_current_status() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -974,58 +903,6 @@ selinux_relabel() done }
-# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{
- local secure_boot_file setup_mode_file
- local secure_boot_byte setup_mode_byte
- secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null)
- setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null)
- if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5)
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5)
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
return 0
fi
- fi
- return 1
-}
-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_fence_kdump_config() { local hostname=`hostname` diff --git a/kexec-tools.spec b/kexec-tools.spec index f04527c..9ecaefd 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -29,6 +29,7 @@ Source24: kdump-lib-initramfs.sh Source25: kdump.sysconfig.ppc64le Source26: kdumpctl.8 Source27: live-image-kdump-howto.txt +Source28: early-kdump-howto.txt
####################################### # These are sources for mkdumpramfs @@ -42,6 +43,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 @@ -136,6 +140,7 @@ rm -f kexec-tools.spec.in cp %{SOURCE10} . cp %{SOURCE21} . cp %{SOURCE27} . +cp %{SOURCE28} .
make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 @@ -194,6 +199,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 +213,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 @@ -305,6 +317,7 @@ done %license COPYING %doc TODO %doc kexec-kdump-howto.txt +%doc early-kdump-howto.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..6e22e0a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -17,6 +17,9 @@ be loaded in the initramfs (based on configuration retrieved from \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR utility to generate the initramfs.
+\fBmkdumprd\fR add a new \fBdracut\fR module 99earlykdump and use \fBdracut\fR +utility to generate the initramfs.
\fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If you require a custom kdump initramfs image, it is suggested that you use the
Lianbo/Dave, I think this needs to be made FADump aware as well.. /sys/kernel/fadump_enabled & /sys/kernel/fadump_registered nodes would be ready by this time.
The problem I could see though is, the default initrd may not be fadump aware if this is the first boot after configuring fadump and system crashed early in the boot process. But still, I think that is better over not having dump capture service configured at all..
Thanks Hari
On Monday 05 March 2018 01:26 PM, Dave Young wrote:
I remember Kazuhito had similar idea about this, add him in CC. Also we may need consider some effects to fadump as well. Ccing Hari.
On 03/05/18 at 03:05pm, Lianbo Jiang wrote:
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@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 _______________________________________________ kexec mailing list -- kexec@lists.fedoraproject.org To unsubscribe send an email to kexec-leave@lists.fedoraproject.org