all: Rename the tool to kdumpst
Big but self-explanatory commit: rename the tool. The name choice was kdumpst, since it's a tool to enable both kdump and pstore setting, also it's a silly wordplay with the superlative of kdump, as in "kdumpest". It's an invasive change (touches most of the files), but should offer no functional change other than logging messages showing kdumpst now, instead of kdump, and some filenames. Notice it doesn't touch documentation, which will be done in a subsequent commit. Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
This commit is contained in:
210
kdumpst-load.sh.in
Normal file
210
kdumpst-load.sh.in
Normal file
@ -0,0 +1,210 @@
|
||||
# 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 "kdumpst: failed to execute command \"${GRUB_CMD}\""
|
||||
exit 1
|
||||
fi
|
||||
sync "${GRUB_BOOT_FILE}" 2>/dev/null
|
||||
|
||||
logger "kdumpst: kexec won't succeed, no reserved memory in this boot..."
|
||||
logger "kdumpst: 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 "kdumpst: failed to execute command \"${GRUB_CMD}\""
|
||||
exit 1
|
||||
fi
|
||||
sync "${GRUB_BOOT_FILE}" 2>/dev/null
|
||||
|
||||
logger "kdumpst: 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.
|
||||
# It accounts for both mkinitcpio and dracut users.
|
||||
create_initrd() {
|
||||
/usr/lib/kdumpst/kdump-mkinitcpio-hook.sh "$(uname -r)"
|
||||
/usr/lib/kdumpst/kdump-dracut-hook.sh "$(uname -r)"
|
||||
}
|
||||
|
||||
# This routine performs a clean-up by deleting the old/useless remaining
|
||||
# kdump initrd files. Even with alpm-hooks, users might install kernels
|
||||
# manually so it makes sense to have this fallback to avoid storage waste.
|
||||
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 "kdumpst: removed unused file \"${FNAME}.img\""
|
||||
fi
|
||||
done
|
||||
|
||||
rm -f "${INSTALLED_KERNELS}"
|
||||
}
|
||||
|
||||
# Now this routine performs a full deletion of all kdump initrd files.
|
||||
clear_all_initrds() {
|
||||
rm -f "${MOUNT_FOLDER}"/kdump-initrd-*
|
||||
}
|
||||
|
||||
# Next routine parses /proc/iomem to obtain the biggest RAM buffer
|
||||
# available. Saves the results in 2 global variables: MEM_{SIZE,START}.
|
||||
parse_ram_buffers() {
|
||||
BUFFERS="$(grep "RAM buffer" /proc/iomem)"
|
||||
while read -r line
|
||||
do
|
||||
RANGE=$(echo "$line" | cut -f1 -d\ )
|
||||
|
||||
MEM_END=$(echo "$RANGE" | cut -f2 -d-)
|
||||
MSTART=$(echo "$RANGE" | cut -f1 -d-)
|
||||
MSIZE=$(( 16#${MEM_END} - 16#${MSTART} ))
|
||||
|
||||
if [ ${MSIZE} -gt "${MEM_SIZE}" ]; then
|
||||
MEM_SIZE="${MSIZE}"
|
||||
MEM_START="${MSTART}"
|
||||
fi
|
||||
done <<< "${BUFFERS}"
|
||||
# Trick to preserve global variables modifications inside loops
|
||||
# using here-strings got from https://stackoverflow.com/a/16854326 .
|
||||
}
|
||||
|
||||
# Function to display basic help about how to use this tool.
|
||||
usage() {
|
||||
cat <<EOF
|
||||
${0##*/} <COMMAND>
|
||||
kdumpst loader.
|
||||
|
||||
Options:
|
||||
load
|
||||
Load pstore/kdump according to the configuration file.
|
||||
|
||||
create-initrd
|
||||
Create the minimal kdump initrd for the running kernel.
|
||||
|
||||
clear-initrd
|
||||
Delete all kdump minimal initrd images.
|
||||
EOF
|
||||
}
|
||||
|
||||
preamble() {
|
||||
load_kdumpst_config
|
||||
|
||||
# In case the kdumpst main folder doesn't exist, create it
|
||||
# here, as soon as possible.
|
||||
mkdir -p "${MOUNT_FOLDER}"
|
||||
}
|
||||
|
||||
# Entry point of the script.
|
||||
case $1 in
|
||||
clear-initrd)
|
||||
preamble
|
||||
clear_all_initrds
|
||||
exit 0
|
||||
;;
|
||||
create-initrd)
|
||||
preamble
|
||||
create_initrd
|
||||
exit 0
|
||||
;;
|
||||
load)
|
||||
# just bail from the case statement, jumping to code below
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Here starts the main purpose of this script, the load operation.
|
||||
preamble
|
||||
|
||||
# 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}"
|
||||
MEM_SIZE=0
|
||||
|
||||
parse_ram_buffers
|
||||
|
||||
if [ "${MEM_SIZE}" -gt 0 ]; 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 "kdumpst: pstore-RAM was loaded successfully"
|
||||
cleanup_unused_initrd
|
||||
grub_update pstore
|
||||
exit 0
|
||||
fi
|
||||
logger "kdumpst: 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
|
||||
|
||||
# The kdump kernel command-line has some parameters appended, check
|
||||
# the configuration files in order to change that. We also remove huge
|
||||
# pages settings here (and crashkernel reservation), to save memory on kdump.
|
||||
KDUMP_CMDLINE=$(sed -re 's/(^| )(crashkernel|hugepages|hugepagesz)=[^ ]*//g;s/"/\\\\"/' /proc/cmdline)
|
||||
KDUMP_CMDLINE="${KDUMP_CMDLINE} ${KDUMP_APPEND_CMDLINE}"
|
||||
|
||||
# To obtain the vmlinux binary path, try first using directly the command-line
|
||||
# information. If it fails, then attempt prepending /boot into that (faced
|
||||
# both situations in the field so far).
|
||||
VMLINUX="$(grep -o 'BOOT_IMAGE=[^ ]*' /proc/cmdline)"
|
||||
VMLINUX="${VMLINUX#*BOOT_IMAGE=}"
|
||||
if [ ! -s "${VMLINUX}" ]; then
|
||||
VMLINUX="/boot/${VMLINUX}"
|
||||
if [ ! -s "${VMLINUX}" ]; then
|
||||
logger "kdumpst: couldn't find the kernel image"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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}" --initrd "${INITRD_FNAME}" --append="${KDUMP_CMDLINE}"; then
|
||||
logger "kdumpst: kexec load failed"
|
||||
exit 1
|
||||
fi
|
||||
logger "kdumpst: panic kexec loaded successfully"
|
||||
Reference in New Issue
Block a user