In case of fadump, the initramfs image has to be built to boot into
the production environment as well as to offload the active crash dump
to the specified dump target (for boot after crash). As the same image
would be used for both boot scenarios, it could not be built optimally
while accommodating both cases.
Use --include to include the initramfs image built for offloading
active crash dump to the specified dump target. Also, introduce a new
out-of-tree dracut module (99zz-fadumpinit) that installs a customized
init program while moving the default /init to /init.dracut. This
customized init program is leveraged to isolate fadump image within
the default initramfs image by kicking off default boot process
(exec /init.dracut) for regular boot scenario and activating fadump
initramfs image, if the system is booting after a crash.
Signed-off-by: Hari Bathini <hbathini(a)linux.ibm.com>
---
* Applying this patch, the initramfs image built with fadump support
can be too large, without
https://github.com/dracutdevs/dracut/pull/1532
TODO:
* Fix missing ssh identify file /root/.ssh/kdump_id_rsa with
squash not used and remote (ssh) dump target configured.
Changes in V3:
* Removed dependency with squash module by extracting fadump
initramfs to /fadumproot directory.
* Moved code that builds initramfs for fadump to mkfadumprd and
added cleanup support based on inputs from Kairui.
Changes in V2:
* Moved kernel modules installation from install() to installkernel() for
zz-fadumpinit dracut module.
* Updated kexec-tools.spec to install zz-fadumpinit module files appropriately.
* Fixed error check for capture initramfs image isolation with dracut.
dracut-fadump-init-fadump.sh | 20 ++++++++++++++
dracut-fadump-module-setup.sh | 17 ++++++++++++
dracut-module-setup.sh | 6 +---
kdumpctl | 22 +++-------------
kexec-tools.spec | 14 ++++++++++
mkfadumprd | 58 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 115 insertions(+), 22 deletions(-)
create mode 100644 dracut-fadump-init-fadump.sh
create mode 100644 dracut-fadump-module-setup.sh
create mode 100644 mkfadumprd
diff --git a/dracut-fadump-init-fadump.sh b/dracut-fadump-init-fadump.sh
new file mode 100644
index 0000000..736a7dd
--- /dev/null
+++ b/dracut-fadump-init-fadump.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+PATH=/bin:/sbin
+
+[ -e /proc/self/mounts ] \
+ || (mkdir -p /proc && mount -t proc -o nosuid,noexec,nodev proc /proc)
+
+grep -q '^sysfs /sys sysfs' /proc/self/mounts \
+ || (mkdir -p /sys && mount -t sysfs -o nosuid,noexec,nodev sysfs /sys)
+
+# If system is booting after a crash, switch to initramfs built for dump capture
+if [ -f /proc/device-tree/rtas/ibm,kernel-dump ] || [ -f
/proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
+ mkdir -p /newroot
+ mount -t ramfs ramfs /newroot
+ mv /fadumproot/* /newroot
+
+ # Jump to initramfs built for dump capture
+ SYSTEMD_IN_INITRD=lenient exec switch_root /newroot /init
+else
+ exec /init.dracut
+fi
diff --git a/dracut-fadump-module-setup.sh b/dracut-fadump-module-setup.sh
new file mode 100644
index 0000000..5ba4564
--- /dev/null
+++ b/dracut-fadump-module-setup.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+check() {
+ return 255
+}
+
+depends() {
+ return 0
+}
+
+install() {
+ mv -f "$initdir/init" "$initdir/init.dracut"
+ inst_script "$moddir/init-fadump.sh" /init
+
+ # Install required binaries for the init script (init-fadump.sh)
+ inst_multiple sh modprobe grep mkdir mount mv switch_root
+}
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 35a961a..ab369b3 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -37,7 +37,7 @@ depends() {
done
}
- if is_squash_available && ! is_fadump_capable; then
+ if is_squash_available; then
add_opt_module squash
else
dwarning "Required modules to build a squashed kdump image is
missing!"
@@ -1085,7 +1085,5 @@ install() {
${initdir}/etc/lvm/lvm.conf &>/dev/null
# Save more memory by dropping switch root capability
- if ! is_fadump_capable; then
- dracut_no_switch_root
- fi
+ dracut_no_switch_root
}
diff --git a/kdumpctl b/kdumpctl
index 978dae5..26247d1 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -8,6 +8,7 @@ KEXEC_ARGS=""
KDUMP_CONFIG_FILE="/etc/kdump.conf"
KDUMP_LOG_PATH="/var/log"
MKDUMPRD="/sbin/mkdumprd -f"
+MKFADUMPRD="/sbin/mkfadumprd"
DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt"
SAVE_PATH=/var/crash
SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa"
@@ -104,25 +105,10 @@ save_core()
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"
- ddebug "rebuild fadump initrd: $target_initrd_tmp $DEFAULT_INITRD_BAK
$KDUMP_KERNELVER"
- $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $KDUMP_KERNELVER \
- -i /tmp/fadump.initramfs /etc/fadump.initramfs
- if [ $? != 0 ]; then
- derror "mkdumprd: failed to rebuild initrd with fadump support"
- rm -f /tmp/fadump.initramfs
+ if ! $MKFADUMPRD "$DEFAULT_INITRD_BAK" "$TARGET_INITRD" --kver
"$KDUMP_KERNELVER"; then
+ derror "mkfadumprd: failed to make fadump initrd"
return 1
fi
- rm -f /tmp/fadump.initramfs
-
- # updating fadump initrd
- ddebug "updating fadump initrd: $target_initrd_tmp $TARGET_INITRD"
- mv $target_initrd_tmp $TARGET_INITRD
- sync
return 0
}
@@ -612,7 +598,7 @@ check_rebuild()
#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)
+ capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE $TARGET_INITRD | grep -e
^kdumpbase$ -e ^zz-fadumpinit$ | wc -l)
fi
fi
diff --git a/kexec-tools.spec b/kexec-tools.spec
index e94ed02..8605a1f 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -39,6 +39,7 @@ Source28: kdump-udev-throttler
Source29: kdump.sysconfig.aarch64
Source30: 60-kdump.install
Source31: kdump-logger.sh
+Source32: mkfadumprd
#######################################
# These are sources for mkdumpramfs
@@ -54,6 +55,9 @@ Source107: dracut-kdump-emergency.target
Source108: dracut-early-kdump.sh
Source109: dracut-early-kdump-module-setup.sh
+Source200: dracut-fadump-init-fadump.sh
+Source201: dracut-fadump-module-setup.sh
+
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
@@ -176,6 +180,7 @@ SYSCONFIG=$RPM_SOURCE_DIR/kdump.sysconfig.%{_target_cpu}
install -m 644 $SYSCONFIG $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/kdump
install -m 755 %{SOURCE7} $RPM_BUILD_ROOT/usr/sbin/mkdumprd
+install -m 755 %{SOURCE32} $RPM_BUILD_ROOT/usr/sbin/mkfadumprd
install -m 644 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/kdump.conf
install -m 644 kexec/kexec.8 $RPM_BUILD_ROOT%{_mandir}/man8/kexec.8
install -m 644 %{SOURCE12} $RPM_BUILD_ROOT%{_mandir}/man8/mkdumprd.8
@@ -211,6 +216,7 @@ install -m 644 makedumpfile-%{mkdf_ver}/eppic_scripts/*
$RPM_BUILD_ROOT/usr/shar
%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')
+%define remove_dracut_fadump_prefix() %(echo -n %1|sed 's/.*dracut-fadump-//g')
# deal with dracut modules
mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase
@@ -228,6 +234,13 @@ cp %{SOURCE108}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlyk
cp %{SOURCE109}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix
%{SOURCE109}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix
%{SOURCE108}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix
%{SOURCE109}}
+%ifarch ppc64 ppc64le
+mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit
+cp %{SOURCE200}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix
%{SOURCE200}}
+cp %{SOURCE201}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix
%{SOURCE201}}
+chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix
%{SOURCE200}}
+chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix
%{SOURCE201}}
+%endif
%define dracutlibdir %{_prefix}/lib/dracut
@@ -309,6 +322,7 @@ done
/usr/sbin/makedumpfile
%endif
/usr/sbin/mkdumprd
+/usr/sbin/mkfadumprd
/usr/sbin/vmcore-dmesg
%{_bindir}/*
%{_datadir}/kdump
diff --git a/mkfadumprd b/mkfadumprd
new file mode 100644
index 0000000..c0ee455
--- /dev/null
+++ b/mkfadumprd
@@ -0,0 +1,58 @@
+#!/bin/bash --norc
+# Generate an initramfs image that isolates dump capture capability within
+# the default initramfs using zz-fadumpinit dracut module.
+
+if [ -f /etc/sysconfig/kdump ]; then
+ . /etc/sysconfig/kdump
+fi
+
+[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+. $dracutbasedir/dracut-functions.sh
+. /lib/kdump/kdump-lib.sh
+. /lib/kdump/kdump-logger.sh
+
+#initiate the kdump logger
+if ! dlog_init; then
+ echo "mkfadumprd: failed to initiate the kdump logger."
+ exit 1
+fi
+
+readonly MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)"
+[ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t
mkfadumprd.XXXXXX failed."
+trap '
+ ret=$?;
+ [[ -d $MKFADUMPRD_TMPDIR ]] && rm --one-file-system -rf --
"$MKFADUMPRD_TMPDIR";
+ exit $ret;
+ ' EXIT
+
+# clean up after ourselves no matter how we die.
+trap 'exit 1;' SIGINT
+
+MKDUMPRD="/sbin/mkdumprd -f"
+# Default boot initramfs to be rebuilt
+REBUILD_INITRD="$1" && shift
+TARGET_INITRD="$1" && shift
+FADUMP_INITRD="$MKFADUMPRD_TMPDIR/fadump.img"
+
+### First build an initramfs with dump capture capability
+# this file tells the initrd is fadump enabled
+touch "$MKFADUMPRD_TMPDIR/fadump.initramfs"
+ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD
$KDUMP_KERNELVER"
+if ! $MKDUMPRD "$FADUMP_INITRD" -i
"$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs; then
+ perror_exit "mkfadumprd: failed to build image with dump capture support"
+fi
+
+### Unpack the initramfs having dump capture capability
+mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot"
+if ! (pushd "$MKFADUMPRD_TMPDIR/fadumproot" > /dev/null && lsinitrd
--unpack "$MKFADUMPRD_TMPDIR/fadump.img" && \
+ popd > /dev/null); then
+ ls "$MKFADUMPRD_TMPDIR/fadumproot"
+ derror "mkfadumprd: failed to unpack '$MKFADUMPRD_TMPDIR'"
+ exit 1
+fi
+
+### Pack it into the normal boot initramfs with zz-fadumpinit module
+_dracut_isolate_args="--rebuild $REBUILD_INITRD --add zz-fadumpinit -i
$MKFADUMPRD_TMPDIR/fadumproot /fadumproot"
+if ! dracut --force --quiet $_dracut_isolate_args $@ "$TARGET_INITRD"; then
+ perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture
capability"
+fi