all: Move the multi-configuration file reading routine to a common helper
Based on Emil's (xexaxo) feedback, we now have a common.sh file that contains the implementation of the routine to read all config files for kdump/pstore, and we use Makefile to join the files, having the same implemention in all users. Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
This commit is contained in:
151
kdump-load.sh.in
Normal file
151
kdump-load.sh.in
Normal file
@ -0,0 +1,151 @@
|
||||
# This function has 2 purposes: if 'kdump' is passed as argument and we don't
|
||||
# have crashkernel memory reserved, we edit grub config file and recreate
|
||||
# grub.cfg, so next boot has it reserved; in this case, we also bail-out,
|
||||
# since kdump can't be loaded anyway.
|
||||
#
|
||||
# If 'pstore' is passsed as argument, we try to unset crashkernel iff it's
|
||||
# already set AND the pattern in grub config is the one added by us - if the
|
||||
# users set crashkernel themselves, we don't mess with that.
|
||||
grub_update() {
|
||||
CRASHK="$(cat /sys/kernel/kexec_crash_size)"
|
||||
SED_ADD="s/^GRUB_CMDLINE_LINUX_DEFAULT=\"/GRUB_CMDLINE_LINUX_DEFAULT=\"${GRUB_CMDLINE}/g"
|
||||
|
||||
if [ "${GRUB_AUTOSET}" -eq 1 ]; then
|
||||
if [ "$1" = "kdump" ] && [ "${CRASHK}" -eq 0 ]; then
|
||||
sed -i "${SED_ADD}" "${GRUB_CFG_FILE}"
|
||||
|
||||
if ! grub-mkconfig -o "${GRUB_BOOT_FILE}" 1>/dev/null; then
|
||||
logger "kdump: failed to execute command \"${GRUB_CMD}\""
|
||||
exit 1
|
||||
fi
|
||||
sync "${GRUB_BOOT_FILE}" 2>/dev/null
|
||||
|
||||
logger "kdump: kexec won't succeed, no reserved memory in this boot..."
|
||||
logger "kdump: but we automatically set crashkernel for next boot."
|
||||
exit 0 # this is considered a successful run
|
||||
fi
|
||||
|
||||
if [ "$1" = "pstore" ] && [ "${CRASHK}" -ne 0 ]; then
|
||||
sed -i "s/\"${GRUB_CMDLINE}/\"/g" "${GRUB_CFG_FILE}"
|
||||
|
||||
if ! grub-mkconfig -o "${GRUB_BOOT_FILE}" 1>/dev/null; then
|
||||
logger "kdump: failed to execute command \"${GRUB_CMD}\""
|
||||
exit 1
|
||||
fi
|
||||
sync "${GRUB_BOOT_FILE}" 2>/dev/null
|
||||
|
||||
logger "kdump: cleared crashkernel memory previously set."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# This function is responsible for creating the kdump initrd, either
|
||||
# via command-line call or in case initrd doesn't exist during kdump load.
|
||||
create_initrd() {
|
||||
rm -f "${MOUNT_FOLDER}/kdump-initrd-$(uname -r).img"
|
||||
|
||||
echo "Creating the kdump initramfs for kernel \"$(uname -r)\" ..."
|
||||
DRACUT_NO_XATTR=1 dracut --no-early-microcode --host-only -q -m\
|
||||
"bash systemd systemd-initrd systemd-sysusers modsign dbus-daemon kdump dbus udev-rules dracut-systemd base fs-lib shutdown"\
|
||||
--kver "$(uname -r)" "${MOUNT_FOLDER}/kdump-initrd-$(uname -r).img"
|
||||
}
|
||||
|
||||
# This routine performs a clean-up by deleting the old/useless remaining
|
||||
# kdump initrd files.
|
||||
cleanup_unused_initrd() {
|
||||
INSTALLED_KERNELS="${MOUNT_FOLDER}/.installed_kernels"
|
||||
|
||||
find /lib/modules/* -maxdepth 0 -type d -exec basename {} \; 1> "${INSTALLED_KERNELS}"
|
||||
|
||||
find "${MOUNT_FOLDER}"/* -name "kdump-initrd*" -type f -print0 2>/dev/null |\
|
||||
while IFS= read -r -d '' file
|
||||
do
|
||||
FNAME="$(basename "${file}" .img)"
|
||||
KVER="${FNAME#kdump-initrd-}"
|
||||
if ! grep -q "${KVER}" "${INSTALLED_KERNELS}" ; then
|
||||
rm -f "${MOUNT_FOLDER}/${FNAME}.img"
|
||||
logger "kdump: removed unused file \"${FNAME}.img\""
|
||||
fi
|
||||
done
|
||||
|
||||
rm -f "${INSTALLED_KERNELS}"
|
||||
}
|
||||
|
||||
load_kdump_config
|
||||
|
||||
# Find the proper mount point expected for kdump collection:
|
||||
DEVN_MOUNTED="$(findmnt "${MOUNT_DEVNODE}" -fno TARGET)"
|
||||
|
||||
# Create the kdump main folder here, as soon as possible, given
|
||||
# the importance of such directory in all kdump/pstore steps.
|
||||
MOUNT_FOLDER="${DEVN_MOUNTED}/${MOUNT_FOLDER}"
|
||||
mkdir -p "${MOUNT_FOLDER}"
|
||||
|
||||
echo "${MOUNT_FOLDER}" > "${MNT_TMP}"
|
||||
sync "${MNT_TMP}"
|
||||
|
||||
# Notice that at this point it's required to have the full
|
||||
# MOUNT_FOLDER, so this must remain after the DEVNODE operations above.
|
||||
if [ "$1" = "initrd" ]; then
|
||||
create_initrd
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "$1" = "clear" ]; then
|
||||
rm -f "${MOUNT_FOLDER}"/kdump-initrd-*
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Pstore-RAM load; if it is configured via the config files and fails
|
||||
# to configure pstore, we still try to load the kdump. We try to reserve
|
||||
# here a ${MEM_REQUIRED} memory region.
|
||||
# Notice that we assume ramoops is a module here - if built-in, users
|
||||
# should properly load it through command-line parameters.
|
||||
if [ "${USE_PSTORE_RAM}" -eq 1 ]; then
|
||||
MEM_REQUIRED="${PSTORE_MEM_AMOUNT}"
|
||||
RECORD_SIZE="${PSTORE_RECORD_SZ}"
|
||||
RANGE=$(grep "RAM buffer" /proc/iomem | head -n1 | cut -f1 -d\ )
|
||||
|
||||
MEM_END=$(echo "$RANGE" | cut -f2 -d-)
|
||||
MEM_START=$(echo "$RANGE" | cut -f1 -d-)
|
||||
MEM_SIZE=$(( 16#${MEM_END} - 16#${MEM_START} ))
|
||||
|
||||
if [ ${MEM_SIZE} -ge "${MEM_REQUIRED}" ]; then
|
||||
if modprobe ramoops mem_address=0x"${MEM_START}" mem_size="${MEM_REQUIRED}" record_size="${RECORD_SIZE}"; then
|
||||
# If Pstore is set, update grub.cfg to avoid reserving crashkernel memory.
|
||||
logger "kdump: pstore-RAM was loaded successfully"
|
||||
cleanup_unused_initrd
|
||||
grub_update pstore
|
||||
exit 0
|
||||
fi
|
||||
logger "kdump: pstore-RAM load failed...will try kdump"
|
||||
fi
|
||||
# Fallback to kdump load - if we fail when configuring pstore, better
|
||||
# trying kdump; in case we have crashkernel memory reserved, lucky us.
|
||||
# If not, we're going to set that automatically on grub_update().
|
||||
# Notice that if it's not set, we bail-out in grub_update() - there's
|
||||
# no point in continuing since kdump cannot work.
|
||||
fi
|
||||
|
||||
cleanup_unused_initrd
|
||||
grub_update kdump
|
||||
|
||||
# After some consideration, we've stolen the kdump parameters from
|
||||
# Debian/Ubuntu implementation, it makes sense for us.
|
||||
KDUMP_CMDLINE=$(sed -re 's/(^| )(crashkernel|hugepages|hugepagesz)=[^ ]*//g;s/"/\\\\"/' /proc/cmdline)
|
||||
KDUMP_CMDLINE="${KDUMP_CMDLINE} panic=-1 oops=panic fsck.mode=force fsck.repair=yes nr_cpus=1 reset_devices"
|
||||
|
||||
VMLINUX="$(grep -o 'BOOT_IMAGE=[^ ]*' /proc/cmdline)"
|
||||
|
||||
# In case we don't have a valid initrd, for some reason, try creating
|
||||
# one before loading kdump (or else it will fail).
|
||||
INITRD_FNAME="${MOUNT_FOLDER}/kdump-initrd-$(uname -r).img"
|
||||
if [ ! -s "${INITRD_FNAME}" ]; then
|
||||
create_initrd
|
||||
fi
|
||||
|
||||
if ! kexec -s -p "${VMLINUX#*BOOT_IMAGE=}" --initrd "${INITRD_FNAME}" --append="${KDUMP_CMDLINE}"; then
|
||||
logger "kdump: kexec load failed"
|
||||
exit 1
|
||||
fi
|
||||
logger "kdump: panic kexec loaded successfully"
|
||||
Reference in New Issue
Block a user