#!/usr/bin/bash --norc
# Generate an initramfs image that isolates dump capture capability within
# the default initramfs using zz-fadumpinit dracut module.

MKDUMPRD="/sbin/mkdumprd"
if [[ $1 == --debug ]]; then
	set -x
	PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]-}): '
	shift
	MKDUMPRD+=" --debug"
	debug_dracut=--debug
else
	debug_dracut=--quiet
fi
MKDUMPRD+=" -f"

if [[ -f /etc/sysconfig/kdump ]]; then
	# shellcheck source=/dev/null
	. /etc/sysconfig/kdump
fi

[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
# shellcheck source=/dev/null
. "$dracutbasedir"/dracut-functions.sh
# shellcheck source=SCRIPTDIR/kdump-lib.sh
. /lib/kdump/kdump-lib.sh
# shellcheck source=SCRIPTDIR/kdump-logger.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

MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)"
[ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t mkfadumprd.XXXXXX failed."
# shellcheck disable=SC2154 # known issue of shellcheck https://github.com/koalaman/shellcheck/issues/1299
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

# 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"
# Don't use squash for capture image or default image as it negatively impacts
# compression ratio and increases the size of the initramfs image.
# Don't compress the capture image as uncompressed image is needed immediately.
# Also, early microcode would not be needed here.
if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs --omit squash --omit squash-squashfs --omit squash-erofs --no-compress --no-early-microcode; then
	perror_exit "mkfadumprd: failed to build image with dump capture support"
fi

### Unpack the initramfs having dump capture capability retaining previous file modification time.
# This helps in saving space by hardlinking identical files.
mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot"
if ! cpio -id --preserve-modification-time --quiet -D "$MKFADUMPRD_TMPDIR/fadumproot" < "$FADUMP_INITRD"; then
	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
	-i "$MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/hostonly-kernel-modules.txt"
	/usr/lib/dracut/fadump-kernel-modules.txt
)

# Use zstd compression method, if available
if ! have_compression_in_dracut_args; then
	if has_command zstd; then
		_dracut_isolate_args+=(--compress zstd)
	fi
fi

if ! dracut "$debug_dracut" --force "${_dracut_isolate_args[@]}" "$@" "$TARGET_INITRD"; then
	perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture capability"
fi
