diff options
author | Daniel Golle <daniel@makrotopia.org> | 2017-03-21 15:58:13 -0600 |
---|---|---|
committer | Daniel Golle <daniel@makrotopia.org> | 2017-06-09 22:21:25 +0200 |
commit | 5e4bb476c0cc46dedc020a802f045d479e483857 (patch) | |
tree | 21fa856ca68582dd0225e6c700a4867661117fc3 /package/boot/kexec-tools/files | |
parent | 8b486ec2b52056b737a4ce64a2040a9a27a6bd60 (diff) | |
download | upstream-5e4bb476c0cc46dedc020a802f045d479e483857.tar.gz upstream-5e4bb476c0cc46dedc020a802f045d479e483857.tar.bz2 upstream-5e4bb476c0cc46dedc020a802f045d479e483857.zip |
kexec-tools: bump version and add support for crashdump kernel
split kexec-tools into two packages, kexec and kdump.
* kexec to simply execute a new kernel
* kdump is for loading and collecting debris of a crashed kernel with
support for kdump forensics.
In order to properly support booting into a crashkernel, an init script
as well as UCI configuration has been added.
As modifying the kernel cmdline is required for this to work in x86
platforms use an uci-defaults script to modify /boot/grub/grub.cfg.
To test collecting crash information, use the 'c' sysrq-trigger, ie.
echo c > /proc/sysrq-trigger
This should result in the crash kernel being executed and (depending
on the configution) dmesg and/or vmcore getting saved.
To check if the crash kernel was loaded properly, use the 'status'
command of the kdump init script.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Diffstat (limited to 'package/boot/kexec-tools/files')
-rw-r--r-- | package/boot/kexec-tools/files/kdump.config | 7 | ||||
-rw-r--r-- | package/boot/kexec-tools/files/kdump.defaults | 11 | ||||
-rwxr-xr-x | package/boot/kexec-tools/files/kdump.init | 182 |
3 files changed, 200 insertions, 0 deletions
diff --git a/package/boot/kexec-tools/files/kdump.config b/package/boot/kexec-tools/files/kdump.config new file mode 100644 index 0000000000..dc6054ffdf --- /dev/null +++ b/package/boot/kexec-tools/files/kdump.config @@ -0,0 +1,7 @@ + +config kdump + option enabled '1' + option save_dmesg '1' + option save_vmcore '0' +# using an external partition to store vmcore is highly recommended! +# option path '/mnt/crashdump' diff --git a/package/boot/kexec-tools/files/kdump.defaults b/package/boot/kexec-tools/files/kdump.defaults new file mode 100644 index 0000000000..2f15e757bf --- /dev/null +++ b/package/boot/kexec-tools/files/kdump.defaults @@ -0,0 +1,11 @@ +#!/bin/sh + +case $(uname -m) in + i?86|x86_64) + if ! grep -q crashkernel /boot/grub/grub.cfg; then + mount /boot -o remount,rw + sed -i 's/linux.*/& crashkernel=32M@32M/' /boot/grub/grub.cfg + mount /boot -o remount,ro + fi + ;; +esac diff --git a/package/boot/kexec-tools/files/kdump.init b/package/boot/kexec-tools/files/kdump.init new file mode 100755 index 0000000000..057b8cc17a --- /dev/null +++ b/package/boot/kexec-tools/files/kdump.init @@ -0,0 +1,182 @@ +#!/bin/sh /etc/rc.common + +START=41 +STOP=98 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Print crashkernel status" + +verify_kdump() { + local cfg="$1" + local enabled + local path + local save_vmcore + local save_dmesg + + config_get_bool enabled "$cfg" enabled 1 + config_get_bool save_dmesg "$cfg" save_dmesg 1 + config_get_bool save_vmcore "$cfg" save_vmcore 0 + + [ "$enabled" -gt 0 ] || return 2 + + [ "$save_dmesg" -gt 0 ] || [ "$save_vmcore" -gt 0 ] || return 2 + + config_get path "$cfg" path "/" + + [ -d "$path" ] || mkdir -p "$path" 2>/dev/null || return 1 +} + +run_kdump() { + local cfg="$1" + local enabled + local path + local save_vmcore + local save_dmesg + + config_get_bool enabled "$cfg" enabled 1 + [ "$enabled" -gt 0 ] || return + + config_get_bool save_dmesg "$cfg" save_dmesg 1 + config_get_bool save_vmcore "$cfg" save_vmcore 0 + config_get path "$cfg" path "/" + + timestamp=$(date "+%Y%m%dT%H%M%S") + + if [ "$save_vmcore" -eq 1 ]; then + # would like 'sparse' but busybox doesn't support it + dd if=/proc/vmcore of="$path/vmcore-$timestamp" conv=fsync bs=1M + fi + + if [ "$save_dmesg" -eq 1 ]; then + vmcore-dmesg /proc/vmcore > "$path/dmesg-$timestamp" + fi + + sync + reboot -f +} + +find_kernel() { + . /lib/functions.sh + local kernel + + kernel="$BOOT_IMAGE" + if [ -r "$kernel" ]; then + echo $kernel + return 0 + fi + + kernel="$(find_mtd_part kernel)" + if [ -r "$kernel" ]; then + echo $kernel + return 0 + fi + + for voldir in /sys/class/ubi/ubi*_*; do + [ ! -e "$voldir" ] && continue + if [ "$(cat "${voldir}/name")" = "kernel" ]; then + kernel="/dev/$(basename "$voldir")" + echo $kernel + return 0 + fi + done + + return 1 +} + +load_crashkernel() { + local append_cmdline + local kernel + + kernel="$(find_kernel)" + [ $? -gt 0 ] && return 1 + + case "$(uname -m)" in + i?86|x86_64) + grep -q "crashkernel=" /proc/cmdline || return 1 + append_cmdline="1 irqpoll reset_devices maxcpus=1" + ;; + arm*) + append_cmdline="1 maxcpus=1 reset_devices" + ;; + esac + kexec -p "$kernel" --reuse-cmdline --append="$append_cmdline" + return $? +} + +start() { + local retval + + if [ ! -e /sys/kernel/kexec_crash_loaded ]; then + return 1 + fi + + if [ -e /proc/vmcore ]; then + config_load kdump + config_foreach run_kdump kdump + else + config_load kdump + config_foreach verify_kdump kdump + retval=$? + [ $retval = 1 ] && return 1 + [ $retval = 0 ] && load_crashkernel + return $? + fi +} + +stop() { + [ "$(cat /sys/kernel/kexec_crash_loaded)" = "1" ] || return + + if [ -e "$BOOT_IMAGE" ]; then + kexec -p -u "$BOOT_IMAGE" + fi +} + +status() { + local retval kernel + + if [ ! -e /sys/kernel/kexec_crash_loaded ]; then + echo "crashdump not supported by kernel" + return + fi + + if [ $(cat /sys/kernel/kexec_crash_size) -eq 0 ]; then + echo "memory for crashdump kernel not reserved!" + echo "check crashkernel= kernel cmdline parameter" + echo "(a reboot is required after installing kdump)" + return + fi + + kernel="$(find_kernel)" + if [ $? -gt 0 ]; then + echo "cannot find kernel image" + return + else + echo "using kernel image $kernel" + fi + + echo -n "kdump configuration is " + config_load kdump + retval=$? + if [ $retval = 0 ]; then + if [ "$(config_foreach echo kdump)" ]; then + config_foreach verify_kdump kdump + retval=$? + else + retval=1 + fi + fi + + if [ $retval = 0 ]; then + echo "valid" + elif [ $retval = 2 ]; then + echo "disabled" + else + echo "BROKEN" + fi + + echo -n "kexec crash kernel " + if [ "$(cat /sys/kernel/kexec_crash_loaded)" = "0" ]; then + echo -n "not " + fi + echo "loaded" +} |