summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-07-26 17:19:39 +0000
committerCoprDistGit <infra@openeuler.org>2024-07-26 17:19:39 +0000
commit5be00af7c80ed4972c1f3379e6db9937e1a8b7bd (patch)
tree7938404f19676c304f68d0d47e475fe4a1440452
parentad07ec0c7538028e4d732f63e34d58150f5ffd42 (diff)
automatic import of kexec-tools
-rw-r--r--.gitignore3
-rw-r--r--98-kexec.rules16
-rw-r--r--add-secure-compile-options-for-makedumpfile.patch32
-rwxr-xr-xdracut-early-kdump-module-setup.sh65
-rwxr-xr-xdracut-early-kdump.sh76
-rw-r--r--dracut-kdump-capture.service30
-rw-r--r--dracut-kdump-emergency.service28
-rw-r--r--dracut-kdump-emergency.target14
-rw-r--r--dracut-kdump-error-handler.service33
-rwxr-xr-xdracut-kdump-error-handler.sh10
-rwxr-xr-xdracut-kdump-wait-for-target.sh23
-rwxr-xr-xdracut-kdump.sh182
-rwxr-xr-xdracut-module-setup.sh846
-rw-r--r--dracut-monitor_dd_progress28
-rw-r--r--early-kdump-howto.txt95
-rw-r--r--kdump-dep-generator.sh22
-rw-r--r--kdump-in-cluster-environment.txt91
-rwxr-xr-xkdump-lib-initramfs.sh277
-rwxr-xr-xkdump-lib.sh657
-rwxr-xr-xkdump-udev-throttler42
-rw-r--r--kdump.conf175
-rw-r--r--kdump.conf.5360
-rw-r--r--kdump.service15
-rw-r--r--kdump.sysconfig37
-rw-r--r--kdump.sysconfig.aarch6437
-rw-r--r--kdump.sysconfig.i38640
-rwxr-xr-xkdump.sysconfig.loongarch6465
-rw-r--r--kdump.sysconfig.ppc6442
-rw-r--r--kdump.sysconfig.ppc64le42
-rw-r--r--kdump.sysconfig.riscv6437
-rw-r--r--kdump.sysconfig.s390x43
-rw-r--r--kdump.sysconfig.x86_6446
-rwxr-xr-xkdumpctl1301
-rw-r--r--kdumpctl.850
-rw-r--r--kexec-Add-quick-kexec-support.patch118
-rw-r--r--kexec-Quick-kexec-implementation-for-arm64.patch143
-rw-r--r--kexec-tools.spec450
-rw-r--r--live-image-kdump-howto.txt25
-rw-r--r--mkdumprd439
-rw-r--r--mkdumprd.833
-rw-r--r--sources3
41 files changed, 6071 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..80337d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/eppic-e8844d3.tar.gz
+/kexec-tools-2.0.26.tar.xz
+/makedumpfile-1.7.3.tar.gz
diff --git a/98-kexec.rules b/98-kexec.rules
new file mode 100644
index 0000000..b73b701
--- /dev/null
+++ b/98-kexec.rules
@@ -0,0 +1,16 @@
+SUBSYSTEM=="cpu", ACTION=="add", GOTO="kdump_reload"
+SUBSYSTEM=="cpu", ACTION=="remove", GOTO="kdump_reload"
+SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload"
+SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload"
+
+GOTO="kdump_reload_end"
+
+LABEL="kdump_reload"
+
+# If kdump is not loaded, calling kdump-udev-throttle will end up
+# doing nothing, but systemd-run will always generate extra logs for
+# each call, so trigger the kdump-udev-throttler only if kdump
+# service is active to avoid unnecessary logs
+RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'"
+
+LABEL="kdump_reload_end"
diff --git a/add-secure-compile-options-for-makedumpfile.patch b/add-secure-compile-options-for-makedumpfile.patch
new file mode 100644
index 0000000..a3207c3
--- /dev/null
+++ b/add-secure-compile-options-for-makedumpfile.patch
@@ -0,0 +1,32 @@
+From 776d8f6355fdf77ec63bae4be09b8f40d0c831ad Mon Sep 17 00:00:00 2001
+From: pengyeqing <pengyeqing@huawei.com>
+Date: Sun, 18 Aug 2019 23:59:23 +0000
+Subject: [PATCH] kexec-tools: add secure compile options for makedumpfile
+
+reason:add secure compile options for makedumpfile
+
+Signed-off-by: pengyeqing <pengyeqing@huawei.com>
+---
+ Makefile | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile
+index 612b9d0..180a64f 100644
+--- a/makedumpfile-1.7.3/Makefile
++++ b/makedumpfile-1.7.3/Makefile
+@@ -10,9 +10,10 @@ endif
+
+ CFLAGS_BASE := $(CFLAGS) -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \
+ -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
+-CFLAGS := $(CFLAGS_BASE) -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"'
+-CFLAGS_ARCH := $(CFLAGS_BASE)
++CFLAGS := $(CFLAGS_BASE) -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' -fstack-protector-strong -Wl,-z,now -fPIE
++CFLAGS_ARCH := $(CFLAGS_BASE) -fPIE
+ # LDFLAGS = -L/usr/local/lib -I/usr/local/include
++LDFLAGS += -pie
+
+ HOST_ARCH := $(shell uname -m)
+ # Use TARGET as the target architecture if specified.
+--
+1.8.3.1
+
diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh
new file mode 100755
index 0000000..e069867
--- /dev/null
+++ b/dracut-early-kdump-module-setup.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+. /etc/sysconfig/kdump
+. /lib/kdump/kdump-lib.sh
+
+KDUMP_KERNEL=""
+KDUMP_INITRD=""
+
+check() {
+ if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]\
+ || [ -n "${IN_KDUMP}" ]
+ then
+ return 1
+ fi
+ return 255
+}
+
+depends() {
+ echo "base shutdown"
+ return 0
+}
+
+prepare_kernel_initrd() {
+ KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
+ if [ -z "$KDUMP_KERNELVER" ]; then
+ kdump_kver=`uname -r`
+ if [ "$kernel" != "$kdump_kver" ]; then
+ dwarn "Using current kernel version '$kdump_kver' for early kdump," \
+ "but the initramfs is generated for kernel version '$kernel'"
+ fi
+ else
+ kdump_kver=$KDUMP_KERNELVER
+ fi
+ KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
+ KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
+}
+
+install() {
+ prepare_kernel_initrd
+ if [ ! -f "$KDUMP_KERNEL" ]; then
+ derror "Could not find required kernel for earlykdump," \
+ "earlykdump will not work!"
+ return 1
+ fi
+ if [ ! -f "$KDUMP_INITRD" ]; then
+ derror "Could not find required kdump initramfs for earlykdump," \
+ "please ensure kdump initramfs is generated first," \
+ "earlykdump will not work!"
+ return 1
+ fi
+
+ inst_multiple tail find cut dirname hexdump
+ inst_simple "/etc/sysconfig/kdump"
+ inst_binary "/usr/sbin/kexec"
+ inst_binary "/usr/bin/gawk" "/usr/bin/awk"
+ inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
+ inst_hook cmdline 00 "$moddir/early-kdump.sh"
+ inst_binary "$KDUMP_KERNEL"
+ inst_binary "$KDUMP_INITRD"
+
+ ln_r "$KDUMP_KERNEL" "${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}"
+ ln_r "$KDUMP_INITRD" "${KDUMP_BOOTDIR}/initramfs-earlykdump.img"
+
+ chmod -x "${initdir}/$KDUMP_KERNEL"
+}
diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh
new file mode 100755
index 0000000..6788a6b
--- /dev/null
+++ b/dracut-early-kdump.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+KEXEC=/sbin/kexec
+standard_kexec_args="-p"
+KDUMP_FILE_LOAD=""
+
+EARLY_KDUMP_INITRD=""
+EARLY_KDUMP_KERNEL=""
+EARLY_KDUMP_CMDLINE=""
+EARLY_KDUMP_KERNELVER=""
+EARLY_KEXEC_ARGS=""
+
+. /etc/sysconfig/kdump
+. /lib/dracut-lib.sh
+. /lib/kdump-lib.sh
+
+prepare_parameters()
+{
+ EARLY_KDUMP_CMDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}")
+ KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
+
+ EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}"
+ EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-earlykdump.img"
+}
+
+early_kdump_load()
+{
+ check_kdump_feasibility
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ if is_fadump_capable; then
+ echo "WARNING: early kdump doesn't support fadump."
+ return 1
+ fi
+
+ check_current_kdump_status
+ if [ $? == 0 ]; then
+ return 1
+ fi
+
+ prepare_parameters
+
+ EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}")
+
+ if [ "$KDUMP_FILE_LOAD" == "on" ]; then
+ echo "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
+}
+
+set_early_kdump()
+{
+ if getargbool 0 rd.earlykdump; then
+ echo "early-kdump is enabled."
+ early_kdump_load
+ else
+ echo "early-kdump is disabled."
+ fi
+
+ return 0
+}
+
+set_early_kdump
diff --git a/dracut-kdump-capture.service b/dracut-kdump-capture.service
new file mode 100644
index 0000000..3f20aba
--- /dev/null
+++ b/dracut-kdump-capture.service
@@ -0,0 +1,30 @@
+# 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.
+
+[Unit]
+Description=Kdump Vmcore Save Service
+After=initrd.target initrd-parse-etc.service sysroot.mount
+After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dracut-pre-pivot.service
+Before=initrd-cleanup.service
+ConditionPathExists=/etc/initrd-release
+OnFailure=emergency.target
+OnFailureJobMode=isolate
+
+[Service]
+Environment=DRACUT_SYSTEMD=1
+Environment=NEWROOT=/sysroot
+Type=oneshot
+ExecStart=/bin/kdump.sh
+StandardInput=null
+StandardOutput=syslog
+StandardError=syslog+console
+KillMode=process
+RemainAfterExit=yes
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
diff --git a/dracut-kdump-emergency.service b/dracut-kdump-emergency.service
new file mode 100644
index 0000000..e023284
--- /dev/null
+++ b/dracut-kdump-emergency.service
@@ -0,0 +1,28 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# This service will be placed in kdump initramfs and replace both the systemd
+# emergency service and dracut emergency shell. IOW, any emergency will be
+# kick this service and in turn isolating to kdump error handler.
+
+[Unit]
+Description=Kdump Emergency
+DefaultDependencies=no
+IgnoreOnIsolate=yes
+
+[Service]
+ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service
+Type=oneshot
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
diff --git a/dracut-kdump-emergency.target b/dracut-kdump-emergency.target
new file mode 100644
index 0000000..a1bb493
--- /dev/null
+++ b/dracut-kdump-emergency.target
@@ -0,0 +1,14 @@
+# 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.
+
+[Unit]
+Description=Emergency Mode
+Documentation=man:systemd.special(7)
+Requires=emergency.service
+After=emergency.service
+AllowIsolate=yes
+IgnoreOnIsolate=yes
diff --git a/dracut-kdump-error-handler.service b/dracut-kdump-error-handler.service
new file mode 100644
index 0000000..a23b75e
--- /dev/null
+++ b/dracut-kdump-error-handler.service
@@ -0,0 +1,33 @@
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+# This service will run the real kdump error handler code. Executing the
+# failure action configured in kdump.conf
+
+[Unit]
+Description=Kdump Error Handler
+DefaultDependencies=no
+After=systemd-vconsole-setup.service
+Wants=systemd-vconsole-setup.service
+AllowIsolate=yes
+
+[Service]
+Environment=HOME=/
+Environment=DRACUT_SYSTEMD=1
+Environment=NEWROOT=/sysroot
+WorkingDirectory=/
+ExecStart=/bin/kdump-error-handler.sh
+Type=oneshot
+StandardInput=tty-force
+StandardOutput=inherit
+StandardError=inherit
+KillMode=process
+IgnoreSIGPIPE=no
+
+# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
+# terminates cleanly.
+KillSignal=SIGHUP
diff --git a/dracut-kdump-error-handler.sh b/dracut-kdump-error-handler.sh
new file mode 100755
index 0000000..fc2b932
--- /dev/null
+++ b/dracut-kdump-error-handler.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+. /lib/kdump-lib-initramfs.sh
+
+set -o pipefail
+export PATH=$PATH:$KDUMP_SCRIPT_DIR
+
+get_kdump_confs
+do_failure_action
+do_final_action
diff --git a/dracut-kdump-wait-for-target.sh b/dracut-kdump-wait-for-target.sh
new file mode 100755
index 0000000..ce984d0
--- /dev/null
+++ b/dracut-kdump-wait-for-target.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# only wait if it's kdump kernel
+if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ]; then
+ exit 0
+fi
+
+. /lib/dracut-lib.sh
+. /lib/kdump-lib-initramfs.sh
+
+# For SSH/NFS target, need to wait for the network to setup
+if is_nfs_dump_target; then
+ get_host_ip
+ exit $?
+fi
+
+if is_ssh_dump_target; then
+ get_host_ip
+ exit $?
+fi
+
+# No need to wait for dump target
+exit 0
diff --git a/dracut-kdump.sh b/dracut-kdump.sh
new file mode 100755
index 0000000..0f54ddc
--- /dev/null
+++ b/dracut-kdump.sh
@@ -0,0 +1,182 @@
+#!/bin/sh
+
+# continue here only if we have to save dump.
+if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
+ exit 0
+fi
+
+exec &> /dev/console
+. /lib/dracut-lib.sh
+. /lib/kdump-lib-initramfs.sh
+
+set -o pipefail
+DUMP_RETVAL=0
+
+export PATH=$PATH:$KDUMP_SCRIPT_DIR
+
+do_dump()
+{
+ local _ret
+
+ eval $DUMP_INSTRUCTION
+ _ret=$?
+
+ if [ $_ret -ne 0 ]; then
+ echo "kdump: saving vmcore failed"
+ fi
+
+ return $_ret
+}
+
+do_kdump_pre()
+{
+ if [ -n "$KDUMP_PRE" ]; then
+ "$KDUMP_PRE"
+ fi
+}
+
+do_kdump_post()
+{
+ if [ -n "$KDUMP_POST" ]; then
+ "$KDUMP_POST" "$1"
+ fi
+}
+
+add_dump_code()
+{
+ DUMP_INSTRUCTION=$1
+}
+
+dump_raw()
+{
+ local _raw=$1
+
+ [ -b "$_raw" ] || return 1
+
+ echo "kdump: saving to raw disk $_raw"
+
+ if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
+ _src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
+ _src_size_mb=$(($_src_size / 1048576))
+ monitor_dd_progress $_src_size_mb &
+ fi
+
+ echo "kdump: saving vmcore"
+ $CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
+ sync
+
+ echo "kdump: saving vmcore complete"
+ return 0
+}
+
+dump_ssh()
+{
+ local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
+ local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
+ local _host=$2
+
+ echo "kdump: saving to $_host:$_dir"
+
+ cat /var/lib/random-seed > /dev/urandom
+ ssh -q $_opt $_host mkdir -p $_dir || return 1
+
+ save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
+ save_opalcore_ssh ${_dir} "${_opt}" $_host
+
+ echo "kdump: saving vmcore"
+
+ if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
+ scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" || return 1
+ ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore" || return 1
+ else
+ $CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "dd bs=512 of=$_dir/vmcore-incomplete" || return 1
+ ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/vmcore.flat" || return 1
+ fi
+
+ echo "kdump: saving vmcore complete"
+ return 0
+}
+
+save_opalcore_ssh() {
+ local _path=$1
+ local _opts="$2"
+ local _location=$3
+
+ if [ ! -f $OPALCORE ]; then
+ # Check if we are on an old kernel that uses a different path
+ if [ -f /sys/firmware/opal/core ]; then
+ OPALCORE="/sys/firmware/opal/core"
+ else
+ return 0
+ fi
+ fi
+
+ echo "kdump: saving opalcore"
+ scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete
+ if [ $? -ne 0 ]; then
+ echo "kdump: saving opalcore failed"
+ return 1
+ fi
+
+ ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore
+ echo "kdump: saving opalcore complete"
+ return 0
+}
+
+save_vmcore_dmesg_ssh() {
+ local _dmesg_collector=$1
+ local _path=$2
+ local _opts="$3"
+ local _location=$4
+
+ echo "kdump: saving vmcore-dmesg.txt"
+ $_dmesg_collector /proc/vmcore | ssh $_opts $_location "dd of=$_path/vmcore-dmesg-incomplete.txt"
+ _exitcode=$?
+
+ if [ $_exitcode -eq 0 ]; then
+ ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
+ echo "kdump: saving vmcore-dmesg.txt complete"
+ else
+ echo "kdump: saving vmcore-dmesg.txt failed"
+ fi
+}
+
+fence_kdump_notify()
+{
+ if [ -n "$FENCE_KDUMP_NODES" ]; then
+ $FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
+ fi
+}
+
+read_kdump_conf
+fence_kdump_notify
+
+get_host_ip
+if [ $? -ne 0 ]; then
+ echo "kdump: get_host_ip exited with non-zero status!"
+ exit 1
+fi
+
+if [ -z "$DUMP_INSTRUCTION" ]; then
+ add_dump_code "dump_fs $NEWROOT"
+fi
+
+do_kdump_pre
+if [ $? -ne 0 ]; then
+ echo "kdump: kdump_pre script exited with non-zero status!"
+ do_final_action
+fi
+make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
+do_dump
+DUMP_RETVAL=$?
+
+do_kdump_post $DUMP_RETVAL
+if [ $? -ne 0 ]; then
+ echo "kdump: kdump_post script exited with non-zero status!"
+fi
+
+if [ $DUMP_RETVAL -ne 0 ]; then
+ exit 1
+fi
+
+do_final_action
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
new file mode 100755
index 0000000..899e7ed
--- /dev/null
+++ b/dracut-module-setup.sh
@@ -0,0 +1,846 @@
+#!/bin/bash
+
+. $dracutfunctions
+. /lib/kdump/kdump-lib.sh
+
+if ! [[ -d "${initdir}/tmp" ]]; then
+ mkdir -p "${initdir}/tmp"
+fi
+
+check() {
+ [[ $debug ]] && set -x
+ #kdumpctl sets this explicitly
+ if [ -z "$IN_KDUMP" ] || [ ! -f /etc/kdump.conf ]
+ then
+ return 1
+ fi
+ return 0
+}
+
+depends() {
+ local _dep="base shutdown"
+
+ is_squash_available() {
+ for kmodule in squashfs overlay loop; do
+ if [ -z "$KDUMP_KERNELVER" ]; then
+ modprobe --dry-run $kmodule &>/dev/null || return 1
+ else
+ modprobe -S $KDUMP_KERNELVER --dry-run $kmodule &>/dev/null || return 1
+ fi
+ done
+ }
+
+ if is_squash_available && ! is_fadump_capable; then
+ _dep="$_dep squash"
+ else
+ dwarning "Required modules to build a squashed kdump image is missing!"
+ fi
+
+ if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then
+ _dep="$_dep drm"
+ fi
+
+ if is_generic_fence_kdump || is_pcs_fence_kdump; then
+ _dep="$_dep network"
+ fi
+
+ echo $_dep
+ return 0
+}
+
+kdump_get_persistent_dev() {
+ local dev="${1//\"/}"
+
+ case "$dev" in
+ UUID=*)
+ dev=`blkid -U "${dev#UUID=}"`
+ ;;
+ LABEL=*)
+ dev=`blkid -L "${dev#LABEL=}"`
+ ;;
+ esac
+ echo $(get_persistent_dev "$dev")
+}
+
+kdump_is_bridge() {
+ [ -d /sys/class/net/"$1"/bridge ]
+}
+
+kdump_is_bond() {
+ [ -d /sys/class/net/"$1"/bonding ]
+}
+
+kdump_is_team() {
+ [ -f /usr/bin/teamnl ] && teamnl $1 ports &> /dev/null
+}
+
+kdump_is_vlan() {
+ [ -f /proc/net/vlan/"$1" ]
+}
+
+# $1: netdev name
+source_ifcfg_file() {
+ local ifcfg_file
+
+ ifcfg_file=$(get_ifcfg_filename $1)
+ if [ -f "${ifcfg_file}" ]; then
+ . ${ifcfg_file}
+ else
+ dwarning "The ifcfg file of $1 is not found!"
+ fi
+}
+
+# $1: netdev name
+kdump_setup_dns() {
+ local _nameserver _dns
+ local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
+
+ source_ifcfg_file $1
+
+ [ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile"
+ [ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile"
+
+ while read content;
+ do
+ _nameserver=$(echo $content | grep ^nameserver)
+ [ -z "$_nameserver" ] && continue
+
+ _dns=$(echo $_nameserver | cut -d' ' -f2)
+ [ -z "$_dns" ] && continue
+
+ if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then
+ echo "nameserver=$_dns" >> "$_dnsfile"
+ fi
+ done < "/etc/resolv.conf"
+}
+
+#$1: netdev name
+#$2: srcaddr
+#if it use static ip echo it, or echo null
+kdump_static_ip() {
+ local _netdev="$1" _srcaddr="$2" _ipv6_flag
+ local _netmask _gateway _ipaddr _target _nexthop
+
+ _ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
+
+ if is_ipv6_address $_srcaddr; then
+ _ipv6_flag="-6"
+ fi
+
+ if [ -n "$_ipaddr" ]; then
+ _gateway=$(ip $_ipv6_flag route list dev $_netdev | \
+ awk '/^default /{print $3}' | head -n 1)
+
+ if [ "x" != "x"$_ipv6_flag ]; then
+ # _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/"
+ _netmask=${_ipaddr#*\/}
+ _srcaddr="[$_srcaddr]"
+ _gateway="[$_gateway]"
+ else
+ _netmask=$(ipcalc -m $_ipaddr | cut -d'=' -f2)
+ fi
+ echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
+ fi
+
+ /sbin/ip $_ipv6_flag route show | grep -v default |\
+ grep ".*via.* $_netdev " | grep -v "^[[:space:]]*nexthop" |\
+ while read _route; do
+ _target=`echo $_route | cut -d ' ' -f1`
+ _nexthop=`echo $_route | cut -d ' ' -f3`
+ if [ "x" != "x"$_ipv6_flag ]; then
+ _target="[$_target]"
+ _nexthop="[$_nexthop]"
+ fi
+ echo "rd.route=$_target:$_nexthop:$_netdev"
+ done >> ${initdir}/etc/cmdline.d/45route-static.conf
+
+ kdump_handle_mulitpath_route $_netdev $_srcaddr
+}
+
+kdump_handle_mulitpath_route() {
+ local _netdev="$1" _srcaddr="$2" _ipv6_flag
+ local _target _nexthop _route _weight _max_weight _rule
+
+ if is_ipv6_address $_srcaddr; then
+ _ipv6_flag="-6"
+ fi
+
+ while IFS="" read _route; do
+ if [[ "$_route" =~ [[:space:]]+nexthop ]]; then
+ _route=$(echo "$_route" | sed -e 's/^[[:space:]]*//')
+ # Parse multipath route, using previous _target
+ [[ "$_target" == 'default' ]] && continue
+ [[ "$_route" =~ .*via.*\ $_netdev ]] || continue
+
+ _weight=`echo "$_route" | cut -d ' ' -f7`
+ if [[ "$_weight" -gt "$_max_weight" ]]; then
+ _nexthop=`echo "$_route" | cut -d ' ' -f3`
+ _max_weight=$_weight
+ if [ "x" != "x"$_ipv6_flag ]; then
+ _rule="rd.route=[$_target]:[$_nexthop]:$_netdev"
+ else
+ _rule="rd.route=$_target:$_nexthop:$_netdev"
+ fi
+ fi
+ else
+ [[ -n "$_rule" ]] && echo "$_rule"
+ _target=`echo "$_route" | cut -d ' ' -f1`
+ _rule="" _max_weight=0 _weight=0
+ fi
+ done >> ${initdir}/etc/cmdline.d/45route-static.conf\
+ <<< "$(/sbin/ip $_ipv6_flag route show)"
+
+ [[ -n $_rule ]] && echo $_rule >> ${initdir}/etc/cmdline.d/45route-static.conf
+}
+
+kdump_get_mac_addr() {
+ cat /sys/class/net/$1/address
+}
+
+#Bonding or team master modifies the mac address
+#of its slaves, we should use perm address
+kdump_get_perm_addr() {
+ local addr=$(ethtool -P $1 | sed -e 's/Permanent address: //')
+ if [ -z "$addr" ] || [ "$addr" = "00:00:00:00:00:00" ]
+ then
+ derror "Can't get the permanent address of $1"
+ else
+ echo "$addr"
+ fi
+}
+
+# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0
+# Because kernel assigned names are not persistent between 1st and 2nd
+# kernel. We could probably end up with eth0 being eth1, eth0 being
+# eth1, and naming conflict happens.
+kdump_setup_ifname() {
+ local _ifname
+
+ # If ifname already has 'kdump-' prefix, we must be switching from
+ # fadump to kdump. Skip prefixing 'kdump-' in this case as adding
+ # another prefix may truncate the ifname. Since an ifname with
+ # 'kdump-' is already persistent, this should be fine.
+ if [[ $1 =~ eth* ]] && [[ ! $1 =~ ^kdump-* ]]; then
+ _ifname="kdump-$1"
+ else
+ _ifname="$1"
+ fi
+
+ echo "$_ifname"
+}
+
+kdump_setup_bridge() {
+ local _netdev=$1
+ local _brif _dev _mac _kdumpdev
+ for _dev in /sys/class/net/$_netdev/brif/* ; do
+ [[ -e "$_dev" ]] || break
+ _kdumpdev=$_dev
+ if kdump_is_bond "$_dev"; then
+ kdump_setup_bond "$_dev"
+ elif kdump_is_team "$_dev"; then
+ kdump_setup_team "$_dev"
+ elif kdump_is_vlan "$_dev"; then
+ kdump_setup_vlan "$_dev"
+ else
+ _mac=$(kdump_get_mac_addr $_dev)
+ _kdumpdev=$(kdump_setup_ifname $_dev)
+ echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/41bridge.conf
+ fi
+ _brif+="$_kdumpdev,"
+ done
+ echo " bridge=$_netdev:$(echo $_brif | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/41bridge.conf
+}
+
+kdump_setup_bond() {
+ local _netdev=$1
+ local _dev _mac _slaves _kdumpdev
+ for _dev in `cat /sys/class/net/$_netdev/bonding/slaves`; do
+ _mac=$(kdump_get_perm_addr $_dev)
+ _kdumpdev=$(kdump_setup_ifname $_dev)
+ echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/42bond.conf
+ _slaves+="$_kdumpdev,"
+ done
+ echo -n " bond=$_netdev:$(echo $_slaves | sed 's/,$//')" >> ${initdir}/etc/cmdline.d/42bond.conf
+ # Get bond options specified in ifcfg
+
+ source_ifcfg_file $_netdev
+
+ bondoptions=":$(echo $BONDING_OPTS | xargs echo | tr " " ",")"
+ echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf
+}
+
+kdump_setup_team() {
+ local _netdev=$1
+ local _dev _mac _slaves _kdumpdev
+ for _dev in `teamnl $_netdev ports | awk -F':' '{print $2}'`; do
+ _mac=$(kdump_get_perm_addr $_dev)
+ _kdumpdev=$(kdump_setup_ifname $_dev)
+ echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/44team.conf
+ _slaves+="$_kdumpdev,"
+ done
+ echo " team=$_netdev:$(echo $_slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf
+ #Buggy version teamdctl outputs to stderr!
+ #Try to use the latest version of teamd.
+ teamdctl "$_netdev" config dump > ${initdir}/tmp/$$-$_netdev.conf
+ if [ $? -ne 0 ]
+ then
+ derror "teamdctl failed."
+ exit 1
+ fi
+ inst_dir /etc/teamd
+ inst_simple ${initdir}/tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf"
+ rm -f ${initdir}/tmp/$$-$_netdev.conf
+}
+
+kdump_setup_vlan() {
+ local _netdev=$1
+ local _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
+ local _netmac="$(kdump_get_mac_addr $_phydev)"
+ local _kdumpdev
+
+ #Just support vlan over bond, it is not easy
+ #to support all other complex setup
+ if kdump_is_bridge "$_phydev"; then
+ derror "Vlan over bridge is not supported!"
+ exit 1
+ elif kdump_is_team "$_phydev"; then
+ derror "Vlan over team is not supported!"
+ exit 1
+ elif kdump_is_bond "$_phydev"; then
+ kdump_setup_bond "$_phydev"
+ echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf
+ else
+ _kdumpdev="$(kdump_setup_ifname $_phydev)"
+ echo " vlan=$(kdump_setup_ifname $_netdev):$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf
+ fi
+}
+
+# setup s390 znet cmdline
+# $1: netdev name
+kdump_setup_znet() {
+ local _options=""
+
+ source_ifcfg_file $1
+
+ for i in $OPTIONS; do
+ _options=${_options},$i
+ done
+ echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} > ${initdir}/etc/cmdline.d/30znet.conf
+}
+
+kdump_get_ip_route()
+{
+ local _route=$(/sbin/ip -o route get to $1 2>&1)
+ [ $? != 0 ] && die "Bad kdump network destination: $1"
+ echo $_route
+}
+
+kdump_get_ip_route_field()
+{
+ if `echo $1 | grep -q $2`; then
+ echo ${1##*$2} | cut -d ' ' -f1
+ fi
+}
+
+kdump_get_remote_ip()
+{
+ local _remote=$(get_remote_host $1) _remote_temp
+ if is_hostname $_remote; then
+ _remote_temp=`getent ahosts $_remote | grep -v : | head -n 1`
+ if [ -z "$_remote_temp" ]; then
+ _remote_temp=`getent ahosts $_remote | head -n 1`
+ fi
+ _remote=`echo $_remote_temp | cut -d' ' -f1`
+ fi
+ echo $_remote
+}
+
+# Setup dracut to bring up network interface that enable
+# initramfs accessing giving destination
+# $1: destination host
+kdump_install_net() {
+ local _destaddr _srcaddr _route _netdev
+ local _static _proto _ip_conf _ip_opts _ifname_opts
+
+ _destaddr=$(kdump_get_remote_ip $1)
+ _route=$(kdump_get_ip_route $_destaddr)
+ _srcaddr=$(kdump_get_ip_route_field "$_route" "src")
+ _netdev=$(kdump_get_ip_route_field "$_route" "dev")
+ _netmac=$(kdump_get_mac_addr $_netdev)
+
+ if [ "$(uname -m)" = "s390x" ]; then
+ kdump_setup_znet $_netdev
+ fi
+
+ _static=$(kdump_static_ip $_netdev $_srcaddr)
+ if [ -n "$_static" ]; then
+ _proto=none
+ elif is_ipv6_address $_srcaddr; then
+ _proto=either6
+ else
+ _proto=dhcp
+ fi
+
+ _ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
+ _ip_opts=" ip=${_static}$(kdump_setup_ifname $_netdev):${_proto}"
+
+ # dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same.
+ # so we have to avoid adding duplicates
+ # We should also check /proc/cmdline for existing ip=xx arg.
+ # For example, iscsi boot will specify ip=xxx arg in cmdline.
+ if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\
+ ! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
+ echo "$_ip_opts" >> $_ip_conf
+ fi
+
+ if kdump_is_bridge "$_netdev"; then
+ kdump_setup_bridge "$_netdev"
+ elif kdump_is_bond "$_netdev"; then
+ kdump_setup_bond "$_netdev"
+ elif kdump_is_team "$_netdev"; then
+ kdump_setup_team "$_netdev"
+ elif kdump_is_vlan "$_netdev"; then
+ kdump_setup_vlan "$_netdev"
+ else
+ _ifname_opts=" ifname=$(kdump_setup_ifname $_netdev):$_netmac"
+ echo "$_ifname_opts" >> $_ip_conf
+ fi
+
+ kdump_setup_dns "$_netdev"
+
+ # Save netdev used for kdump as cmdline
+ # Whoever calling kdump_install_net() is setting up the default gateway,
+ # ie. bootdev/kdumpnic. So don't override the setting if calling
+ # kdump_install_net() for another time. For example, after setting eth0 as
+ # the default gate way for network dump, eth1 in the fence kdump path will
+ # call kdump_install_net again and we don't want eth1 to be the default
+ # gateway.
+ if [ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ] &&
+ [ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]; then
+ echo "kdumpnic=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/60kdumpnic.conf
+ echo "bootdev=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/70bootdev.conf
+ fi
+}
+
+default_dump_target_install_conf()
+{
+ local _target _fstype
+ local _mntpoint _save_path
+
+ is_user_configured_dump_target && return
+
+ _save_path=$(get_bind_mount_source $(get_save_path))
+ _target=$(get_target_from_path $_save_path)
+ _mntpoint=$(get_mntpoint_from_target $_target)
+
+ _fstype=$(get_fs_type_from_target $_target)
+ if is_fs_type_nfs $_fstype; then
+ kdump_install_net "$_target"
+ _fstype="nfs"
+ else
+ _target=$(kdump_get_persistent_dev $_target)
+ fi
+
+ echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf
+
+ # don't touch the path under root mount
+ if [ "$_mntpoint" != "/" ]; then
+ _save_path=${_save_path##"$_mntpoint"}
+ fi
+
+ #erase the old path line, then insert the parsed path
+ sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf
+ echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf
+}
+
+#install kdump.conf and what user specifies in kdump.conf
+kdump_install_conf() {
+ local _opt _val _pdev
+ (read_strip_comments /etc/kdump.conf) > ${initdir}/tmp/$$-kdump.conf
+
+ while read _opt _val;
+ do
+ # remove inline comments after the end of a directive.
+ case "$_opt" in
+ raw)
+ _pdev=$(persistent_policy="by-id" kdump_get_persistent_dev $_val)
+ sed -i -e "s#^${_opt}[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
+ ;;
+ ext[234]|xfs|btrfs|minix)
+ _pdev=$(kdump_get_persistent_dev $_val)
+ sed -i -e "s#^${_opt}[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
+ ;;
+ ssh|nfs)
+ kdump_install_net "$_val"
+ ;;
+ dracut_args)
+ if [[ $(get_dracut_args_fstype "$_val") = nfs* ]] ; then
+ kdump_install_net "$(get_dracut_args_target "$_val")"
+ fi
+ ;;
+ kdump_pre|kdump_post|extra_bins)
+ dracut_install $_val
+ ;;
+ core_collector)
+ dracut_install "${_val%%[[:blank:]]*}"
+ ;;
+ esac
+ done <<< "$(read_strip_comments /etc/kdump.conf)"
+
+ default_dump_target_install_conf
+
+ kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf"
+ inst "${initdir}/tmp/$$-kdump.conf" "/etc/kdump.conf"
+ rm -f ${initdir}/tmp/$$-kdump.conf
+}
+
+# Remove user custom configurations sysctl.conf & sysctl.d/*
+# and apply some optimization for kdump
+overwrite_sysctl_conf() {
+ # As custom configurations like vm.min_free_kbytes can lead
+ # to OOM issues in kdump kernel, avoid them
+ rm -f "${initdir}/etc/sysctl.conf"
+ rm -rf "${initdir}/etc/sysctl.d"
+ rm -rf "${initdir}/run/sysctl.d"
+ rm -rf "${initdir}/usr/lib/sysctl.d"
+
+ mkdir -p "${initdir}/etc/sysctl.d"
+ echo "vm.zone_reclaim_mode = 3" > "${initdir}/etc/sysctl.d/99-zone-reclaim.conf"
+}
+
+kdump_iscsi_get_rec_val() {
+
+ local result
+
+ # The open-iscsi 742 release changed to using flat files in
+ # /var/lib/iscsi.
+
+ result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = ")
+ result=${result##* = }
+ echo $result
+}
+
+kdump_get_iscsi_initiator() {
+ local _initiator
+ local initiator_conf="/etc/iscsi/initiatorname.iscsi"
+
+ [ -f "$initiator_conf" ] || return 1
+
+ while read _initiator; do
+ [ -z "${_initiator%%#*}" ] && continue # Skip comment lines
+
+ case $_initiator in
+ InitiatorName=*)
+ initiator=${_initiator#InitiatorName=}
+ echo "rd.iscsi.initiator=${initiator}"
+ return 0;;
+ *) ;;
+ esac
+ done < ${initiator_conf}
+
+ return 1
+}
+
+# Figure out iBFT session according to session type
+is_ibft() {
+ [ "$(kdump_iscsi_get_rec_val $1 "node.discovery_type")" = fw ]
+}
+
+kdump_setup_iscsi_device() {
+ local path=$1
+ local tgt_name; local tgt_ipaddr;
+ local username; local password; local userpwd_str;
+ local username_in; local password_in; local userpwd_in_str;
+ local netroot_str ; local initiator_str;
+ local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf"
+ local initiator_conf="/etc/iscsi/initiatorname.iscsi"
+
+ dinfo "Found iscsi component $1"
+
+ # Check once before getting explicit values, so we can bail out early,
+ # e.g. in case of pure-hardware(all-offload) iscsi.
+ if ! /sbin/iscsiadm -m session -r ${path} &>/dev/null ; then
+ return 1
+ fi
+
+ if is_ibft ${path}; then
+ return
+ fi
+
+ # Remove software iscsi cmdline generated by 95iscsi,
+ # and let kdump regenerate here.
+ rm -f ${initdir}/etc/cmdline.d/95iscsi.conf
+
+ tgt_name=$(kdump_iscsi_get_rec_val ${path} "node.name")
+ tgt_ipaddr=$(kdump_iscsi_get_rec_val ${path} "node.conn\[0\].address")
+
+ # get and set username and password details
+ username=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username")
+ [ "$username" == "<empty>" ] && username=""
+ password=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password")
+ [ "$password" == "<empty>" ] && password=""
+ username_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username_in")
+ [ -n "$username" ] && userpwd_str="$username:$password"
+
+ # get and set incoming username and password details
+ [ "$username_in" == "<empty>" ] && username_in=""
+ password_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password_in")
+ [ "$password_in" == "<empty>" ] && password_in=""
+
+ [ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in"
+
+ kdump_install_net "$tgt_ipaddr"
+
+ # prepare netroot= command line
+ # FIXME: Do we need to parse and set other parameters like protocol, port
+ # iscsi_iface_name, netdev_name, LUN etc.
+
+ if is_ipv6_address $tgt_ipaddr; then
+ tgt_ipaddr="[$tgt_ipaddr]"
+ fi
+ netroot_str="netroot=iscsi:${userpwd_str}${userpwd_in_str}@$tgt_ipaddr::::$tgt_name"
+
+ [[ -f $netroot_conf ]] || touch $netroot_conf
+
+ # If netroot target does not exist already, append.
+ if ! grep -q $netroot_str $netroot_conf; then
+ echo $netroot_str >> $netroot_conf
+ dinfo "Appended $netroot_str to $netroot_conf"
+ fi
+
+ # Setup initator
+ initiator_str=$(kdump_get_iscsi_initiator)
+ [ $? -ne "0" ] && derror "Failed to get initiator name" && return 1
+
+ # If initiator details do not exist already, append.
+ if ! grep -q "$initiator_str" $netroot_conf; then
+ echo "$initiator_str" >> $netroot_conf
+ dinfo "Appended "$initiator_str" to $netroot_conf"
+ fi
+}
+
+kdump_check_iscsi_targets () {
+ # If our prerequisites are not met, fail anyways.
+ type -P iscsistart >/dev/null || return 1
+
+ kdump_check_setup_iscsi() (
+ local _dev
+ _dev=$1
+
+ [[ -L /sys/dev/block/$_dev ]] || return
+ cd "$(readlink -f /sys/dev/block/$_dev)"
+ until [[ -d sys || -d iscsi_session ]]; do
+ cd ..
+ done
+ [[ -d iscsi_session ]] && kdump_setup_iscsi_device "$PWD"
+ )
+
+ [[ $hostonly ]] || [[ $mount_needs ]] && {
+ for_each_host_dev_and_slaves_all kdump_check_setup_iscsi
+ }
+}
+
+# hostname -a is deprecated, do it by ourself
+get_alias() {
+ local ips
+ local entries
+ local alias_set
+
+ ips=$(hostname -I)
+ for ip in $ips
+ do
+ # in /etc/hosts, alias can come at the 2nd column
+ entries=$(grep $ip /etc/hosts | awk '{ $1=""; print $0 }')
+ if [ $? -eq 0 ]; then
+ alias_set="$alias_set $entries"
+ fi
+ done
+
+ echo $alias_set
+}
+
+is_localhost() {
+ local hostnames=$(hostname -A)
+ local shortnames=$(hostname -A -s)
+ local aliasname=$(get_alias)
+ local nodename=$1
+
+ hostnames="$hostnames $shortnames $aliasname"
+
+ for name in ${hostnames}; do
+ if [ "$name" == "$nodename" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+# retrieves fence_kdump nodes from Pacemaker cluster configuration
+get_pcs_fence_kdump_nodes() {
+ local nodes
+
+ # get cluster nodes from cluster cib, get interface and ip address
+ nodelist=`pcs cluster cib | xmllint --xpath "/cib/status/node_state/@uname" -`
+
+ # nodelist is formed as 'uname="node1" uname="node2" ... uname="nodeX"'
+ # we need to convert each to node1, node2 ... nodeX in each iteration
+ for node in ${nodelist}; do
+ # convert $node from 'uname="nodeX"' to 'nodeX'
+ eval $node
+ nodename=$uname
+ # Skip its own node name
+ if is_localhost $nodename; then
+ continue
+ fi
+ nodes="$nodes $nodename"
+ done
+
+ echo $nodes
+}
+
+# retrieves fence_kdump args from config file
+get_pcs_fence_kdump_args() {
+ if [ -f $FENCE_KDUMP_CONFIG_FILE ]; then
+ . $FENCE_KDUMP_CONFIG_FILE
+ echo $FENCE_KDUMP_OPTS
+ fi
+}
+
+get_generic_fence_kdump_nodes() {
+ local filtered
+ local nodes
+
+ nodes=$(get_option_value "fence_kdump_nodes")
+ for node in ${nodes}; do
+ # Skip its own node name
+ if is_localhost $node; then
+ continue
+ fi
+ filtered="$filtered $node"
+ done
+ echo $filtered
+}
+
+# setup fence_kdump in cluster
+# setup proper network and install needed files
+kdump_configure_fence_kdump () {
+ local kdump_cfg_file=$1
+ local nodes
+ local args
+
+ if is_generic_fence_kdump; then
+ nodes=$(get_generic_fence_kdump_nodes)
+
+ elif is_pcs_fence_kdump; then
+ nodes=$(get_pcs_fence_kdump_nodes)
+
+ # set appropriate options in kdump.conf
+ echo "fence_kdump_nodes $nodes" >> ${kdump_cfg_file}
+
+ args=$(get_pcs_fence_kdump_args)
+ if [ -n "$args" ]; then
+ echo "fence_kdump_args $args" >> ${kdump_cfg_file}
+ fi
+
+ else
+ # fence_kdump not configured
+ return 1
+ fi
+
+ # setup network for each node
+ for node in ${nodes}; do
+ kdump_install_net $node
+ done
+
+ dracut_install /etc/hosts
+ dracut_install /etc/nsswitch.conf
+ dracut_install $FENCE_KDUMP_SEND
+}
+
+# Install a random seed used to feed /dev/urandom
+# By the time kdump service starts, /dev/uramdom is already fed by systemd
+kdump_install_random_seed() {
+ local poolsize=`cat /proc/sys/kernel/random/poolsize`
+
+ if [ ! -d ${initdir}/var/lib/ ]; then
+ mkdir -p ${initdir}/var/lib/
+ fi
+
+ dd if=/dev/urandom of=${initdir}/var/lib/random-seed \
+ bs=$poolsize count=1 2> /dev/null
+}
+
+install() {
+ kdump_install_conf
+ overwrite_sysctl_conf
+
+ if is_ssh_dump_target; then
+ kdump_install_random_seed
+ fi
+ dracut_install -o /etc/adjtime /etc/localtime
+ inst "$moddir/monitor_dd_progress" "/kdumpscripts/monitor_dd_progress"
+ chmod +x ${initdir}/kdumpscripts/monitor_dd_progress
+ inst "/bin/dd" "/bin/dd"
+ inst "/bin/tail" "/bin/tail"
+ inst "/bin/date" "/bin/date"
+ inst "/bin/sync" "/bin/sync"
+ inst "/bin/cut" "/bin/cut"
+ inst "/bin/head" "/bin/head"
+ inst "/bin/awk" "/bin/awk"
+ inst "/bin/sed" "/bin/sed"
+ inst "/sbin/makedumpfile" "/sbin/makedumpfile"
+ inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg"
+ inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
+ inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh"
+ inst "$moddir/kdump.sh" "/usr/bin/kdump.sh"
+ inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service"
+ mkdir -p "$initdir/$systemdsystemunitdir/initrd.target.wants"
+ ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service"
+ inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh"
+ inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service"
+ # Replace existing emergency service and emergency target
+ cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service"
+ cp "$moddir/kdump-emergency.target" "$initdir/$systemdsystemunitdir/emergency.target"
+ # Also redirect dracut-emergency to kdump error handler
+ ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service"
+
+ # Check for all the devices and if any device is iscsi, bring up iscsi
+ # target. Ideally all this should be pushed into dracut iscsi module
+ # at some point of time.
+ kdump_check_iscsi_targets
+
+ # nfs/ssh dump will need to get host ip in second kernel and need to call 'ip' tool, see get_host_ip for more detail
+ # also need to let initqueue wait for target to become ready
+ if is_nfs_dump_target || is_ssh_dump_target; then
+ inst_hook initqueue/finished 01 $moddir/kdump-wait-for-target.sh
+ inst "ip"
+ fi
+
+ # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
+ # safely replace "reserved_memory=XXXX"(default value is 8192) with
+ # "reserved_memory=1024" to lower memory pressure under kdump. We do
+ # it unconditionally here, if "/etc/lvm/lvm.conf" doesn't exist, it
+ # actually does nothing.
+ sed -i -e \
+ 's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1 1024/' \
+ ${initdir}/etc/lvm/lvm.conf &>/dev/null
+
+ # Kdump turns out to require longer default systemd mount timeout
+ # than 1st kernel(90s by default), we use default 300s for kdump.
+ grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null
+ if [ $? -ne 0 ]; then
+ mkdir -p ${initdir}/etc/systemd/system.conf.d
+ echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf
+ echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf
+ fi
+
+ # Forward logs to console directly, this avoids unneccessary memory
+ # consumption and make console output more useful.
+ # Only do so for non fadump image.
+ if ! is_fadump_capable; then
+ mkdir -p ${initdir}/etc/systemd/journald.conf.d
+ echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf
+ echo "Storage=none" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
+ echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
+ fi
+}
diff --git a/dracut-monitor_dd_progress b/dracut-monitor_dd_progress
new file mode 100644
index 0000000..e139d33
--- /dev/null
+++ b/dracut-monitor_dd_progress
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+SRC_FILE_MB=$1
+
+while true
+do
+ DD_PID=`pidof dd`
+ if [ -n "$DD_PID" ]; then
+ break
+ fi
+done
+
+while true
+do
+ sleep 5
+ if [ ! -d /proc/$DD_PID ]; then
+ break
+ fi
+
+ kill -s USR1 $DD_PID
+ CURRENT_SIZE=`tail -n 1 /tmp/dd_progress_file | sed "s/[^0-9].*//g"`
+ [ -n "$CURRENT_SIZE" ] && {
+ CURRENT_MB=$(($CURRENT_SIZE / 1048576))
+ echo -e "Copied $CURRENT_MB MB / $SRC_FILE_MB MB\r"
+ }
+done
+
+rm -f /tmp/dd_progress_file
diff --git a/early-kdump-howto.txt b/early-kdump-howto.txt
new file mode 100644
index 0000000..68b23c7
--- /dev/null
+++ b/early-kdump-howto.txt
@@ -0,0 +1,95 @@
+Early Kdump HOWTO
+
+Introduction
+------------
+
+Early kdump is a mechanism to make kdump operational earlier than normal kdump
+service. The kdump service starts early enough for general crash cases, but
+there are some cases where it has no chance to make kdump operational in boot
+sequence, such as detecting devices and starting early services. If you hit
+such a case, early kdump may allow you to get more information of it.
+
+Early kdump is implemented as a dracut module. It adds a kernel (vmlinuz) and
+initramfs for kdump to your system's initramfs in order to load them as early
+as possible. After that, if you provide "rd.earlykdump" in kernel command line,
+then in the initramfs, early kdump will load those files like the normal kdump
+service. This is disabled by default.
+
+For the normal kdump service, it can check whether the early kdump has loaded
+the crash kernel and initramfs. 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.
+
+You can rebuild the initramfs with earlykdump support with below steps:
+
+1. start kdump service to make sure kdump initramfs is created.
+
+ # systemctl start kdump
+
+ NOTE: If a crash occurs during boot process, early kdump captures a vmcore
+ and reboot the system by default, so the system might go into crash loop.
+ You can avoid such a crash loop by adding the following settings, which
+ power off the system after dump capturing, to kdump.conf in advance:
+
+ final_action poweroff
+ failure_action poweroff
+
+ For the failure_action, you can choose anything other than "reboot".
+
+2. rebuild system initramfs with earlykdump support.
+
+ # dracut --force --add earlykdump
+
+ NOTE: Recommend to backup the original system initramfs before performing
+ this step to put it back if something happens during boot-up.
+
+3. add rd.earlykdump in grub kernel command line.
+
+After making said changes, reboot your system to take effect. Of course, if you
+want to disable early kdump, you can simply remove "rd.earlykdump" from kernel
+boot parameters in grub, and reboot system like above.
+
+Once the boot is completed, you can check the status of the early kdump support
+on the command prompt:
+
+ # journalctl -b | grep early-kdump
+
+Then, you will see some useful logs, for example:
+
+- if early kdump is successful.
+
+Mar 09 09:57:56 localhost dracut-cmdline[190]: early-kdump is enabled.
+Mar 09 09:57:56 localhost dracut-cmdline[190]: kexec: loaded early-kdump kernel
+
+- if early kdump is disabled.
+
+Mar 09 10:02:47 localhost dracut-cmdline[189]: early-kdump is disabled.
+
+Notes
+-----
+
+- The size of early kdump initramfs will be large because it includes vmlinuz
+ and kdump initramfs.
+
+- Early kdump inherits the settings of normal kdump, so any changes that
+ caused normal kdump rebuilding also require rebuilding the system initramfs
+ to make sure that the changes take effect for early kdump. Therefore, after
+ the rebuilding of kdump initramfs is completed, provide a prompt message to
+ tell the fact.
+
+- If you install an updated kernel and reboot the system with it, the early
+ kdump will be disabled by default. To enable it with the new kernel, you
+ need to take the above steps again.
+
+Limitation
+----------
+
+- At present, early kdump doesn't support fadump.
+
+- Early kdump loads a crash kernel and initramfs at the beginning of the
+ process in system's initramfs, so a crash at earlier than that (e.g. in
+ kernel initialization) cannot be captured even with the early kdump.
diff --git a/kdump-dep-generator.sh b/kdump-dep-generator.sh
new file mode 100644
index 0000000..b6fab2d
--- /dev/null
+++ b/kdump-dep-generator.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# More details about systemd generator:
+# http://www.freedesktop.org/wiki/Software/systemd/Generators/
+
+. /usr/lib/kdump/kdump-lib.sh
+
+# If invokded with no arguments for testing purpose, output to /tmp to
+# avoid overriding the existing.
+dest_dir="/tmp"
+
+if [ -n "$1" ]; then
+ dest_dir=$1
+fi
+
+systemd_dir=/usr/lib/systemd/system
+kdump_wants=$dest_dir/kdump.service.wants
+
+if is_ssh_dump_target; then
+ mkdir -p $kdump_wants
+ ln -sf $systemd_dir/network-online.target $kdump_wants/
+fi
diff --git a/kdump-in-cluster-environment.txt b/kdump-in-cluster-environment.txt
new file mode 100644
index 0000000..de1eb5e
--- /dev/null
+++ b/kdump-in-cluster-environment.txt
@@ -0,0 +1,91 @@
+Kdump-in-cluster-environment HOWTO
+
+Introduction
+
+Kdump is a kexec based crash dumping mechansim for Linux. This docuement
+illustrate how to configure kdump in cluster environment to allow the kdump
+crash recovery service complete without being preempted by traditional power
+fencing methods.
+
+Overview
+
+Kexec/Kdump
+
+Details about Kexec/Kdump are available in Kexec-Kdump-howto file and will not
+be described here.
+
+fence_kdump
+
+fence_kdump is an I/O fencing agent to be used with the kdump crash recovery
+service. When the fence_kdump agent is invoked, it will listen for a message
+from the failed node that acknowledges that the failed node is executing the
+kdump crash kernel. Note that fence_kdump is not a replacement for traditional
+fencing methods. The fence_kdump agent can only detect that a node has entered
+the kdump crash recovery service. This allows the kdump crash recovery service
+complete without being preempted by traditional power fencing methods.
+
+fence_kdump_send
+
+fence_kdump_send is a utility used to send messages that acknowledge that the
+node itself has entered the kdump crash recovery service. The fence_kdump_send
+utility is typically run in the kdump kernel after a cluster node has
+encountered a kernel panic. Once the cluster node has entered the kdump crash
+recovery service, fence_kdump_send will periodically send messages to all
+cluster nodes. When the fence_kdump agent receives a valid message from the
+failed nodes, fencing is complete.
+
+How to configure Pacemaker cluster environment:
+
+If we want to use kdump in Pacemaker cluster environment, fence-agents-kdump
+should be installed in every nodes in the cluster. You can achieve this via
+the following command:
+
+ # yum install -y fence-agents-kdump
+
+Next is to add kdump_fence to the cluster. Assuming that the cluster consists
+of three nodes, they are node1, node2 and node3, and use Pacemaker to perform
+resource management and pcs as cli configuration tool.
+
+With pcs it is easy to add a stonith resource to the cluster. For example, add
+a stonith resource named mykdumpfence with fence type of fence_kdump via the
+following commands:
+
+ # pcs stonith create mykdumpfence fence_kdump \
+ pcmk_host_check=static-list pcmk_host_list="node1 node2 node3"
+ # pcs stonith update mykdumpfence pcmk_monitor_action=metadata --force
+ # pcs stonith update mykdumpfence pcmk_status_action=metadata --force
+ # pcs stonith update mykdumpfence pcmk_reboot_action=off --force
+
+Then enable stonith
+ # pcs property set stonith-enabled=true
+
+How to configure kdump:
+
+Actually there are two ways how to configure fence_kdump support:
+
+1) Pacemaker based clusters
+ If you have successfully configured fence_kdump in Pacemaker, there is
+ no need to add some special configuration in kdump. So please refer to
+ Kexec-Kdump-howto file for more information.
+
+2) Generic clusters
+ For other types of clusters there are two configuration options in
+ kdump.conf which enables fence_kdump support:
+
+ fence_kdump_nodes <node(s)>
+ Contains list of cluster node(s) separated by space to send
+ fence_kdump notification to (this option is mandatory to enable
+ fence_kdump)
+
+ fence_kdump_args <arg(s)>
+ Command line arguments for fence_kdump_send (it can contain
+ all valid arguments except hosts to send notification to)
+
+ These options will most probably be configured by your cluster software,
+ so please refer to your cluster documentation how to enable fence_kdump
+ support.
+
+Please be aware that these two ways cannot be combined and 2) has precedence
+over 1). It means that if fence_kdump is configured using fence_kdump_nodes
+and fence_kdump_args options in kdump.conf, Pacemaker configuration is not
+used even if it exists.
diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh
new file mode 100755
index 0000000..03949ea
--- /dev/null
+++ b/kdump-lib-initramfs.sh
@@ -0,0 +1,277 @@
+# These variables and functions are useful in 2nd kernel
+
+. /lib/kdump-lib.sh
+
+KDUMP_PATH="/var/crash"
+CORE_COLLECTOR=""
+DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -d 31"
+DMESG_COLLECTOR="/sbin/vmcore-dmesg"
+FAILURE_ACTION="systemctl reboot -f"
+DATEDIR=`date +%Y-%m-%d-%T`
+HOST_IP='127.0.0.1'
+DUMP_INSTRUCTION=""
+SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
+KDUMP_SCRIPT_DIR="/kdumpscripts"
+DD_BLKSIZE=512
+FINAL_ACTION="systemctl reboot -f"
+KDUMP_CONF="/etc/kdump.conf"
+KDUMP_PRE=""
+KDUMP_POST=""
+NEWROOT="/sysroot"
+OPALCORE="/sys/firmware/opal/mpipl/core"
+
+get_kdump_confs()
+{
+ local config_opt config_val
+
+ while read config_opt config_val;
+ do
+ # remove inline comments after the end of a directive.
+ case "$config_opt" in
+ path)
+ KDUMP_PATH="$config_val"
+ ;;
+ core_collector)
+ [ -n "$config_val" ] && CORE_COLLECTOR="$config_val"
+ ;;
+ sshkey)
+ if [ -f "$config_val" ]; then
+ SSH_KEY_LOCATION=$config_val
+ fi
+ ;;
+ kdump_pre)
+ KDUMP_PRE="$config_val"
+ ;;
+ kdump_post)
+ KDUMP_POST="$config_val"
+ ;;
+ fence_kdump_args)
+ FENCE_KDUMP_ARGS="$config_val"
+ ;;
+ fence_kdump_nodes)
+ FENCE_KDUMP_NODES="$config_val"
+ ;;
+ failure_action|default)
+ case $config_val in
+ shell)
+ FAILURE_ACTION="kdump_emergency_shell"
+ ;;
+ reboot)
+ FAILURE_ACTION="systemctl reboot -f && exit"
+ ;;
+ halt)
+ FAILURE_ACTION="halt && exit"
+ ;;
+ poweroff)
+ FAILURE_ACTION="systemctl poweroff -f && exit"
+ ;;
+ dump_to_rootfs)
+ FAILURE_ACTION="dump_to_rootfs"
+ ;;
+ esac
+ ;;
+ final_action)
+ case $config_val in
+ reboot)
+ FINAL_ACTION="systemctl reboot -f"
+ ;;
+ halt)
+ FINAL_ACTION="halt"
+ ;;
+ poweroff)
+ FINAL_ACTION="systemctl poweroff -f"
+ ;;
+ esac
+ ;;
+ esac
+ done <<< "$(read_strip_comments $KDUMP_CONF)"
+
+ if [ -z "$CORE_COLLECTOR" ]; then
+ CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR"
+ if is_ssh_dump_target || is_raw_dump_target; then
+ CORE_COLLECTOR="$CORE_COLLECTOR -F"
+ fi
+ fi
+}
+
+# dump_fs <mount point| device>
+dump_fs()
+{
+ local _do_umount=""
+ local _dev=$(findmnt -k -f -n -r -o SOURCE $1)
+ local _mp=$(findmnt -k -f -n -r -o TARGET $1)
+ local _op=$(findmnt -k -f -n -r -o OPTIONS $1)
+
+ if [ -z "$_mp" ]; then
+ _dev=$(findmnt -s -f -n -r -o SOURCE $1)
+ _mp=$(findmnt -s -f -n -r -o TARGET $1)
+ _op=$(findmnt -s -f -n -r -o OPTIONS $1)
+
+ if [ -n "$_dev" ] && [ -n "$_mp" ]; then
+ echo "kdump: dump target $_dev is not mounted, trying to mount..."
+ mkdir -p $_mp
+ mount -o $_op $_dev $_mp
+
+ if [ $? -ne 0 ]; then
+ echo "kdump: mounting failed (mount point: $_mp, option: $_op)"
+ return 1
+ fi
+ _do_umount=1
+ else
+ echo "kdump: error: Dump target $_dev is not usable"
+ fi
+ else
+ echo "kdump: dump target is $_dev"
+ fi
+
+ # Remove -F in makedumpfile case. We don't want a flat format dump here.
+ [[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"`
+
+ echo "kdump: saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
+
+ # Only remount to read-write mode if the dump target is mounted read-only.
+ if [[ "$_op" = "ro"* ]]; then
+ echo "kdump: Mounting Dump target $_dev in rw mode."
+ mount -o remount,rw $_dev $_mp || return 1
+ fi
+
+ mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1
+
+ save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
+ save_opalcore_fs "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/"
+
+ echo "kdump: saving vmcore"
+ $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1
+ mv $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore
+ sync
+
+ echo "kdump: saving vmcore complete"
+
+ if [ $_do_umount ]; then
+ umount $_mp || echo "kdump: warn: failed to umount target"
+ fi
+
+ # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure
+ return 0
+}
+
+save_vmcore_dmesg_fs() {
+ local _dmesg_collector=$1
+ local _path=$2
+
+ echo "kdump: saving vmcore-dmesg.txt"
+ $_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt
+ _exitcode=$?
+ if [ $_exitcode -eq 0 ]; then
+ mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt
+ chmod 400 ${_path}/vmcore-dmesg.txt
+ # Make sure file is on disk. There have been instances where later
+ # saving vmcore failed and system rebooted without sync and there
+ # was no vmcore-dmesg.txt available.
+ sync
+ echo "kdump: saving vmcore-dmesg.txt complete"
+ else
+ echo "kdump: saving vmcore-dmesg.txt failed"
+ fi
+}
+
+save_opalcore_fs() {
+ local _path=$1
+
+ if [ ! -f $OPALCORE ]; then
+ # Check if we are on an old kernel that uses a different path
+ if [ -f /sys/firmware/opal/core ]; then
+ OPALCORE="/sys/firmware/opal/core"
+ else
+ return 0
+ fi
+ fi
+
+ echo "kdump: saving opalcore"
+ cp $OPALCORE ${_path}/opalcore
+ if [ $? -ne 0 ]; then
+ echo "kdump: saving opalcore failed"
+ return 1
+ fi
+
+ sync
+ echo "kdump: saving opalcore complete"
+ return 0
+}
+
+dump_to_rootfs()
+{
+
+ echo "Kdump: trying to bring up rootfs device"
+ systemctl start dracut-initqueue
+ echo "Kdump: waiting for rootfs mount, will timeout after 90 seconds"
+ systemctl start sysroot.mount
+
+ dump_fs $NEWROOT
+}
+
+kdump_emergency_shell()
+{
+ echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile
+ /bin/dracut-emergency
+ rm -f /etc/profile
+}
+
+do_failure_action()
+{
+ echo "Kdump: Executing failure action $FAILURE_ACTION"
+ eval $FAILURE_ACTION
+}
+
+do_final_action()
+{
+ eval $FINAL_ACTION
+}
+
+get_host_ip()
+{
+ local _host
+ if is_nfs_dump_target || is_ssh_dump_target
+ then
+ kdumpnic=$(getarg kdumpnic=)
+ [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1
+ _host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
+ [ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
+ _host=`echo $_host | head -n 1 | cut -d' ' -f2`
+ _host="${_host%%/*}"
+ [ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1
+ HOST_IP=$_host
+ fi
+ return 0
+}
+
+read_kdump_conf()
+{
+ if [ ! -f "$KDUMP_CONF" ]; then
+ echo "kdump: $KDUMP_CONF not found"
+ return
+ fi
+
+ get_kdump_confs
+
+ # rescan for add code for dump target
+ while read config_opt config_val;
+ do
+ # remove inline comments after the end of a directive.
+ case "$config_opt" in
+ dracut_args)
+ config_val=$(get_dracut_args_target "$config_val")
+ [ -n "$config_val" ] && add_dump_code "dump_fs $config_val"
+ ;;
+ ext[234]|xfs|btrfs|minix|nfs)
+ add_dump_code "dump_fs $config_val"
+ ;;
+ raw)
+ add_dump_code "dump_raw $config_val"
+ ;;
+ ssh)
+ add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val"
+ ;;
+ esac
+ done <<< "$(read_strip_comments $KDUMP_CONF)"
+}
diff --git a/kdump-lib.sh b/kdump-lib.sh
new file mode 100755
index 0000000..efc1a37
--- /dev/null
+++ b/kdump-lib.sh
@@ -0,0 +1,657 @@
+#!/bin/sh
+#
+# Kdump common variables and functions
+#
+
+DEFAULT_PATH="/var/crash/"
+FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump"
+FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send"
+FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
+
+is_fadump_capable()
+{
+ # Check if firmware-assisted dump is enabled
+ # if no, fallback to kdump check
+ if [ -f $FADUMP_ENABLED_SYS_NODE ]; then
+ rc=`cat $FADUMP_ENABLED_SYS_NODE`
+ [ $rc -eq 1 ] && return 0
+ fi
+ return 1
+}
+
+perror_exit() {
+ echo $@ >&2
+ exit 1
+}
+
+perror() {
+ echo $@ >&2
+}
+
+is_fs_type_nfs()
+{
+ [ "$1" = "nfs" ] || [ "$1" = "nfs4" ]
+}
+
+is_ssh_dump_target()
+{
+ grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf
+}
+
+is_nfs_dump_target()
+{
+ if grep -q "^nfs" /etc/kdump.conf; then
+ return 0;
+ fi
+
+ if is_fs_type_nfs $(get_dracut_args_fstype "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)"); then
+ return 0
+ fi
+
+ local _save_path=$(get_save_path)
+ local _target=$(get_target_from_path $_save_path)
+ local _fstype=$(get_fs_type_from_target $_target)
+
+ if is_fs_type_nfs $_fstype; then
+ return 0
+ fi
+
+ return 1
+}
+
+is_raw_dump_target()
+{
+ grep -q "^raw" /etc/kdump.conf
+}
+
+is_fs_dump_target()
+{
+ egrep -q "^ext[234]|^xfs|^btrfs|^minix" /etc/kdump.conf
+}
+
+strip_comments()
+{
+ echo $@ | sed -e 's/\(.*\)#.*/\1/'
+}
+
+# Read from kdump config file stripping all comments
+read_strip_comments()
+{
+ # strip heading spaces, and print any content starting with
+ # neither space or #, and strip everything after #
+ sed -n -e "s/^\s*\([^# \t][^#]\+\).*/\1/gp" $1
+}
+
+# Check if fence kdump is configured in Pacemaker cluster
+is_pcs_fence_kdump()
+{
+ # no pcs or fence_kdump_send executables installed?
+ type -P pcs > /dev/null || return 1
+ [ -x $FENCE_KDUMP_SEND ] || return 1
+
+ # fence kdump not configured?
+ (pcs cluster cib | grep 'type="fence_kdump"') &> /dev/null || return 1
+}
+
+# Check if fence_kdump is configured using kdump options
+is_generic_fence_kdump()
+{
+ [ -x $FENCE_KDUMP_SEND ] || return 1
+
+ grep -q "^fence_kdump_nodes" /etc/kdump.conf
+}
+
+to_dev_name() {
+ local dev="${1//\"/}"
+
+ case "$dev" in
+ UUID=*)
+ dev=`blkid -U "${dev#UUID=}"`
+ ;;
+ LABEL=*)
+ dev=`blkid -L "${dev#LABEL=}"`
+ ;;
+ esac
+ echo $dev
+}
+
+is_user_configured_dump_target()
+{
+ grep -E -q "^ext[234]|^xfs|^btrfs|^minix|^raw|^nfs|^ssh" /etc/kdump.conf || is_mount_in_dracut_args;
+}
+
+get_user_configured_dump_disk()
+{
+ local _target
+
+ _target=$(egrep "^ext[234]|^xfs|^btrfs|^minix|^raw" /etc/kdump.conf 2>/dev/null |awk '{print $2}')
+ [ -n "$_target" ] && echo $_target && return
+
+ _target=$(get_dracut_args_target "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)")
+ [ -b "$_target" ] && echo $_target
+}
+
+get_root_fs_device()
+{
+ findmnt -k -f -n -o SOURCE /
+}
+
+get_save_path()
+{
+ local _save_path=$(awk '$1 == "path" {print $2}' /etc/kdump.conf)
+ [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH
+
+ # strip the duplicated "/"
+ echo $_save_path | tr -s /
+}
+
+get_block_dump_target()
+{
+ local _target _path
+
+ if is_ssh_dump_target || is_nfs_dump_target; then
+ return
+ fi
+
+ _target=$(get_user_configured_dump_disk)
+ [ -n "$_target" ] && echo $(to_dev_name $_target) && return
+
+ # Get block device name from local save path
+ _path=$(get_save_path)
+ _target=$(get_target_from_path $_path)
+ [ -b "$_target" ] && echo $(to_dev_name $_target)
+}
+
+is_dump_to_rootfs()
+{
+ grep -E "^(failure_action|default)[[:space:]]dump_to_rootfs" /etc/kdump.conf >/dev/null
+}
+
+get_failure_action_target()
+{
+ local _target
+
+ if is_dump_to_rootfs; then
+ # Get rootfs device name
+ _target=$(get_root_fs_device)
+ [ -b "$_target" ] && echo $(to_dev_name $_target) && return
+ # Then, must be nfs root
+ echo "nfs"
+ fi
+}
+
+# Get kdump targets(including root in case of dump_to_rootfs).
+get_kdump_targets()
+{
+ local _target _root
+ local kdump_targets
+
+ _target=$(get_block_dump_target)
+ if [ -n "$_target" ]; then
+ kdump_targets=$_target
+ elif is_ssh_dump_target; then
+ kdump_targets="ssh"
+ else
+ kdump_targets="nfs"
+ fi
+
+ # Add the root device if dump_to_rootfs is specified.
+ _root=$(get_failure_action_target)
+ if [ -n "$_root" -a "$kdump_targets" != "$_root" ]; then
+ kdump_targets="$kdump_targets $_root"
+ fi
+
+ echo "$kdump_targets"
+}
+
+# Return the bind mount source path, return the path itself if it's not bind mounted
+# Eg. if /path/to/src is bind mounted to /mnt/bind, then:
+# /mnt/bind -> /path/to/src, /mnt/bind/dump -> /path/to/src/dump
+#
+# findmnt uses the option "-v, --nofsroot" to exclusive the [/dir]
+# in the SOURCE column for bind-mounts, then if $_mntpoint equals to
+# $_mntpoint_nofsroot, the mountpoint is not bind mounted directory.
+#
+# Below is just an example for mount info
+# /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the
+# directory is bind mounted. The former part represents the device path, rest
+# part is the bind mounted directory which quotes by bracket "[]".
+get_bind_mount_source()
+{
+ local _path=$1
+ # In case it's a sub path in a mount point, get the mount point first
+ local _mnt_top=$(df $_path | tail -1 | awk '{print $NF}')
+ local _mntpoint=$(findmnt $_mnt_top | tail -n 1 | awk '{print $2}')
+ local _mntpoint_nofsroot=$(findmnt -v $_mnt_top | tail -n 1 | awk '{print $2}')
+
+ if [[ "$_mntpoint" = $_mntpoint_nofsroot ]]; then
+ echo $_path && return
+ fi
+
+ _mntpoint=${_mntpoint#*$_mntpoint_nofsroot}
+ _mntpoint=${_mntpoint#[}
+ _mntpoint=${_mntpoint%]}
+ _path=${_path#$_mnt_top}
+
+ echo $_mntpoint$_path
+}
+
+# Return the real underlaying device of a path, ignore bind mounts
+get_target_from_path()
+{
+ local _target
+
+ _target=$(df $1 2>/dev/null | tail -1 | awk '{print $1}')
+ [[ "$_target" == "/dev/root" ]] && [[ ! -e /dev/root ]] && _target=$(get_root_fs_device)
+ echo $_target
+}
+
+get_fs_type_from_target()
+{
+ findmnt -k -f -n -r -o FSTYPE $1
+}
+
+# Find the general mount point of a dump target, not the bind mount point
+get_mntpoint_from_target()
+{
+ # Expcilitly specify --source to findmnt could ensure non-bind mount is returned
+ findmnt -k -f -n -r -o TARGET --source $1
+}
+
+# get_option_value <option_name>
+# retrieves value of option defined in kdump.conf
+get_option_value() {
+ strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-`
+}
+
+check_save_path_fs()
+{
+ local _path=$1
+
+ if [ ! -d $_path ]; then
+ perror_exit "Dump path $_path does not exist."
+ fi
+}
+
+# Check if path exists within dump target
+check_save_path_user_configured()
+{
+ local _target=$1 _path=$2
+ local _mnt=$(get_mntpoint_from_target $_target)
+
+ check_save_path_fs "$_mnt/$_path"
+}
+
+is_atomic()
+{
+ grep -q "ostree" /proc/cmdline
+}
+
+is_ipv6_address()
+{
+ echo $1 | grep -q ":"
+}
+
+# get ip address or hostname from nfs/ssh config value
+get_remote_host()
+{
+ local _config_val=$1
+
+ # ipv6 address in kdump.conf is around with "[]",
+ # factor out the ipv6 address
+ _config_val=${_config_val#*@}
+ _config_val=${_config_val%:/*}
+ _config_val=${_config_val#[}
+ _config_val=${_config_val%]}
+ echo $_config_val
+}
+
+is_hostname()
+{
+ local _hostname=`echo $1 | grep ":"`
+
+ if [ -n "$_hostname" ]; then
+ return 1
+ fi
+ echo $1 | grep -q "[a-zA-Z]"
+}
+
+# Copied from "/etc/sysconfig/network-scripts/network-functions"
+get_hwaddr()
+{
+ if [ -f "/sys/class/net/${1}/address" ]; then
+ awk '{ print toupper($0) }' < /sys/class/net/${1}/address
+ elif [ -d "/sys/class/net/${1}" ]; then
+ LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
+ awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
+ "\\1", 1)); }'
+ fi
+}
+
+get_ifcfg_by_device()
+{
+ grep -E -i -l "^[[:space:]]*DEVICE=\"*${1}\"*[[:space:]]*$" \
+ /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
+}
+
+get_ifcfg_by_hwaddr()
+{
+ grep -E -i -l "^[[:space:]]*HWADDR=\"*${1}\"*[[:space:]]*$" \
+ /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
+}
+
+get_ifcfg_by_uuid()
+{
+ grep -E -i -l "^[[:space:]]*UUID=\"*${1}\"*[[:space:]]*$" \
+ /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
+}
+
+get_ifcfg_by_name()
+{
+ grep -E -i -l "^[[:space:]]*NAME=\"*${1}\"*[[:space:]]*$" \
+ /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
+}
+
+is_nm_running()
+{
+ [ "$(LANG=C nmcli -t --fields running general status 2>/dev/null)" = "running" ]
+}
+
+is_nm_handling()
+{
+ LANG=C nmcli -t --fields device,state dev status 2>/dev/null \
+ | grep -q "^\(${1}:connected\)\|\(${1}:connecting.*\)$"
+}
+
+# $1: netdev name
+get_ifcfg_nmcli()
+{
+ local nm_uuid nm_name
+ local ifcfg_file
+
+ # Get the active nmcli config name of $1
+ if is_nm_running && is_nm_handling "${1}" ; then
+ # The configuration "uuid" and "name" generated by nm is wrote to
+ # the ifcfg file as "UUID=<nm_uuid>" and "NAME=<nm_name>".
+ nm_uuid=$(LANG=C nmcli -t --fields uuid,device c show --active 2>/dev/null \
+ | grep "${1}" | head -1 | cut -d':' -f1)
+ nm_name=$(LANG=C nmcli -t --fields name,device c show --active 2>/dev/null \
+ | grep "${1}" | head -1 | cut -d':' -f1)
+ ifcfg_file=$(get_ifcfg_by_uuid "${nm_uuid}")
+ [ -z "${ifcfg_file}" ] && ifcfg_file=$(get_ifcfg_by_name "${nm_name}")
+ fi
+
+ echo -n "${ifcfg_file}"
+}
+
+# $1: netdev name
+get_ifcfg_legacy()
+{
+ local ifcfg_file
+
+ ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-${1}"
+ [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
+
+ ifcfg_file=$(get_ifcfg_by_name "${1}")
+ [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
+
+ local hwaddr=$(get_hwaddr "${1}")
+ if [ -n "$hwaddr" ]; then
+ ifcfg_file=$(get_ifcfg_by_hwaddr "${hwaddr}")
+ [ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
+ fi
+
+ ifcfg_file=$(get_ifcfg_by_device "${1}")
+
+ echo -n "${ifcfg_file}"
+}
+
+# $1: netdev name
+# Return the ifcfg file whole name(including the path) of $1 if any.
+get_ifcfg_filename() {
+ local ifcfg_file
+
+ ifcfg_file=$(get_ifcfg_nmcli "${1}")
+ if [ -z "${ifcfg_file}" ]; then
+ ifcfg_file=$(get_ifcfg_legacy "${1}")
+ fi
+
+ echo -n "${ifcfg_file}"
+}
+
+# returns 0 when omission of watchdog module is desired in dracut_args
+# returns 1 otherwise
+is_wdt_mod_omitted() {
+ local dracut_args
+ local ret=1
+
+ dracut_args=$(grep "^dracut_args" /etc/kdump.conf)
+ [[ -z $dracut_args ]] && return $ret
+
+ eval set -- $dracut_args
+ while :; do
+ [[ -z $1 ]] && break
+ case $1 in
+ -o|--omit)
+ echo $2 | grep -qw "watchdog"
+ [[ $? == 0 ]] && ret=0
+ break
+ esac
+ shift
+ done
+
+ return $ret
+}
+
+# If "dracut_args" contains "--mount" information, use it
+# directly without any check(users are expected to ensure
+# its correctness).
+is_mount_in_dracut_args()
+{
+ grep -q "^dracut_args .*\-\-mount" /etc/kdump.conf
+}
+
+# If $1 contains dracut_args "--mount", return <filesystem type>
+get_dracut_args_fstype()
+{
+ echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3
+}
+
+# If $1 contains dracut_args "--mount", return <device>
+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
+}
+
+#
+# append_cmdline <kernel cmdline> <parameter name> <parameter value>
+# 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")); }'`
+}
+
+#
+# prepare_kexec_args <kexec args>
+# This function prepares kexec argument.
+#
+prepare_kexec_args()
+{
+ local kexec_args=$1
+ local found_elf_args
+
+ ARCH=`uname -m`
+ if [ "$ARCH" == "i686" -o "$ARCH" == "i386" ]
+ then
+ need_64bit_headers
+ if [ $? == 1 ]
+ then
+ found_elf_args=`echo $kexec_args | grep elf32-core-headers`
+ if [ -n "$found_elf_args" ]
+ then
+ echo -n "Warning: elf32-core-headers overrides correct elf64 setting"
+ echo
+ else
+ kexec_args="$kexec_args --elf64-core-headers"
+ fi
+ else
+ found_elf_args=`echo $kexec_args | grep elf64-core-headers`
+ if [ -z "$found_elf_args" ]
+ then
+ kexec_args="$kexec_args --elf32-core-headers"
+ fi
+ fi
+ fi
+ echo $kexec_args
+}
+
+check_boot_dir()
+{
+ local kdump_bootdir=$1
+ #If user specify a boot dir for kdump kernel, let's use it. Otherwise
+ #check whether it's a atomic host. If yes parse the subdirectory under
+ #/boot; If not just find it under /boot.
+ if [ -n "$kdump_bootdir" ]; then
+ echo "$kdump_bootdir"
+ return
+ fi
+
+ 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
+ echo $kdump_bootdir
+}
+
+#
+# prepare_cmdline <commandline> <commandline remove> <commandline append>
+# This function performs a series of edits on the command line.
+# Store the final result in global $KDUMP_COMMANDLINE.
+prepare_cmdline()
+{
+ local cmdline id
+
+ if [ -z "$1" ]; then
+ cmdline=$(cat /proc/cmdline)
+ else
+ cmdline="$1"
+ fi
+
+ # These params should always be removed
+ cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
+ # These params can be removed configurably
+ cmdline=$(remove_cmdline_param "$cmdline" "$2")
+
+ # 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.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
+
+ # Remove netroot, rd.iscsi.initiator and iscsi_initiator since
+ # we get duplicate entries for the same in case iscsi code adds
+ # it as well.
+ cmdline=$(remove_cmdline_param "$cmdline" netroot rd.iscsi.initiator iscsi_initiator)
+
+ cmdline="${cmdline} $3"
+
+ id=$(get_bootcpu_apicid)
+ if [ ! -z ${id} ] ; then
+ cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
+ fi
+ echo ${cmdline}
+}
diff --git a/kdump-udev-throttler b/kdump-udev-throttler
new file mode 100755
index 0000000..cd77a31
--- /dev/null
+++ b/kdump-udev-throttler
@@ -0,0 +1,42 @@
+#!/bin/bash
+# This util helps to reduce the workload of kdump service restarting
+# on udev event. When hotplugging memory / CPU, multiple udev
+# events may be triggered concurrently, and obviously, we don't want
+# to restart kdump service for each event.
+
+# This script will be called by udev, and make sure kdump service is
+# restart after all events we are watching are settled.
+
+# On each call, this script will update try to aquire the $throttle_lock
+# The first instance acquired the file lock will keep waiting for events
+# to settle and then reload kdump. Other instances will just exit
+# In this way, we can make sure kdump service is restarted immediately
+# and for exactly once after udev events are settled.
+
+throttle_lock="/var/lock/kdump-udev-throttle"
+
+exec 9>$throttle_lock
+if [ $? -ne 0 ]; then
+ echo "Failed to create the lock file! Fallback to non-throttled kdump service restart"
+ /bin/kdumpctl reload
+ exit 1
+fi
+
+flock -n 9
+if [ $? -ne 0 ]; then
+ echo "Throttling kdump restart for concurrent udev event"
+ exit 0
+fi
+
+# Wait for at least 1 second, at most 4 seconds for udev to settle
+# Idealy we will have a less than 1 second lag between udev events settle
+# and kdump reload
+sleep 1 && udevadm settle --timeout 3
+
+# Release the lock, /bin/kdumpctl will block and make the process
+# holding two locks at the same time and we might miss some events
+exec 9>&-
+
+/bin/kdumpctl reload
+
+exit 0
diff --git a/kdump.conf b/kdump.conf
new file mode 100644
index 0000000..1f0fc2d
--- /dev/null
+++ b/kdump.conf
@@ -0,0 +1,175 @@
+# This file contains a series of commands to perform (in order) in the kdump
+# kernel after a kernel crash in the crash kernel(1st kernel) has happened.
+#
+# Directives in this file are only applicable to the kdump initramfs, and have
+# no effect once the root filesystem is mounted and the normal init scripts are
+# processed.
+#
+# Currently, only one dump target and path can be specified. If the dumping to
+# the configured target fails, the failure action which can be configured via
+# the "failure_action" directive will be performed.
+#
+# Supported options:
+#
+# raw <partition>
+# - Will dd /proc/vmcore into <partition>.
+# Use persistent device names for partition devices,
+# such as /dev/vg/<devname>.
+#
+# nfs <nfs mount>
+# - Will mount nfs to <mnt>, and copy /proc/vmcore to
+# <mnt>/<path>/%HOST-%DATE/, supports DNS.
+#
+# ssh <user@server>
+# - Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
+# supports DNS.
+# NOTE: make sure the user has write permissions on the server.
+#
+# sshkey <path>
+# - Will use the sshkey to do ssh dump.
+# Specify the path of the ssh key to use when dumping
+# via ssh. The default value is /root/.ssh/kdump_id_rsa.
+#
+# <fs type> <partition>
+# - Will mount -t <fs type> <partition> <mnt>, and copy
+# /proc/vmcore to <mnt>/<path>/%HOST_IP-%DATE/.
+# NOTE: <partition> can be a device node, label or uuid.
+# It's recommended to use persistent device names
+# such as /dev/vg/<devname>.
+# Otherwise it's suggested to use label or uuid.
+#
+# path <path>
+# - "path" represents the file system path in which vmcore
+# will be saved. If a dump target is specified in
+# kdump.conf, then "path" is relative to the specified
+# dump target.
+#
+# Interpretation of "path" changes a bit if the user didn't
+# specify any dump target explicitly in kdump.conf. In this
+# case, "path" represents the absolute path from root. The
+# dump target and adjusted path are arrived at automatically
+# depending on what's mounted in the current system.
+#
+# Ignored for raw device dumps. If unset, will use the default
+# "/var/crash".
+#
+# core_collector <command> <options>
+# - This allows you to specify the command to copy
+# the vmcore. The default is makedumpfile, which on
+# some architectures can drastically reduce vmcore size.
+# See /sbin/makedumpfile --help for a list of options.
+# Note that the -i and -g options are not needed here,
+# as the initrd will automatically be populated with a
+# config file appropriate for the running kernel.
+# The default core_collector for raw/ssh dump is:
+# "makedumpfile -F -l --message-level 1 -d 31".
+# The default core_collector for other targets is:
+# "makedumpfile -l --message-level 1 -d 31".
+#
+# "makedumpfile -F" will create a flattened vmcore.
+# You need to use "makedumpfile -R" to rearrange the dump data to
+# a normal dumpfile readable with analysis tools. For example:
+# "makedumpfile -R vmcore < vmcore.flat".
+#
+# For core_collector format details, you can refer to
+# kexec-kdump-howto.txt or kdump.conf manpage.
+#
+# kdump_post <binary | script>
+# - This directive allows you to run a executable binary
+# or script after the vmcore dump process terminates.
+# The exit status of the current dump process is fed to
+# the executable binary or script as its first argument.
+#
+# kdump_pre <binary | script>
+# - Works like the "kdump_post" directive, but instead of running
+# after the dump process, runs immediately before it.
+# Exit status of this binary is interpreted as follows:
+# 0 - continue with dump process as usual
+# non 0 - reboot the system
+#
+# extra_bins <binaries | shell scripts>
+# - This directive allows you to specify additional binaries or
+# shell scripts to be included in the kdump initrd.
+# Generally they are useful in conjunction with a kdump_post
+# or kdump_pre binary or script which depends on these extra_bins.
+#
+# extra_modules <module(s)>
+# - This directive allows you to specify extra kernel modules
+# that you want to be loaded in the kdump initrd.
+# Multiple modules can be listed, separated by spaces, and any
+# dependent modules will automatically be included.
+#
+# failure_action <reboot | halt | poweroff | shell | dump_to_rootfs>
+# - Action to perform in case dumping fails.
+# reboot: Reboot the system.
+# halt: Halt the system.
+# poweroff: Power down the system.
+# shell: Drop to a bash shell.
+# Exiting the shell reboots the system by default,
+# or perform "final_action".
+# dump_to_rootfs: Dump vmcore to rootfs from initramfs context and
+# reboot by default or perform "final_action".
+# Useful when non-root dump target is specified.
+# The default option is "reboot".
+#
+# default <reboot | halt | poweroff | shell | dump_to_rootfs>
+# - Same as the "failure_action" directive above, but this directive
+# is obsolete and will be removed in the future.
+#
+# final_action <reboot | halt | poweroff>
+# - Action to perform in case dumping succeeds. Also performed
+# when "shell" or "dump_to_rootfs" failure action finishes.
+# Each action is same as the "failure_action" directive above.
+# The default is "reboot".
+#
+# force_rebuild <0 | 1>
+# - By default, kdump initrd will only be rebuilt when necessary.
+# Specify 1 to force rebuilding kdump initrd every time when kdump
+# service starts.
+#
+# force_no_rebuild <0 | 1>
+# - By default, kdump initrd will be rebuilt when necessary.
+# Specify 1 to bypass rebuilding of kdump initrd.
+#
+# force_no_rebuild and force_rebuild options are mutually
+# exclusive and they should not be set to 1 simultaneously.
+#
+# override_resettable <0 | 1>
+# - Usually an unresettable block device can't be a dump target.
+# Specifying 1 when you want to dump even though the block
+# target is unresettable
+# By default, it is 0, which will not try dumping destined to fail.
+#
+# dracut_args <arg(s)>
+# - Pass extra dracut options when rebuilding kdump initrd.
+#
+# fence_kdump_args <arg(s)>
+# - Command line arguments for fence_kdump_send (it can contain
+# all valid arguments except hosts to send notification to).
+#
+# fence_kdump_nodes <node(s)>
+# - List of cluster node(s) except localhost, separated by spaces,
+# to send fence_kdump notifications to.
+# (this option is mandatory to enable fence_kdump).
+#
+
+#raw /dev/vg/lv_kdump
+#ext4 /dev/vg/lv_kdump
+#ext4 LABEL=/boot
+#ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937
+#nfs my.server.com:/export/tmp
+#ssh user@my.server.com
+#sshkey /root/.ssh/kdump_id_rsa
+path /var/crash
+core_collector makedumpfile -l --message-level 1 -d 31
+#core_collector scp
+#kdump_post /var/crash/scripts/kdump-post.sh
+#kdump_pre /var/crash/scripts/kdump-pre.sh
+#extra_bins /usr/bin/lftp
+#extra_modules gfs2
+#failure_action shell
+#force_rebuild 1
+#force_no_rebuild 1
+#dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3"
+#fence_kdump_args -p 7410 -f auto -c 0 -i 10
+#fence_kdump_nodes node1 node2
diff --git a/kdump.conf.5 b/kdump.conf.5
new file mode 100644
index 0000000..5a0952b
--- /dev/null
+++ b/kdump.conf.5
@@ -0,0 +1,360 @@
+.TH KDUMP.CONF 5 "07/23/2008" "kexec-tools"
+
+.SH NAME
+kdump.conf \- configuration file for kdump kernel.
+
+.SH DESCRIPTION
+
+kdump.conf is a configuration file for the kdump kernel crash
+collection service.
+
+kdump.conf provides post-kexec instructions to the kdump kernel. It is
+stored in the initrd file managed by the kdump service. If you change
+this file and do not want to reboot in order for the changes to take
+effect, restart the kdump service to rebuild the initrd.
+
+For most configurations, you can simply review the examples provided
+in the stock /etc/kdump.conf.
+
+.B NOTE:
+For filesystem dumps the dump target must be mounted before building
+kdump initramfs.
+
+kdump.conf only affects the behavior of the initramfs. Please read the
+kdump operational flow section of kexec-kdump-howto.txt in the docs to better
+understand how this configuration file affects the behavior of kdump.
+
+.SH OPTIONS
+
+.B raw <partition>
+.RS
+Will dd /proc/vmcore into <partition>. Use persistent device names for
+partition devices, such as /dev/vg/<devname>.
+.RE
+
+.B nfs <nfs mount>
+.RS
+Will mount nfs to <mnt>, and copy /proc/vmcore to <mnt>/<path>/%HOST-%DATE/,
+supports DNS. Note that a fqdn should be used as the server name in the
+mount point.
+.RE
+
+.B ssh <user@server>
+.RS
+Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/,
+supports DNS. NOTE: make sure user has necessary write permissions on
+server and that a fqdn is used as the server name.
+.RE
+
+.B sshkey <path>
+.RS
+Specify the path of the ssh key to use when dumping via ssh.
+The default value is /root/.ssh/kdump_id_rsa.
+.RE
+
+.B <fs type> <partition>
+.RS
+Will mount -t <fs type> <partition> <mnt>, and copy /proc/vmcore to
+<mnt>/<path>/%HOST_IP-%DATE/. NOTE: <partition> can be a device node, label
+or uuid. It's recommended to use persistent device names such as
+/dev/vg/<devname>. Otherwise it's suggested to use label or uuid.
+.RE
+
+.B path <path>
+.RS
+"path" represents the file system path in which vmcore will be saved.
+If a dump target is specified in kdump.conf, then "path" is relative to the
+specified dump target.
+.PP
+Interpretation of "path" changes a bit if the user didn't specify any dump
+target explicitly in kdump.conf. In this case, "path" represents the
+absolute path from root. The dump target and adjusted path are arrived
+at automatically depending on what's mounted in the current system.
+.PP
+Ignored for raw device dumps. If unset, will use the default "/var/crash".
+.RE
+
+.B core_collector <command> <options>
+.RS
+This allows you to specify the command to copy the vmcore.
+The default is makedumpfile, which on some architectures can drastically reduce
+core file size. See /sbin/makedumpfile --help for a list of options.
+Note that the -i and -g options are not needed here, as the initrd
+will automatically be populated with a config file appropriate
+for the running kernel.
+.PP
+Note 1: About default core collector:
+The default core_collector for raw/ssh dump is:
+"makedumpfile -F -l --message-level 1 -d 31".
+The default core_collector for other targets is:
+"makedumpfile -l --message-level 1 -d 31".
+Even if core_collector option is commented out in kdump.conf, makedumpfile
+is the default core collector and kdump uses it internally.
+If one does not want makedumpfile as default core_collector, then they
+need to specify one using core_collector option to change the behavior.
+.PP
+Note 2: If "makedumpfile -F" is used then you will get a flattened format
+vmcore.flat, you will need to use "makedumpfile -R" to rearrange the
+dump data from standard input to a normal dumpfile (readable with analysis
+tools).
+ie. "makedumpfile -R vmcore < vmcore.flat"
+
+.RE
+
+.B kdump_post <binary | script>
+.RS
+This directive allows you to run a specified executable
+just after the vmcore dump process terminates. The exit
+status of the current dump process is fed to the kdump_post
+executable as its first argument($1). Executable can modify
+it to indicate the new exit status of succeeding dump process,
+.PP
+Note that scripts written for use with this directive must use
+the /bin/bash interpreter.
+.RE
+
+.B kdump_pre <binary | script>
+.RS
+Works just like the "kdump_post" directive, but instead
+of running after the dump process, runs immediately
+before. Exit status of this binary is interpreted
+as follows:
+.PP
+0 - continue with dump process as usual
+.PP
+non 0 - reboot the system
+.PP
+Note that scripts written for this directive must use
+the /bin/bash interpreter.
+.RE
+
+.B extra_bins <binaries | shell scripts>
+.RS
+This directive allows you to specify additional
+binaries or shell scripts you'd like to include in
+your kdump initrd. Generally only useful in
+conjunction with a kdump_post binary or script that
+relies on other binaries or scripts.
+.RE
+
+.B extra_modules <module(s)>
+.RS
+This directive allows you to specify extra kernel
+modules that you want to be loaded in the kdump
+initrd, typically used to set up access to
+non-boot-path dump targets that might otherwise
+not be accessible in the kdump environment. Multiple
+modules can be listed, separated by spaces, and any
+dependent modules will automatically be included.
+.RE
+
+.B failure_action <reboot | halt | poweroff | shell | dump_to_rootfs>
+.RS
+Action to perform in case dumping to the intended target fails. The default is "reboot".
+reboot: Reboot the system (this is what most people will want, as it returns the system
+to a normal state). halt: Halt the system and lose the vmcore. poweroff: The system
+will be powered down. shell: Drop to a shell session inside the initramfs, from which
+you can manually perform additional recovery actions. Exiting this shell reboots the
+system by default or performs "final_action".
+Note: kdump uses bash as the default shell. dump_to_rootfs: If non-root dump
+target is specified, the failure action can be set as dump_to_rootfs. That means when
+dumping to target fails, dump vmcore to rootfs from initramfs context and reboot
+by default or perform "final_action".
+.RE
+
+.B default <reboot | halt | poweroff | shell | dump_to_rootfs>
+.RS
+Same as the "failure_action" directive above, but this directive is obsolete
+and will be removed in the future.
+.RE
+
+.B final_action <reboot | halt | poweroff>
+.RS
+Action to perform in case dumping to the intended target succeeds.
+Also performed when "shell" or "dump_to_rootfs" failure action finishes.
+Each action is same as the "failure_action" directive above.
+The default is "reboot".
+.RE
+
+.B force_rebuild <0 | 1>
+.RS
+By default, kdump initrd will only be rebuilt when necessary.
+Specify 1 to force rebuilding kdump initrd every time when kdump service starts.
+.RE
+
+.B force_no_rebuild <0 | 1>
+.RS
+By default, kdump initrd will be rebuilt when necessary.
+Specify 1 to bypass rebuilding of kdump initrd.
+
+.PP
+force_no_rebuild and force_rebuild options are mutually exclusive and
+they should not be set to 1 simultaneously.
+.RE
+
+.B override_resettable <0 | 1>
+.RS
+Usually an unresettable block device can't be a dump target. Specifying 1 means
+that even though the block target is unresettable, the user wants to try dumping anyway.
+By default, it's set to 0, which will not try something destined to fail.
+.RE
+
+
+.B dracut_args <arg(s)>
+.RS
+Kdump uses dracut to generate initramfs for second kernel. This option
+allows a user to pass arguments to dracut directly.
+.RE
+
+
+.B fence_kdump_args <arg(s)>
+.RS
+Command line arguments for fence_kdump_send (it can contain all valid
+arguments except hosts to send notification to).
+.RE
+
+
+.B fence_kdump_nodes <node(s)>
+.RS
+List of cluster node(s) except localhost, separated by spaces, to send fence_kdump notification
+to (this option is mandatory to enable fence_kdump).
+.RE
+
+
+.SH DEPRECATED OPTIONS
+
+.B net <nfs mount>|<user@server>
+.RS
+net option is replaced by nfs and ssh options. Use nfs or ssh options
+directly.
+.RE
+
+.B options <module> <option list>
+.RS
+Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump to add module options as
+kernel command line parameters. For example, specify 'loop.max_loop=1' to limit
+maximum loop devices to 1.
+.RE
+
+.B link_delay <seconds>
+.RS
+link_delay was used to wait for a network device to initialize before using it.
+Now dracut network module takes care of this issue automatically.
+.RE
+
+.B disk_timeout <seconds>
+.RS
+Similar to link_delay, dracut ensures disks are ready before kdump uses them.
+.RE
+
+.B debug_mem_level <0-3>
+.RS
+Turn on verbose debug output of kdump scripts regarding free/used memory at
+various points of execution. This feature has been
+moved to dracut now.
+Use KDUMP_COMMANDLINE_APPEND in /etc/sysconfig/kdump and
+append dracut cmdline param rd.memdebug=[0-3] to enable the debug output.
+
+Higher level means more debugging output.
+.PP
+0 - no output
+.PP
+1 - partial /proc/meminfo
+.PP
+2 - /proc/meminfo
+.PP
+3 - /proc/meminfo + /proc/slabinfo
+.RE
+
+.B blacklist <list of kernel modules>
+.RS
+blacklist option was recently being used to prevent loading modules in
+initramfs. General terminology for blacklist has been that module is
+present in initramfs but it is not actually loaded in kernel. Hence
+retaining blacklist option creates more confusing behavior. It has been
+deprecated.
+.PP
+Instead, use rd.driver.blacklist option on second kernel to blacklist
+a certain module. One can edit /etc/sysconfig/kdump.conf and edit
+KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer
+to dracut.cmdline man page for more details on module blacklist option.
+.RE
+
+.RE
+
+.SH EXAMPLES
+Here are some examples for core_collector option:
+.PP
+Core collector command format depends on dump target type. Typically for
+filesystem (local/remote), core_collector should accept two arguments.
+First one is source file and second one is target file. For ex.
+.TP
+ex1.
+core_collector "cp --sparse=always"
+
+Above will effectively be translated to:
+
+cp --sparse=always /proc/vmcore <dest-path>/vmcore
+.TP
+ex2.
+core_collector "makedumpfile -l --message-level 1 -d 31"
+
+Above will effectively be translated to:
+
+makedumpfile -l --message-level 1 -d 31 /proc/vmcore <dest-path>/vmcore
+.PP
+For dump targets like raw and ssh, in general, core collector should expect
+one argument (source file) and should output the processed core on standard
+output (There is one exception of "scp", discussed later). This standard
+output will be saved to destination using appropriate commands.
+
+raw dumps examples:
+.TP
+ex3.
+core_collector "cat"
+
+Above will effectively be translated to.
+
+cat /proc/vmcore | dd of=<target-device>
+.TP
+ex4.
+core_collector "makedumpfile -F -l --message-level 1 -d 31"
+
+Above will effectively be translated to.
+
+makedumpfile -F -l --message-level 1 -d 31 | dd of=<target-device>
+.PP
+ssh dumps examples
+.TP
+ex5.
+core_collector "cat"
+
+Above will effectively be translated to.
+
+cat /proc/vmcore | ssh <options> <remote-location> "dd of=path/vmcore"
+.TP
+ex6.
+core_collector "makedumpfile -F -l --message-level 1 -d 31"
+
+Above will effectively be translated to.
+
+makedumpfile -F -l --message-level 1 -d 31 | ssh <options> <remote-location> "dd of=path/vmcore"
+
+There is one exception to standard output rule for ssh dumps. And that is
+scp. As scp can handle ssh destinations for file transfers, one can
+specify "scp" as core collector for ssh targets (no output on stdout).
+.TP
+ex7.
+core_collector "scp"
+
+Above will effectively be translated to.
+
+scp /proc/vmcore <user@host>:path/vmcore
+
+.PP
+examples for other options please see
+.I /etc/kdump.conf
+
+.SH SEE ALSO
+
+kexec(8) mkdumprd(8) dracut.cmdline(7)
diff --git a/kdump.service b/kdump.service
new file mode 100644
index 0000000..f888dd6
--- /dev/null
+++ b/kdump.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Crash recovery kernel arming
+After=network.target network-online.target remote-fs.target basic.target
+DefaultDependencies=no
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/kdumpctl start
+ExecStop=/usr/bin/kdumpctl stop
+ExecReload=/usr/bin/kdumpctl reload
+RemainAfterExit=yes
+StartLimitInterval=0
+
+[Install]
+WantedBy=multi-user.target
diff --git a/kdump.sysconfig b/kdump.sysconfig
new file mode 100644
index 0000000..df518d6
--- /dev/null
+++ b/kdump.sysconfig
@@ -0,0 +1,37 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
diff --git a/kdump.sysconfig.aarch64 b/kdump.sysconfig.aarch64
new file mode 100644
index 0000000..39a39eb
--- /dev/null
+++ b/kdump.sysconfig.aarch64
@@ -0,0 +1,37 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 swiotlb=noforce novmcoredd numa=off"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
diff --git a/kdump.sysconfig.i386 b/kdump.sysconfig.i386
new file mode 100644
index 0000000..c31a8cb
--- /dev/null
+++ b/kdump.sysconfig.i386
@@ -0,0 +1,40 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
+
+#What is the images extension. Relocatable kernels don't have one
+KDUMP_IMG_EXT=""
diff --git a/kdump.sysconfig.loongarch64 b/kdump.sysconfig.loongarch64
new file mode 100755
index 0000000..86c6d89
--- /dev/null
+++ b/kdump.sysconfig.loongarch64
@@ -0,0 +1,65 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len rd_start rd_size initrd resume=UUID"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="nr_cpus=1 init 3 irqpoll reset_devices cgroup_disable=memory udev.children-max=2 panic=10 novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinux"
+
+#Please replace with the capture kernel to be reboot and the
+#the corresponding initrd only for LoongArch architecture
+# Example:
+# DEFAULT_KDUMP_KERNEL="/boot/vmlinux-4.19.190-4.lns8.loongarch64+kdump"
+# DEFAULT_TARGET_INITRD="/boot/initramfs-4.19.190-4.lns8.loongarch64+kdump.img"
+# If a DEFAULT_KDUMP_KERNEL is not specified, the default is set to
+# "/boot/vmlinux-$(uname -r)+kdump"
+DEFAULT_KDUMP_KERNEL=""
+# If a DEFAULT_TARGET_INITRD is not specified, the default is set to
+# "/boot/initramfs-$(uname -r)+kdump.img"
+DEFAULT_TARGET_INITRD=""
+
+# Logging is controlled by following variables in the first kernel:
+# - @var KDUMP_STDLOGLVL - logging level to standard error (console output)
+# - @var KDUMP_SYSLOGLVL - logging level to syslog (by logger command)
+# - @var KDUMP_KMSGLOGLVL - logging level to /dev/kmsg (only for boot-time)
+#
+# In the second kernel, kdump will use the rd.kdumploglvl option to set the
+# log level in the above KDUMP_COMMANDLINE_APPEND.
+# - @var rd.kdumploglvl - logging level to syslog (by logger command)
+# - for example: add the rd.kdumploglvl=3 option to KDUMP_COMMANDLINE_APPEND
+#
+# Logging levels: no logging(0), error(1),warn(2),info(3),debug(4)
+#
+# KDUMP_STDLOGLVL=3
+# KDUMP_SYSLOGLVL=0
+# KDUMP_KMSGLOGLVL=0
diff --git a/kdump.sysconfig.ppc64 b/kdump.sysconfig.ppc64
new file mode 100644
index 0000000..1f95452
--- /dev/null
+++ b/kdump.sysconfig.ppc64
@@ -0,0 +1,42 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS="--dt-no-old-root"
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
+
+#What is the images extension. Relocatable kernels don't have one
+KDUMP_IMG_EXT=""
+
+#Specify the action after failure
diff --git a/kdump.sysconfig.ppc64le b/kdump.sysconfig.ppc64le
new file mode 100644
index 0000000..1f95452
--- /dev/null
+++ b/kdump.sysconfig.ppc64le
@@ -0,0 +1,42 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS="--dt-no-old-root"
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
+
+#What is the images extension. Relocatable kernels don't have one
+KDUMP_IMG_EXT=""
+
+#Specify the action after failure
diff --git a/kdump.sysconfig.riscv64 b/kdump.sysconfig.riscv64
new file mode 100644
index 0000000..1e65df8
--- /dev/null
+++ b/kdump.sysconfig.riscv64
@@ -0,0 +1,37 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices novmcoredd noinitrd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
diff --git a/kdump.sysconfig.s390x b/kdump.sysconfig.s390x
new file mode 100644
index 0000000..abd45a2
--- /dev/null
+++ b/kdump.sysconfig.s390x
@@ -0,0 +1,43 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd"
+
+# Any additional /sbin/mkdumprd arguments required.
+MKDUMPRD_ARGS=""
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
+
+#What is the images extension. Relocatable kernels don't have one
+KDUMP_IMG_EXT=""
diff --git a/kdump.sysconfig.x86_64 b/kdump.sysconfig.x86_64
new file mode 100644
index 0000000..8217204
--- /dev/null
+++ b/kdump.sysconfig.x86_64
@@ -0,0 +1,46 @@
+# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump
+# If no version is specified, then the init script will try to find a
+# kdump kernel with the same version number as the running kernel.
+KDUMP_KERNELVER=""
+
+# The kdump commandline is the command line that needs to be passed off to
+# the kdump kernel. This will likely match the contents of the grub kernel
+# line. For example:
+# KDUMP_COMMANDLINE="ro root=LABEL=/"
+# Dracut depends on proper root= options, so please make sure that appropriate
+# root= options are copied from /proc/cmdline. In general it is best to append
+# command line options using "KDUMP_COMMANDLINE_APPEND=".
+# If a command line is not specified, the default will be taken from
+# /proc/cmdline
+KDUMP_COMMANDLINE=""
+
+# This variable lets us remove arguments from the current kdump commandline
+# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
+# NOTE: some arguments such as crashkernel will always be removed
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet"
+
+# This variable lets us append arguments to the current kdump commandline
+# after processed by KDUMP_COMMANDLINE_REMOVE
+KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 acpi_no_memhotplug transparent_hugepage=never nokaslr hest_disable novmcoredd"
+
+# Any additional kexec arguments required. In most situations, this should
+# be left empty
+#
+# Example:
+# KEXEC_ARGS="--elf32-core-headers"
+KEXEC_ARGS=""
+
+#Where to find the boot image
+#KDUMP_BOOTDIR="/boot"
+
+#What is the image type used for kdump
+KDUMP_IMG="vmlinuz"
+
+#What is the images extension. Relocatable kernels don't have one
+KDUMP_IMG_EXT=""
+
+# Using kexec file based syscall by default
+#
+# Here, the "on" is the only valid value to enable the kexec file load and
+# anything else is equal to the "off"(disable).
+KDUMP_FILE_LOAD="off"
diff --git a/kdumpctl b/kdumpctl
new file mode 100755
index 0000000..00c0064
--- /dev/null
+++ b/kdumpctl
@@ -0,0 +1,1301 @@
+#!/bin/bash
+KEXEC=/sbin/kexec
+
+KDUMP_KERNELVER=""
+KDUMP_COMMANDLINE=""
+KEXEC_ARGS=""
+KDUMP_FILE_LOAD=""
+KDUMP_CONFIG_FILE="/etc/kdump.conf"
+MKDUMPRD="/sbin/mkdumprd -f"
+DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt"
+SAVE_PATH=/var/crash
+SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
+INITRD_CHECKSUM_LOCATION="/boot/.fadump_initrd_checksum"
+DUMP_TARGET=""
+DEFAULT_INITRD=""
+DEFAULT_INITRD_BAK=""
+TARGET_INITRD=""
+FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
+#kdump shall be the default dump mode
+DEFAULT_DUMP_MODE="kdump"
+image_time=0
+
+[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+. $dracutbasedir/dracut-functions.sh
+. /lib/kdump/kdump-lib.sh
+
+standard_kexec_args="-p"
+
+# Some default values in case /etc/sysconfig/kdump doesn't include
+KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug"
+
+if [ -f /etc/sysconfig/kdump ]; then
+ . /etc/sysconfig/kdump
+fi
+
+single_instance_lock()
+{
+ local rc timeout=5
+
+ exec 9>/var/lock/kdump
+ if [ $? -ne 0 ]; then
+ echo "Create file lock failed"
+ exit 1
+ fi
+
+ flock -n 9
+ rc=$?
+
+ while [ $rc -ne 0 ]; do
+ echo "Another app is currently holding the kdump lock; waiting for it to exit..."
+ flock -w $timeout 9
+ rc=$?
+ done
+}
+
+determine_dump_mode()
+{
+ # Check if firmware-assisted dump is enabled
+ # if yes, set the dump mode as fadump
+ if is_fadump_capable; then
+ echo "Dump mode is fadump"
+ DEFAULT_DUMP_MODE="fadump"
+ fi
+}
+
+save_core()
+{
+ coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"
+
+ mkdir -p $coredir
+ cp --sparse=always /proc/vmcore $coredir/vmcore-incomplete
+ if [ $? == 0 ]; then
+ mv $coredir/vmcore-incomplete $coredir/vmcore
+ echo "saved a vmcore to $coredir"
+ else
+ echo "failed to save a vmcore to $coredir" >&2
+ fi
+
+ # pass the dmesg to Abrt tool if exists, in order
+ # to collect the kernel oops message.
+ # https://fedorahosted.org/abrt/
+ if [ -x /usr/bin/dumpoops ]; then
+ makedumpfile --dump-dmesg $coredir/vmcore $coredir/dmesg >/dev/null 2>&1
+ dumpoops -d $coredir/dmesg >/dev/null 2>&1
+ if [ $? == 0 ]; then
+ echo "kernel oops has been collected by abrt tool"
+ fi
+ fi
+}
+
+rebuild_fadump_initrd()
+{
+ local target_initrd_tmp
+
+ # this file tells the initrd is fadump enabled
+ touch /tmp/fadump.initramfs
+ target_initrd_tmp="$TARGET_INITRD.tmp"
+ $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $kdump_kver \
+ -i /tmp/fadump.initramfs /etc/fadump.initramfs
+ if [ $? != 0 ]; then
+ echo "mkdumprd: failed to rebuild initrd with fadump support" >&2
+ rm -f /tmp/fadump.initramfs
+ return 1
+ fi
+ rm -f /tmp/fadump.initramfs
+
+ # updating fadump initrd
+ mv $target_initrd_tmp $TARGET_INITRD
+ sync
+
+ return 0
+}
+
+check_earlykdump_is_enabled()
+{
+ grep -q -w "rd.earlykdump" /proc/cmdline
+ return $?
+}
+
+rebuild_kdump_initrd()
+{
+ $MKDUMPRD $TARGET_INITRD $kdump_kver
+ if [ $? != 0 ]; then
+ echo "mkdumprd: failed to make kdump initrd" >&2
+ return 1
+ fi
+
+ if check_earlykdump_is_enabled; then
+ echo "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump."
+ fi
+
+ return 0
+}
+
+rebuild_initrd()
+{
+ if [[ ! -w "$KDUMP_BOOTDIR" ]];then
+ echo "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD"
+ return 1
+ fi
+
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ rebuild_fadump_initrd
+ else
+ rebuild_kdump_initrd
+ fi
+
+ return $?
+}
+
+#$1: the files to be checked with IFS=' '
+check_exist()
+{
+ for file in $1; do
+ if [ ! -f "$file" ]; then
+ echo -n "Error: $file not found."; echo
+ return 1
+ fi
+ done
+}
+
+#$1: the files to be checked with IFS=' '
+check_executable()
+{
+ for file in $1; do
+ if [ ! -x "$file" ]; then
+ echo -n "Error: $file is not executable."; echo
+ return 1
+ fi
+ done
+}
+
+backup_default_initrd()
+{
+ if [ ! -f "$DEFAULT_INITRD" ]; then
+ return
+ fi
+
+ if [ ! -e $DEFAULT_INITRD_BAK ]; then
+ echo "Backing up $DEFAULT_INITRD before rebuild."
+ # save checksum to verify before restoring
+ sha1sum $DEFAULT_INITRD > $INITRD_CHECKSUM_LOCATION
+ cp $DEFAULT_INITRD $DEFAULT_INITRD_BAK
+ if [ $? -ne 0 ]; then
+ echo "WARNING: failed to backup $DEFAULT_INITRD."
+ rm -f $DEFAULT_INITRD_BAK
+ fi
+ fi
+}
+
+restore_default_initrd()
+{
+ # If a backup initrd exists, we must be switching back from
+ # fadump to kdump. Restore the original default initrd.
+ if [ -f $DEFAULT_INITRD_BAK ] && [ -f $INITRD_CHECKSUM_LOCATION ]; then
+ # verify checksum before restoring
+ backup_checksum=`sha1sum $DEFAULT_INITRD_BAK | awk '{ print $1 }'`
+ default_checksum=`cat $INITRD_CHECKSUM_LOCATION | awk '{ print $1 }'`
+ if [ "$default_checksum" != "$backup_checksum" ]; then
+ echo "WARNING: checksum mismatch! Can't restore original initrd.."
+ else
+ rm -f $INITRD_CHECKSUM_LOCATION
+ mv $DEFAULT_INITRD_BAK $DEFAULT_INITRD
+ if [[ $? -eq 0 ]]; then
+ echo -n "Restoring original initrd as fadump mode "
+ echo "is disabled."
+ sync
+ fi
+ fi
+ fi
+}
+
+check_config()
+{
+ local nr
+
+ nr=$(awk 'BEGIN{cnt=0} /^raw|^ssh[[:blank:]]|^nfs|^ext[234]|^xfs|^btrfs|^minix|^dracut_args .*\-\-mount/{cnt++} END{print cnt}' $KDUMP_CONFIG_FILE)
+ [ $nr -gt 1 ] && {
+ echo "More than one dump targets specified."
+ return 1
+ }
+
+ # Check if path option is set more than once.
+ nr=$(awk 'BEGIN{cnt=0} /^path /{cnt++} END{print cnt}' $KDUMP_CONFIG_FILE)
+ [ $nr -gt 1 ] && {
+ echo "Mutiple paths specifed in $KDUMP_CONFIG_FILE"
+ return 1
+ }
+
+ nr=$(grep "^dracut_args .*\-\-mount" $KDUMP_CONFIG_FILE | grep -o "\-\-mount" | wc -l)
+ [ $nr -gt 1 ] && {
+ echo "Multiple mount targets specified in one \"dracut_args\"."
+ return 1
+ }
+
+ # Check if we have any leading spaces (or tabs) before the
+ # variable name in the kdump conf file
+ if grep -E -q '^[[:blank:]]+[a-z]' $KDUMP_CONFIG_FILE; then
+ echo "No whitespaces are allowed before a kdump option name in $KDUMP_CONFIG_FILE"
+ return 1
+ fi
+
+ while read config_opt config_val; do
+ case "$config_opt" in
+ \#* | "")
+ ;;
+ raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|failure_action|default|final_action|force_rebuild|force_no_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes)
+ # remove inline comments after the end of a directive.
+ [ -z "$config_val" ] && {
+ echo "Invalid kdump config value for option $config_opt."
+ return 1;
+ }
+ if [ -d "/proc/device-tree/ibm,opal/dump" ] && [ "$config_opt" == "raw" ]; then
+ echo "WARNING: Won't capture opalcore when 'raw' dump target is used."
+ fi
+ ;;
+ net|options|link_delay|disk_timeout|debug_mem_level|blacklist)
+ echo "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives."
+ ;;
+ *)
+ echo "Invalid kdump config option $config_opt"
+ ;;
+ esac
+ done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)"
+
+ check_failure_action_config || return 1
+ check_final_action_config || return 1
+
+ check_fence_kdump_config || return 1
+
+ return 0
+}
+
+# get_pcs_cluster_modified_files <image timestamp>
+# return list of modified file for fence_kdump modified in Pacemaker cluster
+get_pcs_cluster_modified_files()
+{
+ local time_stamp
+ local modified_files
+
+ is_generic_fence_kdump && return 1
+ is_pcs_fence_kdump || return 1
+
+ time_stamp=`pcs cluster cib | xmllint --xpath 'string(/cib/@cib-last-written)' - | \
+ xargs -0 date +%s --date`
+
+ if [ -n $time_stamp -a $time_stamp -gt $image_time ]; then
+ modified_files="cluster-cib"
+ fi
+
+ if [ -f $FENCE_KDUMP_CONFIG_FILE ]; then
+ time_stamp=`stat -c "%Y" $FENCE_KDUMP_CONFIG_FILE`
+ if [ "$time_stamp" -gt "$image_time" ]; then
+ modified_files="$modified_files $FENCE_KDUMP_CONFIG_FILE"
+ fi
+ fi
+
+ echo $modified_files
+}
+
+setup_initrd()
+{
+ KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}")
+
+ if [ -z "$KDUMP_KERNELVER" ]; then
+ kdump_kver=`uname -r`
+ else
+ kdump_kver=$KDUMP_KERNELVER
+ fi
+
+ kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}"
+
+ DEFAULT_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`.img"
+ DEFAULT_INITRD_BAK="${KDUMP_BOOTDIR}/.initramfs-`uname -r`.img.default"
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ TARGET_INITRD="$DEFAULT_INITRD"
+
+ # backup initrd for reference before replacing it
+ # with fadump aware initrd
+ backup_default_initrd
+ else
+ TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
+
+ # check if a backup of default initrd exists. If yes,
+ # it signifies a switch from fadump mode. So, restore
+ # the backed up default initrd.
+ restore_default_initrd
+ fi
+}
+
+check_files_modified()
+{
+ local modified_files=""
+
+ #also rebuild when Pacemaker cluster conf is changed and fence kdump is enabled.
+ modified_files=$(get_pcs_cluster_modified_files)
+
+ EXTRA_BINS=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2`
+ CHECK_FILES=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2`
+ CORE_COLLECTOR=`grep ^core_collector $KDUMP_CONFIG_FILE | cut -d\ -f2`
+ CORE_COLLECTOR=`type -P $CORE_COLLECTOR`
+ EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
+ CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-`
+ EXTRA_BINS="$EXTRA_BINS $CHECK_FILES"
+ files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS $CORE_COLLECTOR"
+ [[ -e /etc/fstab ]] && files="$files /etc/fstab"
+
+ # Check for any updated extra module
+ EXTRA_MODULES="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')"
+ if [ -n "$EXTRA_MODULES" ]; then
+ if [ -e /lib/modules/$kdump_kver/modules.dep ]; then
+ files="$files /lib/modules/$kdump_kver/modules.dep"
+ fi
+ for _module in $EXTRA_MODULES; do
+ _module_file="$(modinfo --set-version "$kdump_kver" --filename "$_module" 2>/dev/null)"
+ if [[ $? -eq 0 ]]; then
+ files="$files $_module_file"
+ for _dep_modules in $(modinfo -F depends $_module | tr ',' ' '); do
+ files="$files $(modinfo --set-version "$kdump_kver" --filename $_dep_modules 2>/dev/null)"
+ done
+ else
+ # If it's not a module nor builtin, give an error
+ if ! ( modprobe --set-version "$kdump_kver" --dry-run "$_module" &>/dev/null ); then
+ echo "Module $_module not found"
+ fi
+ fi
+ done
+ fi
+
+ check_exist "$files" && check_executable "$EXTRA_BINS"
+ [ $? -ne 0 ] && return 2
+
+ for file in $files; do
+ if [ -e "$file" ]; then
+ time_stamp=`stat -c "%Y" $file`
+ if [ "$time_stamp" -gt "$image_time" ]; then
+ modified_files="$modified_files $file"
+ fi
+ if [ -L "$file" ]; then
+ file=$(readlink -m $file)
+ time_stamp=`stat -c "%Y" $file`
+ if [ "$time_stamp" -gt "$image_time" ]; then
+ modified_files="$modified_files $file"
+ fi
+ fi
+ else
+ echo "$file doesn't exist"
+ fi
+ done
+
+ if [ -n "$modified_files" ]; then
+ echo "Detected change(s) in the following file(s):"
+ echo -n " "; echo "$modified_files" | sed 's/\s/\n /g'
+ return 1
+ fi
+
+ return 0
+}
+
+check_dump_fs_modified()
+{
+ local _old_dev _old_mntpoint _old_fstype
+ local _new_dev _new_mntpoint _new_fstype
+ local _target _path _dracut_args
+ local _target_drivers _module_name _module_filename
+
+ local _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')"
+
+ # No need to check in case of mount target specified via "dracut_args".
+ if is_mount_in_dracut_args; then
+ return 0
+ fi
+
+ # No need to check in case of raw target.
+ # Currently we do not check also if ssh/nfs target is specified
+ if is_ssh_dump_target || is_nfs_dump_target || is_raw_dump_target; then
+ return 0
+ fi
+
+ _target=$(get_user_configured_dump_disk)
+
+ if [[ -n "$_target" ]]; then
+ _target=$(to_dev_name $_target)
+ _new_fstype=$(blkid $_target | awk -F"TYPE=" '{print $2}' | cut -d '"' -f 2)
+ else
+ _path=$(get_save_path)
+ _target=$(get_target_from_path $_path)
+ _target=$(to_dev_name $_target)
+ _new_fstype=$(get_fs_type_from_target $_target)
+ if [[ -z "$_target" || -z "$_new_fstype" ]];then
+ echo "Dump path $_path does not exist"
+ return 2
+ fi
+ fi
+
+ _record_block_drivers() {
+ local _drivers
+ if [[ -b /dev/block/$1 ]]; then
+ _drivers=$(udevadm info -a "/dev/block/$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p')
+ fi
+ if [[ -b $1 ]]; then
+ _drivers=$(udevadm info -a "$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p')
+ fi
+ for _driver in $_drivers; do
+ if ! [[ " $_target_drivers " == *" $_driver "* ]]; then
+ _target_drivers="$_target_drivers $_driver"
+ fi
+ done
+ return 1
+ }
+
+ check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")"
+ for _driver in $_target_drivers; do
+ # Skip deprecated/invalid driver name or built-in module
+ _module_name=$(modinfo --set-version "$kdump_kver" -F name $_driver 2>/dev/null)
+ _module_filename=$(modinfo --set-version "$kdump_kver" -n $_driver 2>/dev/null)
+ if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename" = *"(builtin)"* ]]; then
+ continue
+ fi
+ if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then
+ echo "Detected change in block device driver, new loaded module: $_module_name"
+ return 1
+ fi
+ done
+
+ if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then
+ _new_dev=$_target
+ else
+ _new_dev=$(get_persistent_dev $_target)
+ if [ -z "$_new_dev" ]; then
+ echo "Get persistent device name failed"
+ return 2
+ fi
+ fi
+
+ if ! findmnt $_target >/dev/null; then
+ echo "Dump target $_target is probably not mounted."
+ return 2
+ fi
+
+ if [[ "$_target" = "$(get_root_fs_device)" ]]; then
+ _new_mntpoint="/sysroot"
+ else
+ _new_mntpoint="/kdumproot/$(get_mntpoint_from_target $_target)"
+ fi
+
+ _dracut_args=$(lsinitrd $TARGET_INITRD -f usr/lib/dracut/build-parameter.txt)
+ if [[ -z "$_dracut_args" ]];then
+ echo "Warning: No dracut arguments found in initrd"
+ return 0
+ fi
+
+ # if --mount argument present then match old and new target, mount
+ # point and file system. If any of them mismatches then rebuild
+ echo $_dracut_args | grep "\-\-mount" &> /dev/null
+ if [[ $? -eq 0 ]];then
+ set -- $(echo $_dracut_args | awk -F "--mount '" '{print $2}' | cut -d' ' -f1,2,3)
+ _old_dev=$1
+ _old_mntpoint=$2
+ _old_fstype=$3
+ [[ $_new_dev = $_old_dev && $_new_mntpoint = $_old_mntpoint && $_new_fstype = $_old_fstype ]] && return 0
+ # otherwise rebuild if target device is not a root device
+ else
+ [[ "$_target" = "$(get_root_fs_device)" ]] && return 0
+ fi
+
+ echo "Detected change in File System"
+ return 1
+}
+
+check_wdt_modified()
+{
+ local -A _drivers
+ local _alldrivers _active _wdtdrv _wdtppath _dir
+ local wd_old wd_new
+
+ is_wdt_mod_omitted
+ [[ $? -eq 0 ]] && return 0
+ [[ -d /sys/class/watchdog/ ]] || return 0
+
+ # Copied logic from dracut 04watchdog/module-setup.sh::installkernel()
+ for _dir in /sys/class/watchdog/*; do
+ [[ -d "$_dir" ]] || continue
+ [[ -f "$_dir/state" ]] || continue
+ _active=$(< "$_dir/state")
+ [[ "$_active" = "active" ]] || continue
+ # device/modalias will return driver of this device
+ _wdtdrv=$(< "$_dir/device/modalias")
+ # There can be more than one module represented by same
+ # modalias. Currently load all of them.
+ # TODO: Need to find a way to avoid any unwanted module
+ # represented by modalias
+ _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null)
+ if [[ $_wdtdrv ]]; then
+ for i in $_wdtdrv; do
+ _drivers[$i]=1
+ done
+ fi
+ # however in some cases, we also need to check that if there is
+ # a specific driver for the parent bus/device. In such cases
+ # we also need to enable driver for parent bus/device.
+ _wdtppath=$(readlink -f "$_dir/device")
+ while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do
+ _wdtppath=$(readlink -f "$_wdtppath/..")
+ [[ -f "$_wdtppath/modalias" ]] || continue
+
+ _wdtdrv=$(< "$_wdtppath/modalias")
+ _wdtdrv=$(modprobe --set-version "$kdump_kver" -R $_wdtdrv 2>/dev/null)
+ if [[ $_wdtdrv ]]; then
+ for i in $_wdtdrv; do
+ _drivers[$i]=1
+ done
+ fi
+ done
+ done
+
+ # ensure that watchdog module is loaded as early as possible
+ _alldrivers="${!_drivers[*]}"
+ [[ $_alldrivers ]] && wd_new="rd.driver.pre=${_alldrivers// /,}"
+ wd_old=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf)
+
+ [[ "$wd_old" = "$wd_new" ]] && return 0
+
+ return 1
+}
+
+# returns 0 if system is not modified
+# returns 1 if system is modified
+# returns 2 if system modification is invalid
+check_system_modified()
+{
+ local ret
+
+ [[ -f $TARGET_INITRD ]] || return 1
+
+ check_files_modified
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ return $ret
+ fi
+
+ check_dump_fs_modified
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ return $ret
+ fi
+
+ check_wdt_modified
+ if [ $? -ne 0 ]; then
+ echo "Detected change in watchdog state"
+ return 1
+ fi
+
+ return 0
+}
+
+check_rebuild()
+{
+ local capture_capable_initrd="1"
+ local _force_rebuild force_rebuild="0"
+ local _force_no_rebuild force_no_rebuild="0"
+ local ret system_modified="0"
+
+ setup_initrd
+
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ _force_no_rebuild=`grep ^force_no_rebuild $KDUMP_CONFIG_FILE 2>/dev/null`
+ if [ $? -eq 0 ]; then
+ force_no_rebuild=`echo $_force_no_rebuild | cut -d' ' -f2`
+ if [ "$force_no_rebuild" != "0" ] && [ "$force_no_rebuild" != "1" ];then
+ echo "Error: force_no_rebuild value is invalid"
+ return 1
+ fi
+ fi
+
+ _force_rebuild=`grep ^force_rebuild $KDUMP_CONFIG_FILE 2>/dev/null`
+ if [ $? -eq 0 ]; then
+ force_rebuild=`echo $_force_rebuild | cut -d' ' -f2`
+ if [ "$force_rebuild" != "0" ] && [ "$force_rebuild" != "1" ];then
+ echo "Error: force_rebuild value is invalid"
+ return 1
+ fi
+ fi
+
+ if [[ "$force_no_rebuild" == "1" && "$force_rebuild" == "1" ]]; then
+ echo "Error: force_rebuild and force_no_rebuild are enabled simultaneously in kdump.conf"
+ return 1
+ fi
+
+ # Will not rebuild kdump initrd
+ if [ "$force_no_rebuild" == "1" ]; then
+ return 0
+ fi
+
+ #check to see if dependent files has been modified
+ #since last build of the image file
+ if [ -f $TARGET_INITRD ]; then
+ image_time=`stat -c "%Y" $TARGET_INITRD 2>/dev/null`
+
+ #in case of fadump mode, check whether the default/target
+ #initrd is already built with dump capture capability
+ if [ "$DEFAULT_DUMP_MODE" == "fadump" ]; then
+ capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE $TARGET_INITRD | grep ^kdumpbase$ | wc -l)
+ fi
+ fi
+
+ check_system_modified
+ ret=$?
+ if [ $ret -eq 2 ]; then
+ return 1
+ elif [ $ret -eq 1 ];then
+ system_modified="1"
+ fi
+
+ if [ $image_time -eq 0 ]; then
+ echo -n "No kdump initial ramdisk found."; echo
+ elif [ "$capture_capable_initrd" == "0" ]; then
+ echo -n "Rebuild $TARGET_INITRD with dump capture support"; echo
+ elif [ "$force_rebuild" != "0" ]; then
+ echo -n "Force rebuild $TARGET_INITRD"; echo
+ elif [ "$system_modified" != "0" ]; then
+ :
+ else
+ return 0
+ fi
+
+ echo "Rebuilding $TARGET_INITRD"
+ rebuild_initrd
+ return $?
+}
+
+# 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.
+load_kdump()
+{
+ KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}")
+ KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}")
+
+ if [ "$KDUMP_FILE_LOAD" == "on" ]; then
+ echo "Using kexec file based syscall."
+ KEXEC_ARGS="$KEXEC_ARGS -s"
+ fi
+
+ $KEXEC $KEXEC_ARGS $standard_kexec_args \
+ --command-line="$KDUMP_COMMANDLINE" \
+ --initrd=$TARGET_INITRD $kdump_kernel
+ if [ $? == 0 ]; then
+ echo "kexec: loaded kdump kernel"
+ return 0
+ else
+ echo "kexec: failed to load kdump kernel" >&2
+ if [ "$KDUMP_FILE_LOAD" == "on" ]; then
+ echo "kexec_file_load() failed, please try kexec_load()" >&2
+ fi
+ return 1
+ fi
+}
+
+check_ssh_config()
+{
+ while read config_opt config_val; do
+ case "$config_opt" in
+ sshkey)
+ # remove inline comments after the end of a directive.
+ if [ -f "$config_val" ]; then
+ # canonicalize the path
+ SSH_KEY_LOCATION=$(/usr/bin/readlink -m $config_val)
+ else
+ echo "WARNING: '$config_val' doesn't exist, using default value '$SSH_KEY_LOCATION'"
+ fi
+ ;;
+ path)
+ SAVE_PATH=$config_val
+ ;;
+ ssh)
+ DUMP_TARGET=$config_val
+ ;;
+ *)
+ ;;
+ esac
+ done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)"
+
+ #make sure they've configured kdump.conf for ssh dumps
+ local SSH_TARGET=`echo -n $DUMP_TARGET | sed -n '/.*@/p'`
+ if [ -z "$SSH_TARGET" ]; then
+ return 1
+ fi
+ return 0
+}
+
+# ipv6 host address may takes a long time to be ready.
+# Instead of checking against ipv6 address, we just check the network reachable
+# by the return val of 'ssh'
+check_and_wait_network_ready()
+{
+ local start_time=$(date +%s)
+ local warn_once=1
+ local cur
+ local diff
+ local retval
+ local errmsg
+
+ while true; do
+ errmsg=$(ssh -i $SSH_KEY_LOCATION -o BatchMode=yes $DUMP_TARGET mkdir -p $SAVE_PATH 2>&1)
+ retval=$?
+
+ # ssh exits with the exit status of the remote command or with 255 if an error occurred
+ if [ $retval -eq 0 ]; then
+ return 0
+ elif [ $retval -ne 255 ]; then
+ echo "Could not create $DUMP_TARGET:$SAVE_PATH, you should check the privilege on server side" >&2
+ return 1
+ fi
+
+ # if server removes the authorized_keys or, no /root/.ssh/kdump_id_rsa
+ echo $errmsg | grep -q "Permission denied\|No such file or directory\|Host key verification failed"
+ if [ $? -eq 0 ]; then
+ echo "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"kdumpctl propagate\"" >&2
+ return 1
+ fi
+
+ if [ $warn_once -eq 1 ]; then
+ echo "Network dump target is not usable, waiting for it to be ready"
+ warn_once=0
+ fi
+ echo -n .
+
+ cur=$(date +%s)
+ let "diff = $cur - $start_time"
+ # 60s time out
+ if [ $diff -gt 180 ]; then
+ break;
+ fi
+ sleep 1
+ done
+
+ echo "Could not create $DUMP_TARGET:$SAVE_PATH, ipaddr is not ready yet. You should check network connection" >&2
+ return 1
+}
+
+check_ssh_target()
+{
+ check_and_wait_network_ready
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+ return 0
+}
+
+propagate_ssh_key()
+{
+ check_ssh_config
+ if [ $? -ne 0 ]; then
+ echo "No ssh config specified in $KDUMP_CONFIG_FILE. Can't propagate" >&2
+ exit 1
+ fi
+
+ local KEYFILE=$SSH_KEY_LOCATION
+ local errmsg="Failed to propagate ssh key"
+
+ #Check to see if we already created key, if not, create it.
+ if [ -f $KEYFILE ]; then
+ echo "Using existing keys..."
+ else
+ echo -n "Generating new ssh keys... "
+ /usr/bin/ssh-keygen -t rsa -f $KEYFILE -N "" 2>&1 > /dev/null
+ echo "done."
+ fi
+
+ #now find the target ssh user and server to contact.
+ SSH_USER=`echo $DUMP_TARGET | cut -d\ -f2 | cut -d@ -f1`
+ SSH_SERVER=`echo $DUMP_TARGET | sed -e's/\(.*@\)\(.*$\)/\2/'`
+
+ #now send the found key to the found server
+ ssh-copy-id -i $KEYFILE $SSH_USER@$SSH_SERVER
+ RET=$?
+ if [ $RET == 0 ]; then
+ echo $KEYFILE has been added to ~$SSH_USER/.ssh/authorized_keys on $SSH_SERVER
+ return 0
+ else
+ echo $errmsg, $KEYFILE failed in transfer to $SSH_SERVER >&2
+ exit 1
+ fi
+}
+
+show_reserved_mem()
+{
+ local mem=$(cat /sys/kernel/kexec_crash_size)
+ local mem_mb=$(expr $mem / 1024 / 1024)
+
+ echo "Reserved "$mem_mb"MB memory for crash kernel"
+}
+
+check_current_fadump_status()
+{
+ # Check if firmware-assisted dump has been registered.
+ rc=`cat $FADUMP_REGISTER_SYS_NODE`
+ [ $rc -eq 1 ] && return 0
+ return 1
+}
+
+check_current_status()
+{
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ check_current_fadump_status
+ else
+ check_current_kdump_status
+ fi
+
+ return $?
+}
+
+save_raw()
+{
+ local kdump_dir
+ local raw_target
+
+ raw_target=$(awk '$1 ~ /^raw$/ { print $2; }' $KDUMP_CONFIG_FILE)
+ [ -z "$raw_target" ] && return 0
+ [ -b "$raw_target" ] || {
+ echo "raw partition $raw_target not found"
+ return 1
+ }
+ check_fs=$(lsblk --nodeps -npo FSTYPE $raw_target)
+ if [[ $(echo $check_fs | wc -w) -ne 0 ]]; then
+ echo "Warning: Detected '$check_fs' signature on $raw_target, data loss is expected."
+ return 0
+ fi
+ kdump_dir=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-`
+ if [ -z "${kdump_dir}" ]; then
+ coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`"
+ else
+ coredir="${kdump_dir}/`date +"%Y-%m-%d-%H:%M"`"
+ fi
+
+ mkdir -p "$coredir"
+ [ -d "$coredir" ] || {
+ echo "failed to create $coredir"
+ return 1
+ }
+ if makedumpfile -R $coredir/vmcore <$raw_target >/dev/null 2>&1; then
+ # dump found
+ echo "Dump saved to $coredir/vmcore"
+ # wipe makedumpfile header
+ dd if=/dev/zero of=$raw_target bs=1b count=1 2>/dev/null
+ else
+ rm -rf "$coredir"
+ fi
+
+ return 0
+}
+
+local_fs_dump_target()
+{
+ local _target
+
+ _target=$(egrep "^ext[234]|^xfs|^btrfs|^minix" /etc/kdump.conf)
+ if [ $? -eq 0 ]; then
+ echo $_target|awk '{print $2}'
+ fi
+}
+
+path_to_be_relabeled()
+{
+ local _path _target _mnt="/" _rmnt
+
+ if is_user_configured_dump_target; then
+ if is_mount_in_dracut_args; then
+ return;
+ fi
+
+ _target=$(local_fs_dump_target)
+ if [[ -n "$_target" ]]; then
+ _mnt=$(findmnt -k -f -n -r -o TARGET $_target)
+ if [ -z "$_mnt" ]; then
+ return
+ fi
+ else
+ return
+ fi
+ fi
+
+ _path=$(get_save_path)
+ # if $_path is masked by other mount, we will not relabel it.
+ _rmnt=$(df $_mnt/$_path 2>/dev/null | tail -1 | awk '{ print $NF }')
+ if [ "$_rmnt" == "$_mnt" ]; then
+ echo $_mnt/$_path
+ fi
+}
+
+selinux_relabel()
+{
+ local _path _i _attr
+
+ _path=$(path_to_be_relabeled)
+ if [ -z "$_path" ] || ! [ -d "$_path" ] ; then
+ return
+ fi
+
+ for _i in $(find $_path); do
+ _attr=$(getfattr -m "security.selinux" $_i 2>/dev/null)
+ if [ -z "$_attr" ]; then
+ restorecon $_i;
+ fi
+ done
+}
+
+check_fence_kdump_config()
+{
+ local hostname=`hostname`
+ local ipaddrs=`hostname -I`
+ local nodes=$(get_option_value "fence_kdump_nodes")
+
+ for node in $nodes; do
+ if [ "$node" = "$hostname" ]; then
+ echo "Option fence_kdump_nodes cannot contain $hostname"
+ return 1
+ fi
+ # node can be ipaddr
+ echo $ipaddrs | grep $node > /dev/null
+ if [ $? -eq 0 ]; then
+ echo "Option fence_kdump_nodes cannot contain $node"
+ return 1
+ fi
+ done
+
+ return 0
+}
+
+check_dump_feasibility()
+{
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ return 0
+ fi
+
+ check_kdump_feasibility
+ return $?
+}
+
+start_fadump()
+{
+ echo 1 > $FADUMP_REGISTER_SYS_NODE
+ if ! check_current_fadump_status; then
+ echo "fadump: failed to register"
+ return 1
+ fi
+
+ echo "fadump: registered successfully"
+ return 0
+}
+
+start_dump()
+{
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ start_fadump
+ else
+ load_kdump
+ fi
+
+ return $?
+}
+
+check_failure_action_config()
+{
+ local default_option
+ local failure_action
+ local option="failure_action"
+
+ default_option=$(awk '$1 ~ /^default$/ {print $2;}' $KDUMP_CONFIG_FILE)
+ failure_action=$(awk '$1 ~ /^failure_action$/ {print $2;}' $KDUMP_CONFIG_FILE)
+
+ if [ -z "$failure_action" -a -z "$default_option" ]; then
+ return 0
+ elif [ -n "$failure_action" -a -n "$default_option" ]; then
+ echo "Cannot specify 'failure_action' and 'default' option together"
+ return 1
+ fi
+
+ if [ -n "$default_option" ]; then
+ option="default"
+ failure_action="$default_option"
+ fi
+
+ case "$failure_action" in
+ reboot|halt|poweroff|shell|dump_to_rootfs)
+ return 0
+ ;;
+ *)
+ echo $"Usage kdump.conf: $option {reboot|halt|poweroff|shell|dump_to_rootfs}"
+ return 1
+ esac
+}
+
+check_final_action_config()
+{
+ local final_action
+
+ final_action=$(awk '$1 ~ /^final_action$/ {print $2;}' $KDUMP_CONFIG_FILE)
+ if [ -z "$final_action" ]; then
+ return 0
+ else
+ case "$final_action" in
+ reboot|halt|poweroff)
+ return 0
+ ;;
+ *)
+ echo $"Usage kdump.conf: final_action {reboot|halt|poweroff}"
+ return 1
+ esac
+ fi
+}
+
+start()
+{
+ check_dump_feasibility
+ if [ $? -ne 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ check_config
+ if [ $? -ne 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ if sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; then
+ selinux_relabel
+ fi
+
+ save_raw
+ if [ $? -ne 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ check_current_status
+ if [ $? == 0 ]; then
+ echo "Kdump already running: [WARNING]"
+ return 0
+ fi
+
+ if check_ssh_config; then
+ if ! check_ssh_target; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+ fi
+
+ check_rebuild
+ if [ $? != 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ start_dump
+ if [ $? != 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ echo "Starting kdump: [OK]"
+}
+
+reload()
+{
+ check_current_status
+ if [ $? -ne 0 ]; then
+ echo "Kdump was not running: [WARNING]"
+ fi
+
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ reload_fadump
+ return $?
+ else
+ stop_kdump
+ fi
+
+ if [ $? -ne 0 ]; then
+ echo "Stopping kdump: [FAILED]"
+ return 1
+ fi
+
+ echo "Stopping kdump: [OK]"
+
+ setup_initrd
+ if [ $? -ne 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ start_dump
+ if [ $? -ne 0 ]; then
+ echo "Starting kdump: [FAILED]"
+ return 1
+ fi
+
+ echo "Starting kdump: [OK]"
+}
+
+stop_fadump()
+{
+ echo 0 > $FADUMP_REGISTER_SYS_NODE
+ if check_current_fadump_status; then
+ echo "fadump: failed to unregister"
+ return 1
+ fi
+
+ echo "fadump: unregistered successfully"
+ return 0
+}
+
+stop_kdump()
+{
+ if [ "$KDUMP_FILE_LOAD" == "on" ]; then
+ $KEXEC -s -p -u
+ else
+ $KEXEC -p -u
+ fi
+
+ if [ $? != 0 ]; then
+ echo "kexec: failed to unload kdump kernel"
+ return 1
+ fi
+
+ echo "kexec: unloaded kdump kernel"
+ return 0
+}
+
+reload_fadump()
+{
+ echo 1 > $FADUMP_REGISTER_SYS_NODE
+ if [ $? == 0 ]; then
+ echo "fadump: re-registered successfully"
+ return 0
+ else
+ # FADump could fail on older kernel where re-register
+ # support is not enabled. Try stop/start from userspace
+ # to handle such scenario.
+ stop_fadump
+ if [ $? == 0 ]; then
+ start_fadump
+ return $?
+ fi
+ fi
+
+ return 1
+}
+
+stop()
+{
+ if [ $DEFAULT_DUMP_MODE == "fadump" ]; then
+ stop_fadump
+ else
+ stop_kdump
+ fi
+
+ if [ $? != 0 ]; then
+ echo "Stopping kdump: [FAILED]"
+ return 1
+ fi
+
+ echo "Stopping kdump: [OK]"
+ return 0
+}
+
+rebuild() {
+ check_config
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ if check_ssh_config; then
+ if ! check_ssh_target; then
+ return 1
+ fi
+ fi
+
+ setup_initrd
+ if [ $? -ne 0 ]; then
+ return 1
+ fi
+
+ echo "Rebuilding $TARGET_INITRD"
+ rebuild_initrd
+ return $?
+}
+
+if [ ! -f "$KDUMP_CONFIG_FILE" ]; then
+ echo "Error: No kdump config file found!" >&2
+ exit 1
+fi
+
+main ()
+{
+ # Determine if the dump mode is kdump or fadump
+ determine_dump_mode
+
+ case "$1" in
+ start)
+ if [ -s /proc/vmcore ]; then
+ save_core
+ reboot
+ else
+ start
+ fi
+ ;;
+ stop)
+ stop
+ ;;
+ status)
+ EXIT_CODE=0
+ check_current_status
+ case "$?" in
+ 0)
+ echo "Kdump is operational"
+ EXIT_CODE=0
+ ;;
+ 1)
+ echo "Kdump is not operational"
+ EXIT_CODE=3
+ ;;
+ esac
+ exit $EXIT_CODE
+ ;;
+ reload)
+ reload
+ ;;
+ restart)
+ stop
+ start
+ ;;
+ rebuild)
+ rebuild
+ ;;
+ condrestart)
+ ;;
+ propagate)
+ propagate_ssh_key
+ ;;
+ showmem)
+ show_reserved_mem
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|status|restart|reload|rebuild|propagate|showmem}"
+ exit 1
+ esac
+}
+
+# Other kdumpctl instances will block in queue, until this one exits
+single_instance_lock
+
+# To avoid fd 9 leaking, we invoke a subshell, close fd 9 and call main.
+# So that fd isn't leaking when main is invoking a subshell.
+(exec 9<&-; main $1)
+
+exit $?
diff --git a/kdumpctl.8 b/kdumpctl.8
new file mode 100644
index 0000000..ae97af7
--- /dev/null
+++ b/kdumpctl.8
@@ -0,0 +1,50 @@
+.TH KDUMPCTL 8 2015-07-13 kexec-tools
+
+.SH NAME
+kdumpctl \- control interface for kdump
+
+.SH SYNOPSIS
+.B kdumpctl
+.I COMMAND
+
+.SH DESCRIPTION
+.B kdumpctl
+is used to check or control the kdump service.
+In most cases, you should use
+.B systemctl
+to start / stop / enable kdump service instead. However,
+.B kdumpctl
+provides more details for debug and a helper to setup ssh key authentication.
+
+.SH COMMANDS
+.TP
+.I start
+Start the service.
+.TP
+.I stop
+Stop the service.
+.TP
+.I status
+Prints the current status of kdump service.
+It returns non-zero value if kdump is not operational.
+.TP
+.I restart
+Is equal to
+.I start; stop
+.TP
+.I reload
+reload crash kernel image and initramfs without triggering a rebuild.
+.TP
+.I rebuild
+rebuild the crash kernel initramfs.
+.TP
+.I propagate
+Helps to setup key authentication for ssh storage since it's
+impossible to use password authentication during kdump.
+.TP
+.I showmem
+Prints the size of reserved memory for crash kernel in megabytes.
+
+.SH "SEE ALSO"
+.BR kdump.conf (5),
+.BR mkdumprd (8)
diff --git a/kexec-Add-quick-kexec-support.patch b/kexec-Add-quick-kexec-support.patch
new file mode 100644
index 0000000..b4a7276
--- /dev/null
+++ b/kexec-Add-quick-kexec-support.patch
@@ -0,0 +1,118 @@
+From 893ef61ca2b1e857b950654c1bb57f3624df5dc5 Mon Sep 17 00:00:00 2001
+From: snoweay <snoweay@163.com>
+Date: Wed, 12 Aug 2020 07:53:13 -0400
+Subject: [PATCH] kexec: Add quick kexec support
+
+Add quick kexec option -q and flags.
+
+In normal kexec, relocating kernel may cost 5 ~ 10 seconds, to
+copy all segments from vmalloced memory to kernel boot memory,
+because of disabled mmu.
+
+We introduce quick kexec to save time of copying memory as above,
+just like kdump(kexec on crash), by using reserved memory.
+
+We also add this support in syscall kexec_load of linux kernel
+through flags of KEXEC_QUICK.
+
+Add KEXEC_FLAGS_MAX to avoid conflicting with KEXEC_LIVE_UPDATE.
+---
+ kexec/kexec-syscall.h | 2 ++
+ kexec/kexec-xen.h | 2 +-
+ kexec/kexec.c | 10 ++++++++++
+ kexec/kexec.h | 4 +++-
+ 4 files changed, 16 insertions(+), 2 deletion(-)
+
+diff --git a/kexec/kexec-syscall.h b/kexec/kexec-syscall.h
+index bea29d4..5f22353 100644
+--- a/kexec/kexec-syscall.h
++++ b/kexec/kexec-syscall.h
+@@ -109,6 +109,8 @@ static inline long kexec_file_load(int kernel_fd, int initrd_fd,
+
+ #define KEXEC_ON_CRASH 0x00000001
+ #define KEXEC_PRESERVE_CONTEXT 0x00000002
++#define KEXEC_QUICK 0x00000004
++#define KEXEC_FLAGS_MAX 0x00000010
+ #define KEXEC_ARCH_MASK 0xffff0000
+
+ /* Flags for kexec file based system call */
+diff --git a/kexec/kexec-xen.h b/kexec/kexec-xen.h
+index 70fb576..d417c90 100644
+--- a/kexec/kexec-xen.h
++++ b/kexec/kexec-xen.h
+@@ -79,7 +79,7 @@ extern int __xc_interface_close(xc_interface *xch);
+ #endif
+
+ #ifndef KEXEC_LIVE_UPDATE
+-#define KEXEC_LIVE_UPDATE 0x00000004
++#define KEXEC_LIVE_UPDATE KEXEC_FLAGS_MAX
+ #endif
+
+ int xen_get_kexec_range(int range, uint64_t *start, uint64_t *end);
+diff --git a/kexec/kexec.c b/kexec/kexec.c
+index f63b36b..5b8beca 100644
+--- a/kexec/kexec.c
++++ b/kexec/kexec.c
+@@ -1009,6 +1009,7 @@ void usage(void)
+ " -l, --load Load the new kernel into the\n"
+ " current kernel.\n"
+ " -p, --load-panic Load the new kernel for use on panic.\n"
++ " -q, --load-quick Load the new kernel to quick kexec\n"
+ " -u, --unload Unload the current kexec target kernel.\n"
+ " If capture kernel is being unloaded\n"
+ " specify -p with -u.\n"
+@@ -1340,6 +1341,7 @@ int main(int argc, char *argv[])
+ int has_opt_load = 0;
+ int do_load = 1;
+ int do_exec = 0;
++ int do_quick = 0;
+ int do_load_jump_back_helper = 0;
+ int do_shutdown = 1;
+ int do_sync = 1, skip_sync = 0;
+@@ -1460,6 +1462,14 @@ int main(int argc, char *argv[])
+ kexec_file_flags |= KEXEC_FILE_ON_CRASH;
+ kexec_flags = KEXEC_ON_CRASH;
+ break;
++ case OPT_QUICK:
++ do_load = 1;
++ do_exec = 0;
++ do_shutdown = 0;
++ do_quick = 1;
++ kexec_flags = KEXEC_QUICK;
++ skip_checks = 1;
++ break;
+ case OPT_MEM_MIN:
+ mem_min = strtoul(optarg, &endptr, 0);
+ if (*endptr) {
+diff --git a/kexec/kexec.h b/kexec/kexec.h
+index 595dd68..9cbc77f 100644
+--- a/kexec/kexec.h
++++ b/kexec/kexec.h
+@@ -218,6 +218,7 @@ extern int file_types;
+ #define OPT_UNLOAD 'u'
+ #define OPT_TYPE 't'
+ #define OPT_PANIC 'p'
++#define OPT_QUICK 'q'
+ #define OPT_KEXEC_FILE_SYSCALL 's'
+ #define OPT_KEXEC_SYSCALL 'c'
+ #define OPT_KEXEC_SYSCALL_AUTO 'a'
+@@ -249,6 +250,7 @@ extern int file_types;
+ { "entry", 1, 0, OPT_ENTRY }, \
+ { "type", 1, 0, OPT_TYPE }, \
+ { "load-panic", 0, 0, OPT_PANIC }, \
++ { "load-quick", 0, 0, OPT_QUICK }, \
+ { "mem-min", 1, 0, OPT_MEM_MIN }, \
+ { "mem-max", 1, 0, OPT_MEM_MAX }, \
+ { "reuseinitrd", 0, 0, OPT_REUSE_INITRD }, \
+@@ -259,7 +261,7 @@ extern int file_types;
+ { "status", 0, 0, OPT_STATUS }, \
+ { "print-ckr-size", 0, 0, OPT_PRINT_CKR_SIZE }, \
+
+-#define KEXEC_OPT_STR "h?vdfixyluet:pscaS"
++#define KEXEC_OPT_STR "h?vdfixyluet:pqscaS"
+
+ extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr);
+ extern void die(const char *fmt, ...)
+--
+2.30.0
+
diff --git a/kexec-Quick-kexec-implementation-for-arm64.patch b/kexec-Quick-kexec-implementation-for-arm64.patch
new file mode 100644
index 0000000..19c6338
--- /dev/null
+++ b/kexec-Quick-kexec-implementation-for-arm64.patch
@@ -0,0 +1,143 @@
+From 5a302cd06079a285cb24a74c0f60b26866ae4e4d Mon Sep 17 00:00:00 2001
+From: snoweay <snoweay@163.com>
+Date: Wed, 12 Aug 2020 07:59:06 -0400
+Subject: [PATCH] kexec: Quick kexec implementation for arm64
+
+Implement quick kexec on arch/arm64.
+
+Locate kernel segments from reserved memory of range "Quick kexec".
+---
+ kexec/arch/arm64/iomem.h | 1 +
+ kexec/arch/arm64/kexec-arm64.c | 42 +++++++++++++++++++++++++-----------
+ kexec/arch/arm64/kexec-image-arm64.c | 11 ++++++++++
+ 3 files changed, 41 insertions(+), 13 deletions(-)
+
+diff --git a/kexec/arch/arm64/iomem.h b/kexec/arch/arm64/iomem.h
+index 45d7953..f283f50 100644
+--- a/kexec/arch/arm64/iomem.h
++++ b/kexec/arch/arm64/iomem.h
+@@ -7,5 +7,6 @@
+ #define KERNEL_DATA "Kernel data\n"
+ #define CRASH_KERNEL "Crash kernel\n"
+ #define IOMEM_RESERVED "reserved\n"
++#define QUICK_KEXEC "Quick kexec\n"
+
+ #endif
+diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
+index 219ec49..8a3bb69 100644
+--- a/kexec/arch/arm64/kexec-arm64.c
++++ b/kexec/arch/arm64/kexec-arm64.c
+@@ -99,6 +99,9 @@ uint64_t get_vp_offset(void)
+ return arm64_mem.vp_offset;
+ }
+
++/* Reserved memory for quick kexec. */
++struct memory_range quick_reserved_mem;
++
+ /**
+ * arm64_process_image_header - Process the arm64 image header.
+ *
+@@ -627,23 +630,33 @@ on_error:
+ return result;
+ }
+
+-unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
++static unsigned long locate_hole_from_range(struct memory_range *range)
+ {
+ unsigned long hole;
++ unsigned long hole_end;
+
+- if (info->kexec_flags & KEXEC_ON_CRASH) {
+- unsigned long hole_end;
++ hole = (range->start < mem_min ? mem_min : range->start);
++ hole = _ALIGN_UP(hole, MiB(2));
++ hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
+
+- hole = (crash_reserved_mem[usablemem_rgns.size - 1].start < mem_min ?
+- mem_min : crash_reserved_mem[usablemem_rgns.size - 1].start);
+- hole = _ALIGN_UP(hole, MiB(2));
+- hole_end = hole + arm64_mem.text_offset + arm64_mem.image_size;
++ if ((hole_end > mem_max) ||
++ (hole_end > range->end)) {
++ dbgprintf("%s: Kexec kernel out of range\n", __func__);
++ hole = ULONG_MAX;
++ }
+
+- if ((hole_end > mem_max) ||
+- (hole_end > crash_reserved_mem[usablemem_rgns.size - 1].end)) {
+- dbgprintf("%s: Crash kernel out of range\n", __func__);
+- hole = ULONG_MAX;
+- }
++ return hole;
++}
++
++unsigned long arm64_locate_kernel_segment(struct kexec_info *info)
++{
++ unsigned long hole;
++
++ if (info->kexec_flags & KEXEC_ON_CRASH) {
++ hole = locate_hole_from_range(
++ &crash_reserved_mem[usablemem_rgns.size - 1]);
++ } else if (info->kexec_flags & KEXEC_QUICK) {
++ hole = locate_hole_from_range(&quick_reserved_mem);
+ } else {
+ hole = locate_hole(info,
+ arm64_mem.text_offset + arm64_mem.image_size,
+@@ -709,6 +722,8 @@ int arm64_load_other_segments(struct kexec_info *info,
+ hole_min = image_base + arm64_mem.image_size;
+ if (info->kexec_flags & KEXEC_ON_CRASH)
+ hole_max = crash_reserved_mem[usablemem_rgns.size - 1].end;
++ else if (info->kexec_flags & KEXEC_QUICK)
++ hole_max = quick_reserved_mem.end;
+ else
+ hole_max = ULONG_MAX;
+
+@@ -1050,7 +1050,8 @@ static bool to_be_excluded(char *str, unsigned long long start, unsigned long lo
+
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
+- !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)))
++ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
++ !strncmp(str, QUICK_KEXEC, strlen(QUICK_KEXEC)))
+ return false;
+ else
+ return true;
+diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c
+index aa8f2e2..f22db62 100644
+--- a/kexec/arch/arm64/kexec-image-arm64.c
++++ b/kexec/arch/arm64/kexec-image-arm64.c
+@@ -13,6 +13,9 @@
+ #include "kexec-arm64.h"
+ #include "kexec-syscall.h"
+ #include "arch/options.h"
++#include "iomem.h"
++
++extern struct memory_range quick_reserved_mem;
+
+ int image_arm64_probe(const char *kernel_buf, off_t kernel_size)
+ {
+@@ -38,6 +41,7 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
+ {
+ const struct arm64_image_header *header;
+ unsigned long kernel_segment;
++ unsigned long start, end;
+ int result;
+
+ if (info->file_mode) {
+@@ -61,6 +65,13 @@ int image_arm64_load(int argc, char **argv, const char *kernel_buf,
+ return 0;
+ }
+
++ if (info->kexec_flags & KEXEC_QUICK)
++ parse_iomem_single(QUICK_KEXEC, &start, &end);
++ dbgprintf("%s: Get Quick kexec reserved mem from 0x%016lx to 0x%016lx\n",
++ __func__, start, end);
++ quick_reserved_mem.start = start;
++ quick_reserved_mem.end = end;
++
+ header = (const struct arm64_image_header *)(kernel_buf);
+
+ if (arm64_process_image_header(header))
+--
+2.9.5
+
diff --git a/kexec-tools.spec b/kexec-tools.spec
new file mode 100644
index 0000000..160b456
--- /dev/null
+++ b/kexec-tools.spec
@@ -0,0 +1,450 @@
+%global eppic_ver e8844d3793471163ae4a56d8f95897be9e5bd554
+%global eppic_shortver %(c=%{eppic_ver}; echo ${c:0:7})
+%global mkdf_ver 1.7.3
+
+Name: kexec-tools
+Version: 2.0.26
+Release: 6
+License: GPLv2
+Summary: The kexec/kdump userspace component
+URL: https://www.kernel.org/
+Source0: http://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.xz
+Source1: kdumpctl
+Source2: kdump.sysconfig
+Source3: kdump.sysconfig.x86_64
+Source4: kdump.sysconfig.i386
+Source5: kdump.sysconfig.ppc64
+Source7: mkdumprd
+Source8: kdump.conf
+Source9: https://github.com/makedumpfile/makedumpfile/releases/download/%{mkdf_ver}/makedumpfile-%{mkdf_ver}.tar.gz
+Source12: mkdumprd.8
+Source13: 98-kexec.rules
+Source15: kdump.conf.5
+Source16: kdump.service
+Source18: kdump.sysconfig.s390x
+Source19: https://github.com/lucchouina/eppic/archive/%{eppic_ver}/eppic-%{eppic_shortver}.tar.gz
+Source20: kdump-lib.sh
+Source21: kdump-in-cluster-environment.txt
+Source22: kdump-dep-generator.sh
+Source23: kdump-lib-initramfs.sh
+Source24: kdump.sysconfig.ppc64le
+Source25: kdumpctl.8
+Source26: live-image-kdump-howto.txt
+Source27: early-kdump-howto.txt
+Source28: kdump-udev-throttler
+Source29: kdump.sysconfig.aarch64
+Source30: kdump.sysconfig.loongarch64
+Source31: kdump.sysconfig.riscv64
+
+Source100: dracut-kdump.sh
+Source101: dracut-module-setup.sh
+Source102: dracut-monitor_dd_progress
+Source103: dracut-kdump-error-handler.sh
+Source104: dracut-kdump-emergency.service
+Source105: dracut-kdump-error-handler.service
+Source106: dracut-kdump-capture.service
+Source107: dracut-kdump-emergency.target
+Source108: dracut-early-kdump.sh
+Source109: dracut-early-kdump-module-setup.sh
+Source110: dracut-kdump-wait-for-target.sh
+
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+Requires(pre): coreutils sed zlib
+Requires: dracut >= 047-34.git20180604
+Requires: dracut-network >= 044-117
+Requires: dracut-squash >= 049-4
+Requires: ethtool
+BuildRequires: zlib-devel elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel
+BuildRequires: pkgconfig intltool gettext
+BuildRequires: systemd-units
+BuildRequires: automake autoconf libtool
+%ifarch %{ix86} x86_64
+Obsoletes: diskdumputils netdump kexec-tools-eppic
+%endif
+
+%ifnarch s390x
+Requires: systemd-udev%{?_isa}
+%endif
+
+%undefine _hardened_build
+
+Patch0001: add-secure-compile-options-for-makedumpfile.patch
+Patch0002: kexec-Add-quick-kexec-support.patch
+Patch0003: kexec-Quick-kexec-implementation-for-arm64.patch
+
+%ifarch sw_64
+Patch0004: sw_64.patch
+Patch0005: makedumpfile-1.7.2-sw.patch
+%endif
+
+%ifarch riscv64
+Patch0006: kexec-tools-Add-riscv-support.patch
+Patch0007: riscv-makedumpfile-1.7.3.patch
+%endif
+
+%ifarch loongarch64
+Patch0008: Add-loongarch-iomem.h.patch
+%endif
+
+%description
+kexec-tools provides /sbin/kexec binary that facilitates a new
+kernel to boot using the kernel's kexec feature either on a
+normal or a panic reboot. This package contains the /sbin/kexec
+binary and ancillary utilities that together form the userspace
+component of the kernel's kexec feature.
+
+%package help
+Summary: Doc files for %{name}
+Buildarch: noarch
+
+%description help
+The %{name}-help package contains doc files for %{name}.
+
+%prep
+%setup -q
+
+mkdir -p -m755 kcp
+tar -z -x -v -f %{SOURCE9}
+tar -z -x -v -f %{SOURCE19}
+
+%autopatch -p1
+
+%build
+autoreconf
+%configure --sbindir=/usr/sbin \
+ CFLAGS="${CFLAGS} -fstack-protector-strong -Wl,-z,now -pie -fPIC -fPIE"
+rm -f kexec-tools.spec.in
+# for docs
+cp %{SOURCE21} %{SOURCE26} %{SOURCE27} .
+
+make
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+make -C eppic-%{eppic_ver}/libeppic
+make -C makedumpfile-%{mkdf_ver} LINKTYPE=dynamic USELZO=on USESNAPPY=on
+make -C makedumpfile-%{mkdf_ver} LDFLAGS="$LDFLAGS -I../eppic-%{eppic_ver}/libeppic -L../eppic-%{eppic_ver}/libeppic" eppic_makedumpfile.so
+%endif
+
+%install
+mkdir -p -m755 %{buildroot}/usr/sbin
+mkdir -p -m755 %{buildroot}%{_sysconfdir}/sysconfig
+mkdir -p -m755 %{buildroot}%{_localstatedir}/crash
+mkdir -p -m755 %{buildroot}%{_mandir}/man8/
+mkdir -p -m755 %{buildroot}%{_mandir}/man5/
+mkdir -p -m755 %{buildroot}%{_docdir}
+mkdir -p -m755 %{buildroot}%{_datadir}/kdump
+mkdir -p -m755 %{buildroot}%{_udevrulesdir}
+mkdir -p %{buildroot}%{_unitdir}
+mkdir -p -m755 %{buildroot}%{_bindir}
+mkdir -p -m755 %{buildroot}%{_libdir}
+mkdir -p -m755 %{buildroot}%{_prefix}/lib/kdump
+
+%ifarch riscv64
+sed -i 's/--initrd=$TARGET_INITRD //g' %{SOURCE1}
+%endif
+
+install -m 755 %{SOURCE1} %{buildroot}%{_bindir}/kdumpctl
+
+install -m 755 build/sbin/kexec %{buildroot}/usr/sbin/kexec
+install -m 755 build/sbin/vmcore-dmesg %{buildroot}/usr/sbin/vmcore-dmesg
+install -m 644 build/man/man8/kexec.8 %{buildroot}%{_mandir}/man8/
+install -m 644 build/man/man8/vmcore-dmesg.8 %{buildroot}%{_mandir}/man8/
+
+SYSCONFIG=%{_sourcedir}/kdump.sysconfig.%{_target_cpu}
+[ -f $SYSCONFIG ] || SYSCONFIG=%{_sourcedir}/kdump.sysconfig.%{_arch}
+[ -f $SYSCONFIG ] || SYSCONFIG=%{_sourcedir}/kdump.sysconfig
+install -m 644 $SYSCONFIG %{buildroot}%{_sysconfdir}/sysconfig/kdump
+
+install -m 755 %{SOURCE7} %{buildroot}/usr/sbin/mkdumprd
+install -m 644 %{SOURCE8} %{buildroot}%{_sysconfdir}/kdump.conf
+install -m 644 kexec/kexec.8 %{buildroot}%{_mandir}/man8/kexec.8
+install -m 644 %{SOURCE12} %{buildroot}%{_mandir}/man8/mkdumprd.8
+install -m 644 %{SOURCE25} %{buildroot}%{_mandir}/man8/kdumpctl.8
+install -m 755 %{SOURCE20} %{buildroot}%{_prefix}/lib/kdump/kdump-lib.sh
+install -m 755 %{SOURCE23} %{buildroot}%{_prefix}/lib/kdump/kdump-lib-initramfs.sh
+install -m 755 %{SOURCE28} $RPM_BUILD_ROOT%{_udevrulesdir}/../kdump-udev-throttler
+install -m 644 %{SOURCE15} %{buildroot}%{_mandir}/man5/kdump.conf.5
+install -m 644 %{SOURCE16} %{buildroot}%{_unitdir}/kdump.service
+install -m 755 -D %{SOURCE22} %{buildroot}%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
+install -m 644 %{SOURCE13} $RPM_BUILD_ROOT%{_udevrulesdir}/98-kexec.rules
+
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+install -m 755 makedumpfile-%{mkdf_ver}/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile
+install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.8 $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8
+install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.conf.5 $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5
+install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample
+install -m 755 makedumpfile-%{mkdf_ver}/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so
+mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/
+install -m 644 makedumpfile-%{mkdf_ver}/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/
+%endif
+
+%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')
+
+# For dracut modules
+mkdir -p -m755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase
+cp %{SOURCE100} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}}
+cp %{SOURCE101} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}}
+cp %{SOURCE102} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE102}}
+cp %{SOURCE103} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE103}}
+cp %{SOURCE104} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE104}}
+cp %{SOURCE105} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE105}}
+cp %{SOURCE106} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE106}}
+cp %{SOURCE107} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE107}}
+cp %{SOURCE110} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE110}}
+chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}}
+chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}}
+mkdir -p -m755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump
+cp %{SOURCE108} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix %{SOURCE108}}
+cp %{SOURCE109} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}}
+chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix %{SOURCE108}}
+chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}}
+chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE103}}
+
+%define dracutlibdir %{_prefix}/lib/dracut
+# For custom dracut modules
+mkdir -p %{buildroot}/%{dracutlibdir}/modules.d/
+mv %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/* %{buildroot}/%{dracutlibdir}/modules.d/
+
+%post
+%systemd_post kdump.service
+
+touch /etc/kdump.conf
+# Fix up broken boxes
+if [ -d /proc/bus/mckinley ]
+then
+ # for HP zx1 machines
+ sed -e's/\(^KDUMP_COMMANDLINE_APPEND.*\)\("$\)/\1 machvec=dig"/' \
+ /etc/sysconfig/kdump > /etc/sysconfig/kdump.new
+ mv /etc/sysconfig/kdump.new /etc/sysconfig/kdump
+elif [ -d /proc/sgi_sn ]
+then
+ # for SGI SN boxes
+ sed -e's/\(^KEXEC_ARGS.*\)\("$\)/\1 --noio"/' \
+ /etc/sysconfig/kdump > /etc/sysconfig/kdump.new
+ mv /etc/sysconfig/kdump.new /etc/sysconfig/kdump
+fi
+
+
+%postun
+%systemd_postun_with_restart kdump.service
+
+%preun
+%systemd_preun kdump.service
+
+%triggerun -- kexec-tools < 2.0.2-3
+# Save runlevel info for future migration
+/usr/bin/systemd-sysv-convert --save kdump >/dev/null 2>&1 ||:
+# Not needed after uninstall
+/sbin/chkconfig --del kdump >/dev/null 2>&1 || :
+/bin/systemctl try-restart kdump.service >/dev/null 2>&1 || :
+
+%triggerin -- kernel-kdump
+touch %{_sysconfdir}/kdump.conf
+
+%triggerpostun -- kernel kernel-xen kernel-debug kernel-PAE kernel-kdump
+# Search for kernel installs, if not found, remove kdump initrd
+IMGDIR=/boot
+for i in `ls $IMGDIR/initramfs*kdump.img 2>/dev/null`
+do
+ KDVER=`echo $i | sed -e's/^.*initramfs-//' -e's/kdump.*$//'`
+ if [ ! -e $IMGDIR/vmlinuz-$KDVER ]
+ then
+ rm -f $i
+ fi
+done
+
+
+%files
+%doc News
+%doc TODO
+%license COPYING
+%config(noreplace,missingok) %{_sysconfdir}/sysconfig/kdump
+%config(noreplace,missingok) %verify(not mtime) %{_sysconfdir}/kdump.conf
+%config %{_udevrulesdir}
+%{_udevrulesdir}/../kdump-udev-throttler
+%dir %{_localstatedir}/crash
+/usr/sbin/kexec
+/usr/sbin/mkdumprd
+/usr/sbin/vmcore-dmesg
+%{_bindir}/*
+%{_datadir}/kdump
+%{_prefix}/lib/kdump
+%{dracutlibdir}/modules.d/*
+%{_unitdir}/kdump.service
+%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+%{_libdir}/eppic_makedumpfile.so
+/usr/share/makedumpfile/
+%endif
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+%{_sysconfdir}/makedumpfile.conf.sample
+%endif
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+/usr/sbin/makedumpfile
+%endif
+
+%files help
+%doc early-kdump-howto.txt
+%doc kdump-in-cluster-environment.txt
+%doc live-image-kdump-howto.txt
+%{_mandir}/man8/kdumpctl.8.gz
+%{_mandir}/man8/kexec.8.gz
+%{_mandir}/man8/mkdumprd.8.gz
+%{_mandir}/man8/vmcore-dmesg.8.gz
+%{_mandir}/man5/*
+%ifarch %{ix86} x86_64 aarch64 sw_64 loongarch64 ppc64le riscv64
+%{_mandir}/man8/makedumpfile.8.gz
+%endif
+
+%changelog
+* Mon Jul 8 2024 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.26-6
+- Undo the deletion of rd.lvm.lv in cmdline
+
+* Mon May 13 2024 Wenhua Huang <huangwenhua@kylinos.cn> - 2.0.26-5
+- Add loongarch iomem.h
+
+* Thu Apr 18 2024 Mingzheng Xing <xingmingzheng@iscas.ac.cn> - 2.0.26-4
+- Add riscv64 support
+
+* Mon Jan 30 2023 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.26-3
+- update makedumpfile to makedumpfile-1.7.3
+
+* Tue Jan 2 2024 peng.zou <peng.zou@shingroup.cn> - 2.0.26-2
+- Add ppc64le support
+
+* Mon Jan 30 2023 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.26-1
+- update to kexec-tools-2.0.26.1
+
+* Fri Dec 30 2022 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.23-11
+- fix shellcheck error in dracut module setup
+
+* Mon Dec 12 2022 guojiancheng <jiancheng.guo@i-soft.com.cn> - 2.0.23-10
+- Add sw support
+
+* Tue Nov 17 2022 doupengda <doupengda@loongson.cn> - 2.0.23-9
+- add loongarch64 support
+
+* Wed Aug 24 2022 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.23-8
+- arm64: fix PAGE_OFFSET calc for flipped mm
+
+* Tue Aug 23 2022 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.23-7
+- kdumpctl:ignore deprecated and invalid kdump config option
+
+* Wed Aug 3 2022 chenhaixiang <chenhaixiang3@huawei.com> - 2.0.23-6
+- fix CVE-2021-20269
+
+* Fri Mar 11 2022 wangbin <wangbin224@huawei.com> - 2.0.23-5
+- packing 98-kexec.rules instead of 98-kexec.rules.ppc64
+
+* Wed Feb 23 2022 wangbin <wangbin224@huawei.com> - 2.0.23-4
+- arm64/crashdump: deduce paddr of _text based on kernel code size
+
+* Wed Feb 23 2022 snoweay <snoweay@163.com> - 2.0.23-3
+- Fix conflicts between quick kexec and load-live-update with xen.
+
+* Wed Dec 29 2021 zhouwenpei <zhouwenpei1@huawei.com> - 2.0.23-2
+- modify the patch header
+
+* Sat Dec 25 2021 zhouwenpei <zhouwenpei1@huawei.com> - 2.0.23-1
+- update to 2.0.23
+
+* Tue Jul 27 2021 zhouwenpei <zhouwenpei1@huawei.com> - 2.0.20-7
+- fix build fail caused by file format not recognized
+
+* Sat Mar 27 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.0.20-6
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:Fix bug: Filed to generate the vmcore file in the ARM architecture
+ Fix bug: Filed to generate the vmcore-dmesg.txt file in the ARM architecture
+
+* Mon Mar 22 2021 yangzhuangzhuang <yangzhuangzhuang1@huawei.com> - 2.0.20-5
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:support more than one crash kernel regions.
+ Fix bugs of unuseable quick kexec on arm64, becaues of arm64-kexec-allocate-memory-space-avoiding-reserved-regions
+ excluding QUICK_KEXEC memory region.
+
+* Mon Sep 14 2020 zhangruifang2020 <zhangruifang1@huawei.com> - 2.0.20-4
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:sychronize git patches to enhance quality
+
+* Thu Sep 10 2020 zhangruifang2020 <zhangruifang1@huawei.com> - 2.0.20-3
+- Type:bugfix
+- ID:NA
+- SUG:NA
+- DESC:fix issue about iomem file that contains too many contens.As a result,the kdump service failed.
+
+* Thu Aug 13 2020 snoweay <snoweay@163.com> - 2.0.20-2
+- Add support for quick kexec
+ kexec: Add quick kexec support
+ arm64: Quick kexec implementation for arm64
+
+* Thu Jul 23 2020 zhangxingliang <zhangxingliang3@huawei.com> - 2.0.20-1
+- Type:update
+- ID:NA
+- SUG:NA
+- DESC:update to 2.0.20
+
+* Thu May 14 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.0.17-16
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:fix kdump stuck
+
+* Wed Jan 1 2020 openEuler Buildteam <buildteam@openeuler.org> - 2.0.17-15
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:modify patch
+
+* Tue Dec 31 2019 Jialong Chen <chenjialong@huawei.com> - 2.0.17-14
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:modify SECTION_SIZE_BITS to 30 and keep the same as the kernel configuration.
+ add executable permissions for kdump-error-handler.sh.
+
+* Thu Dec 19 2019 chengquan <chengquan3@huawei.com> - 2.0.17-13
+- Type:enhancement
+- ID:NA
+- SUG:NA
+- DESC:add url for package
+
+* Wed Sep 25 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.0-17.12
+- add secure compile options and merge bugfix patches from community
+ xen: Avoid overlapping segments in low memory
+ x86: Check /proc/mounts before mtab for mounts
+ x86: Find mounts by FS type, not name
+ kexec/kexec.c: Add the missing close() for fd used for kexec_file_load()
+ kexec-uImage-arm64.c: Fix return value of uImage_arm64_probe()
+ kexec/kexec-zlib.h: Add 'is_zlib_file()' helper function
+ kexec/arm64: Add support for handling zlib compressed (Image.gz) image
+
+* Sat Sep 21 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.0-17.11
+- Package init
+
+* Thu Aug 22 2019 Yeqing Peng<pengyeqing@huawei.com> - 2.0-17.10.h1
+- Type:bugfix
+- ID:NA
+- SUG:restart
+- DESC: fix bugs as follows:
+ 1.dmesg fix infinite loop if log buffer wraps around.
+ 2.arm64 error out if kernel command line is too long.
+ 3.fix an error that can not parse the e820 reserved region.
+ 4.x86 fix BAD_FREE in get_efi_runtime_map().
+ 5.fix check against 'fdt_add_subnode' return value.
+ 6.arm64 add error handling check against return value of 'set_bootargs()'.
+ 7.fix adding '/chosen' node for cases where it is not available in dtb
+ passed via --dtb option.
+ 8.fix '/chosen' v/s 'chosen' node being passed to fdt helper functions.
+ 9.arm64 wipe old initrd addresses when patching the DTB.
+ 10.arm64 increase the command line buf space to 1536.
+ 11.arm64 bugfix get the paddr of mem_section return error address.
+ 12.arm64 support more than one crash kernel regions.
+ 13.modify SECTIONS_SIZE_BITS to 27 for arm64.
diff --git a/live-image-kdump-howto.txt b/live-image-kdump-howto.txt
new file mode 100644
index 0000000..1695a1c
--- /dev/null
+++ b/live-image-kdump-howto.txt
@@ -0,0 +1,25 @@
+Kdump now works on live images with some manual configurations. Here is the step
+by step guide.
+
+1. Enable crashkernel reservation
+
+Since there isn't any config file that can be used to configure kernel
+parameters for live images before booting them, we have to append 'crashkernel'
+argument in boot menu every time we boot a live image.
+
+2. Change dump target in /etc/kdump.conf
+
+When kdump kernel boots in a live environment, the default target /var/crash is
+in RAM so you need to change the dump target to an external disk or a network
+dump target.
+
+Besides, make sure that "default dump_to_rootfs" is not specified.
+
+3. Start kdump service
+
+ $ kdumpctl start
+
+4. Trigger a kdump test
+
+ $ echo 1 > /proc/sys/kernel/sysrq
+ $ echo c > /proc/sysrq-trigger
diff --git a/mkdumprd b/mkdumprd
new file mode 100644
index 0000000..35f5eed
--- /dev/null
+++ b/mkdumprd
@@ -0,0 +1,439 @@
+#!/bin/bash --norc
+# New mkdumprd
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# Written by Cong Wang <amwang@redhat.com>
+#
+
+[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+. $dracutbasedir/dracut-functions.sh
+. /lib/kdump/kdump-lib.sh
+export IN_KDUMP=1
+
+conf_file="/etc/kdump.conf"
+SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
+SAVE_PATH=$(get_save_path)
+OVERRIDE_RESETTABLE=0
+
+extra_modules=""
+dracut_args="--quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o \"plymouth dash resume ifcfg earlykdump\""
+
+is_wdt_addition_needed() {
+ local active
+
+ is_wdt_mod_omitted
+ [[ $? -eq 0 ]] && return 1
+ [[ -d /sys/class/watchdog/ ]] || return 1
+ for dir in /sys/class/watchdog/*; do
+ [[ -f "$dir/state" ]] || continue
+ active=$(< "$dir/state")
+ [[ "$active" = "active" ]] && return 0
+ done
+ return 1
+}
+
+add_dracut_arg() {
+ dracut_args="$dracut_args $@"
+}
+
+add_dracut_module() {
+ add_dracut_arg "--add" "\"$1\""
+}
+
+add_dracut_mount() {
+ add_dracut_arg "--mount" "\"$1\""
+}
+
+add_dracut_sshkey() {
+ add_dracut_arg "--sshkey" "\"$1\""
+}
+
+# caller should ensure $1 is valid and mounted in 1st kernel
+to_mount() {
+ local _dev=$1 _source _target _fstype _options _mntopts _pdev
+
+ _source=$(findmnt -k -f -n -r -o SOURCE $_dev)
+ _target=$(get_mntpoint_from_target $_dev)
+ # mount under /sysroot if dump to root disk or mount under
+ #/kdumproot/$_target in other cases in 2nd kernel. systemd
+ #will be in charge to umount it.
+
+ if [ "$_target" = "/" ];then
+ _target="/sysroot"
+ else
+ _target="/kdumproot/$_target"
+ fi
+
+ _fstype=$(findmnt -k -f -n -r -o FSTYPE $_dev)
+ [[ -e /etc/fstab ]] && _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev)
+ if [ -z "$_options" ]; then
+ _options=$(findmnt -k -f -n -r -o OPTIONS $_dev)
+ if [[ $_fstype == "nfs"* ]]; then
+ _options=$(echo $_options | sed 's/,addr=[^,]*//')
+ _options=$(echo $_options | sed 's/,proto=[^,]*//')
+ _options=$(echo $_options | sed 's/,clientaddr=[^,]*//')
+ fi
+ fi
+ # mount fs target as rw in 2nd kernel
+ _options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g')
+ # filter out 'noauto' here, it will be force appended later, avoid duplication
+ _options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g')
+ # drop nofail or nobootwait
+ _options=$(echo $_options | sed 's/\(^\|,\)nofail\($\|,\)/\1/g')
+ _options=$(echo $_options | sed 's/\(^\|,\)nobootwait\($\|,\)/\1/g')
+ # only mount the dump target when needed.
+ _options="$_options,noauto"
+
+ _mntopts="$_target $_fstype $_options"
+ #for non-nfs _dev converting to use udev persistent name
+ if [ -b "$_source" ]; then
+ _pdev="$(get_persistent_dev $_source)"
+ if [ -z "$_pdev" ]; then
+ return 1
+ fi
+
+ else
+ _pdev=$_dev
+ fi
+
+ echo "$_pdev $_mntopts"
+}
+
+is_readonly_mount() {
+ local _mnt
+ _mnt=$(findmnt -k -f -n -r -o OPTIONS $1)
+
+ #fs/proc_namespace.c: show_mountinfo():
+ #seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw");
+ [[ "$_mnt" =~ ^ro ]]
+}
+
+#Function: get_ssh_size
+#$1=dump target
+#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
+get_ssh_size() {
+ local _opt _out _size
+ _opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
+ _out=$(ssh -q -n $_opt $1 "df -P $SAVE_PATH")
+ [ $? -ne 0 ] && {
+ perror_exit "checking remote ssh server available size failed."
+ }
+
+ #ssh output removed the line break, so print field NF-2
+ _size=$(echo -n $_out| awk '{avail=NF-2; print $avail}')
+ echo -n $_size
+}
+
+#mkdir if save path does not exist on ssh dump target
+#$1=ssh dump target
+#caller should ensure write permission on $1:$SAVE_PATH
+#called from while loop and shouldn't read from stdin, so we're using "ssh -n"
+mkdir_save_path_ssh()
+{
+ local _opt _dir
+ _opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes"
+ ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null
+ _ret=$?
+ if [ $_ret -ne 0 ]; then
+ perror_exit "mkdir failed on $1:$SAVE_PATH"
+ fi
+
+ #check whether user has write permission on $1:$SAVE_PATH
+ _dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null)
+ _ret=$?
+ if [ $_ret -ne 0 ]; then
+ perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination"
+ fi
+ ssh -qn $_opt $1 rmdir $_dir
+
+ return 0
+}
+
+#Function: get_fs_size
+#$1=dump target
+get_fs_size() {
+ local _mnt=$(get_mntpoint_from_target $1)
+ echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}')
+}
+
+#Function: get_raw_size
+#$1=dump target
+get_raw_size() {
+ echo -n $(fdisk -s "$1")
+}
+
+#Function: check_size
+#$1: dump type string ('raw', 'fs', 'ssh')
+#$2: dump target
+check_size() {
+ local avail memtotal
+
+ memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo)
+ case "$1" in
+ raw)
+ avail=$(get_raw_size "$2")
+ ;;
+ ssh)
+ avail=$(get_ssh_size "$2")
+ ;;
+ fs)
+ avail=$(get_fs_size "$2")
+ ;;
+ *)
+ return
+ esac
+
+ if [ $? -ne 0 ]; then
+ perror_exit "Check dump target size failed"
+ fi
+
+ if [ $avail -lt $memtotal ]; then
+ echo "Warning: There might not be enough space to save a vmcore."
+ echo " The size of $2 should be greater than $memtotal kilo bytes."
+ fi
+}
+
+# $1: core_collector config value
+verify_core_collector() {
+ local _cmd="${1%% *}"
+ local _params="${1#* }"
+
+ if [ "$_cmd" != "makedumpfile" ]; then
+ if is_raw_dump_target; then
+ echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually."
+ fi
+ return
+ fi
+
+ if is_ssh_dump_target || is_raw_dump_target; then
+ if ! strstr "$_params" "-F"; then
+ perror_exit "The specified dump target needs makedumpfile \"-F\" option."
+ fi
+ _params="$_params vmcore"
+ else
+ _params="$_params vmcore dumpfile"
+ fi
+
+ if ! $_cmd --check-params $_params; then
+ perror_exit "makedumpfile parameter check failed."
+ fi
+}
+
+add_mount() {
+ local _mnt=$(to_mount "$1")
+
+ if [ $? -ne 0 ]; then
+ exit 1
+ fi
+
+ add_dracut_mount "$_mnt"
+}
+
+#handle the case user does not specify the dump target explicitly
+handle_default_dump_target()
+{
+ local _target
+ local _mntpoint
+
+ is_user_configured_dump_target && return
+
+ check_save_path_fs $SAVE_PATH
+
+ _save_path=$(get_bind_mount_source $SAVE_PATH)
+ _target=$(get_target_from_path $_save_path)
+ _mntpoint=$(get_mntpoint_from_target $_target)
+
+ SAVE_PATH=${_save_path##"$_mntpoint"}
+ add_mount "$_target"
+ check_size fs $_target
+}
+
+get_override_resettable()
+{
+ local override_resettable
+
+ override_resettable=$(grep "^override_resettable" $conf_file)
+ if [ -n "$override_resettable" ]; then
+ OVERRIDE_RESETTABLE=$(echo $override_resettable | cut -d' ' -f2)
+ if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ];then
+ perror_exit "override_resettable value $OVERRIDE_RESETTABLE is invalid"
+ fi
+ fi
+}
+
+
+# $1: function name
+for_each_block_target()
+{
+ local dev majmin
+
+ for dev in $(get_kdump_targets); do
+ [ -b "$dev" ] || continue
+ majmin=$(get_maj_min $dev)
+ check_block_and_slaves $1 $majmin && return 1
+ done
+
+ return 0
+}
+
+
+
+#judge if a specific device with $1 is unresettable
+#return false if unresettable.
+is_unresettable()
+{
+ local path="/sys/$(udevadm info --query=all --path=/sys/dev/block/$1 | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable"
+ local resettable=1
+
+ if [ -f "$path" ]
+ then
+ resettable="$(cat $path)"
+ [ $resettable -eq 0 -a "$OVERRIDE_RESETTABLE" -eq 0 ] && {
+ local device=$(udevadm info --query=all --path=/sys/dev/block/$1 | awk -F= '/DEVNAME/{print $2}')
+ echo "Error: Can not save vmcore because device $device is unresettable"
+ return 0
+ }
+ fi
+
+ return 1
+}
+
+#check if machine is resettable.
+#return true if resettable
+check_resettable()
+{
+ local _ret _target
+
+ get_override_resettable
+
+ for_each_block_target is_unresettable
+ _ret=$?
+
+ [ $_ret -eq 0 ] && return
+
+ return 1
+}
+
+# $1: maj:min
+is_crypt()
+{
+ local majmin=$1 dev line ID_FS_TYPE=""
+
+ line=$(udevadm info --query=property --path=/sys/dev/block/$majmin \
+ | grep "^ID_FS_TYPE")
+ eval "$line"
+ [[ "$ID_FS_TYPE" = "crypto_LUKS" ]] && {
+ dev=$(udevadm info --query=all --path=/sys/dev/block/$majmin | awk -F= '/DEVNAME/{print $2}')
+ echo "Device $dev is encrypted."
+ return 0
+ }
+ return 1
+}
+
+check_crypt()
+{
+ local _ret _target
+
+ for_each_block_target is_crypt
+ _ret=$?
+
+ [ $_ret -eq 0 ] && return
+
+ return 1
+}
+
+if ! check_resettable; then
+ exit 1
+fi
+
+if ! check_crypt; then
+ echo "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot."
+fi
+
+# firstly get right SSH_KEY_LOCATION
+keyfile=$(awk '/^sshkey/ {print $2}' $conf_file)
+if [ -f "$keyfile" ]; then
+ # canonicalize the path
+ SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile)
+fi
+
+if [ "$(uname -m)" = "s390x" ]; then
+ add_dracut_module "znet"
+fi
+
+if is_wdt_addition_needed; then
+ add_dracut_arg "-a" "watchdog"
+fi
+
+while read config_opt config_val;
+do
+ # remove inline comments after the end of a directive.
+ case "$config_opt" in
+ extra_modules)
+ extra_modules="$extra_modules $config_val"
+ ;;
+ ext[234]|xfs|btrfs|minix|nfs)
+ if ! findmnt $config_val >/dev/null; then
+ perror_exit "Dump target $config_val is probably not mounted."
+ fi
+
+ # User configured target, use $SAVE_PATH as the dump path within the target
+ check_save_path_user_configured "$config_val" "$SAVE_PATH"
+ check_size fs "$config_val"
+ add_mount "$config_val"
+ ;;
+ raw)
+ # checking raw disk writable
+ dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || {
+ perror_exit "Bad raw disk $config_val"
+ }
+ _praw=$(persistent_policy="by-id" get_persistent_dev $config_val)
+ if [ -z "$_praw" ]; then
+ exit 1
+ fi
+ add_dracut_arg "--device" "$_praw"
+ check_size raw $config_val
+ ;;
+ ssh)
+ if strstr "$config_val" "@";
+ then
+ mkdir_save_path_ssh $config_val
+ check_size ssh $config_val
+ add_dracut_module "ssh-client"
+ add_dracut_sshkey "$SSH_KEY_LOCATION"
+ else
+ perror_exit "Bad ssh dump target $config_val"
+ fi
+ ;;
+ core_collector)
+ verify_core_collector "$config_val"
+ ;;
+ dracut_args)
+ add_dracut_arg $config_val
+ ;;
+ *)
+ ;;
+ esac
+done <<< "$(read_strip_comments $conf_file)"
+
+handle_default_dump_target
+
+if [ -n "$extra_modules" ]
+then
+ add_dracut_arg "--add-drivers" "$extra_modules"
+fi
+
+if ! is_fadump_capable; then
+ # The 2nd rootfs mount stays behind the normal dump target mount,
+ # so it doesn't affect the logic of check_dump_fs_modified().
+ is_dump_to_rootfs && add_mount "$(to_dev_name $(get_root_fs_device))"
+
+ add_dracut_arg "--no-hostonly-default-device"
+fi
+
+echo "$dracut_args $@" | xargs dracut
+
+_rc=$?
+sync
+exit $_rc
diff --git a/mkdumprd.8 b/mkdumprd.8
new file mode 100644
index 0000000..7faae57
--- /dev/null
+++ b/mkdumprd.8
@@ -0,0 +1,33 @@
+.TH MKDUMRD 8 "Fri Feb 9 2007"
+.SH NAME
+mkdumprd \- creates initial ramdisk images for kdump crash recovery
+.SH SYNOPSIS
+\fBmkdumprd\fR [OPTION]
+
+.SH DESCRIPTION
+\fBmkdumprd\fR creates an initial ram file system for use in conjunction with
+the booting of a kernel within the kdump framework for crash recovery.
+\fBmkdumprds\fR purpose is to create an initial ram filesystem capable of copying
+the crashed systems vmcore image to a location specified in \fI/etc/kdump.conf
+
+\fBmkdumprd\fR interrogates the running system to understand what modules need to
+be loaded in the initramfs (based on configuration retrieved from
+\fI/etc/kdump.conf)\fR
+
+\fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase 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
+kdump service infrastructure to create one, and then manually unpack, modify and
+repack the image.
+
+
+.SH OPTIONS
+.TP
+All options here are passed to dracut directly, please refer \fBdracut\fR docs
+for the info.
+
+.SH "SEE ALSO"
+.BR dracut (8)
diff --git a/sources b/sources
new file mode 100644
index 0000000..7db3061
--- /dev/null
+++ b/sources
@@ -0,0 +1,3 @@
+eff1054d1b1e82128683f6fe7d58d55d eppic-e8844d3.tar.gz
+ce3c79e0f639035ef7ddfc39b286a61a kexec-tools-2.0.26.tar.xz
+79a6e73fde9293cc335e96df5654c22e makedumpfile-1.7.3.tar.gz