#!/bin/sh set -eu version="${1-}" kdumpdir="/var/lib/kdump" [ -x /usr/sbin/mkinitramfs ] || exit 0 # passing the kernel version is required if [ -z "${version}" ]; then echo >&2 "W: kdump-tools: ${DPKG_MAINTSCRIPT_PACKAGE:-kdump-tools package} did not pass a version number" exit 2 fi if ! linux-version list | grep "${version}" > /dev/null ; then exit 0 fi # exit if kernel does not need an initramfs if [ "${INITRD-}" = 'No' ]; then exit 0 fi # initramfs generation may fail, or include an inappropriate set of kernel # modules in a chroot. Leave it to the target system to handle on reboot if [ -x "$(command -v ischroot)" ] && ischroot; then echo "W: kdump-tools: Executing in a chroot, skipping initramfs generation." >&2 exit 0; fi # avoid running multiple times if [ -n "${DEB_MAINT_PARAMS-}" ]; then eval set -- "$DEB_MAINT_PARAMS" if [ -z "$1" ] || [ "$1" != "configure" ]; then exit 0 fi fi if test ! -e /etc/initramfs-tools/initramfs.conf; then echo "W: kdump-tools: /etc/initramfs-tools/initramfs.conf is missing." >&2 exit 2 fi . /etc/initramfs-tools/initramfs.conf for conf_file in /etc/initramfs-tools/conf.d/*; do if test -f "$conf_file" && basename "$conf_file" | grep '^[[:alnum:]][[:alnum:]\._-]*$' | grep -qv '\.dpkg-.*$'; then . "$conf_file" fi done if test "${MODULES-most}" = most; then # Switch from "most" to "dep" to reduce the size of the initramfs. # "netboot" and "list" are expected to be already small enough. KDUMP_MODULES=dep fi # We need a modified copy of initramfs-tools directory # with MODULES=dep in initramfs.conf if [ ! -d "$kdumpdir" ];then mkdir -p "$kdumpdir" fi # Force re-creation of $kdumpdir/initramfs-tools # in case the source has changed since last time # we ran if [ -d "$kdumpdir/initramfs-tools" ];then rm -Rf $kdumpdir/initramfs-tools fi cp -pr /etc/initramfs-tools "$kdumpdir" initramfsdir="$kdumpdir/initramfs-tools" if test -n "${KDUMP_MODULES-}" -a "${KDUMP_MODULES-}" != "${MODULES}"; then mkdir -p "$initramfsdir/conf.d" echo "MODULES=${KDUMP_MODULES}" > "$initramfsdir/conf.d/zzz-kdump" fi # Add scsi_dh_* modules if in use otherwise # kexec reboot on multipath will fail # (LP: #1635597) for I in $(lsmod | grep scsi_dh | cut -d" " -f1);do echo "${I}" >> $initramfsdir/modules done #Add makedump scripts/init-bottom tee $initramfsdir/scripts/init-bottom/makedump 1> /dev/null << EOF #!/bin/sh PREREQ="" prereqs() { echo "\${PREREQ}" } case \${1} in prereqs) prereqs exit 0 ;; esac #Check if VMCORE is available if [ ! -f /proc/vmcore ]; then exit 0 fi . /scripts/functions . /scripts/local log_end_msg log_begin_msg "mounting \${ROOT} over \${rootmnt}" sleep 2 log_end_msg mount -o remount,rw,relatime,errors=remount-ro \${ROOT} \${rootmnt} log_begin_msg "Dumping the crashed kernel" log_end_msg KDUMP_DEFAULTS=\${rootmnt}/etc/default/kdump-tools [ -r \$KDUMP_DEFAULTS ] && . \$KDUMP_DEFAULTS mkdir -p \${rootmnt}/var/crash rm -fr /var/crash ln -s \${rootmnt}/var/crash /var/crash KDUMP_COREDIR=\${KDUMP_COREDIR:=/var/crash} KDUMP_SKIP_VMCORE=\${KDUMP_SKIP_VMCORE:=1} KDUMP_DUMP_DMESG=\${KDUMP_DUMP_DMESG:=1} KDUMP_NUM_DUMPS=\${KDUMP_NUM_DUMPS:=0} MAKEDUMP_ARGS=\${MAKEDUMP_ARGS:="-c -d 31"} IOMEM_ADDR=\`grep -i "Crash kernel" /proc/iomem | sed "s/-..*//" | sed "s/^[ 0]*/0x/"\` vmcore_file=/proc/vmcore KDUMP_STAMP=\`date +"%Y%m%d%H%M"\` KDUMP_STAMPDIR="\$KDUMP_COREDIR/\$KDUMP_STAMP" if [ -d \$KDUMP_STAMPDIR ]; then log_failure_msg "Directory \$KDUMP_STAMPDIR already exist" exit 1 fi mkdir -p \$KDUMP_STAMPDIR KDUMP_COREFILE="\$KDUMP_STAMPDIR/dump.\$KDUMP_STAMP" KDUMP_DMESGFILE="\$KDUMP_STAMPDIR/dmesg.\$KDUMP_STAMP" if [ "\$KDUMP_DUMP_DMESG" -eq 1 ] ; then log_begin_msg "running makedumpfile --dump-dmesg \$vmcore file \$KDUMP_DMESGFILE" sleep 2 log_end_msg makedumpfile --dump-dmesg \$vmcore_file \$KDUMP_DMESGFILE fi if [ "\$KDUMP_SKIP_VMCORE" -ne 1 ]; then log_begin_msg "running makedumpfile \$MAKEDUMP_ARGS \$vmcore_file \$KDUMP_COREFILE" sleep 2 log_end_msg makedumpfile \$MAKEDUMP_ARGS \$vmcore_file \$KDUMP_COREFILE fi sync umount \${rootmnt} 2> /dev/null log_success_msg "Rebooting system" sleep 2 echo 1 > /proc/sys/kernel/sysrq echo b > /proc/sysrq-trigger EOF chmod 755 $initramfsdir/scripts/init-bottom/makedump # Add makedump hooks tee $initramfsdir/hooks/makedump 1> /dev/null << EOF #!/bin/sh PREREQ="" prereqs() { echo "\$PREREQ" } case \$1 in prereqs) prereqs exit 0 ;; esac if [ ! -x /usr/bin/makedumpfile ]; then exit 0 fi . /usr/share/initramfs-tools/scripts/functions . /usr/share/initramfs-tools/hook-functions copy_exec /usr/bin/makedumpfile EOF chmod 755 $initramfsdir/hooks/makedump # Add cleanup hooks tee $initramfsdir/hooks/cleanup 1> /dev/null << EOF #!/bin/sh PREREQ="" prereqs() { echo "\$PREREQ" } case \$1 in prereqs) prereqs exit 0 ;; esac . /usr/share/initramfs-tools/scripts/functions . /usr/share/initramfs-tools/hook-functions rm -fr \${DESTDIR}/lib/modules/\${version}/kernel/drivers/gpu rm -fr \${DESTDIR}/lib/modules/\${version}/kernel/drivers/video rm -fr \${DESTDIR}/lib/modules/\${version}/kernel/drivers/vfio rm -fr \${DESTDIR}/lib/modules/\${version}/updates/dkms/nvidia* rm -fr \${DESTDIR}/lib/firmware/amdgpu rm -fr \${DESTDIR}/lib/firmware/cxgb* rm -fr \${DESTDIR}/lib/firmware/radeon EOF chmod 755 $initramfsdir/hooks/cleanup sed -e 's/MODULES=.*/MODULES=dep/' /etc/initramfs-tools/initramfs.conf > "$initramfsdir/initramfs.conf" || true if ! [ -e "$initramfsdir/initramfs.conf" ];then echo >&2 "W: kdump-tools: Unable to create $initramfsdir/initramfs.conf" exit 2 fi # Mark our custom initramfs.conf to indicate that kdump-tools # hooks/scripts should run/get included in our minimal initrd. # # Unfortunately, this is not true for Debian. OPTION=VAR is a # control provided only by Ubuntu initramfs-tools, so this is # innocuous /harmless on Debian - kept here for better code # sync between Debian and Ubuntu. We needed special checks on # hook/script in Debian to prevent them on regular initrd. echo "KDUMP=y" >> $initramfsdir/initramfs.conf # Cleaning up existing initramfs with same version # as mkinitramfs do not have a force option if [ -e "$kdumpdir/initrd.img-${version}" ];then rm -f "$kdumpdir/initrd.img-${version}" fi # we're good - create initramfs. echo "kdump-tools: Generating $kdumpdir/initrd.img-${version}" INITRD_TMPDIR="$(mktemp -d)" INITRD_FNAME="initrd.img-${version}" INITRD_CMDLINE=" -k -d ${initramfsdir} -o ${kdumpdir}/${INITRD_FNAME}.new ${version}" # NB: we *want* to split on spaces in INITRD_CMDLINE, so disable this check here # shellcheck disable=SC2086 if TMPDIR=${INITRD_TMPDIR} mkinitramfs ${INITRD_CMDLINE} 1>/dev/null; then mv "${kdumpdir}/${INITRD_FNAME}.new" "${kdumpdir}/${INITRD_FNAME}" # Retain the initrd decompressed size in order potential users (like # kdump memory estimator) are able to use that in calculations. INITRD_DECOMPRESSED=$(find "${INITRD_TMPDIR}" -maxdepth 1 ! -path "${INITRD_TMPDIR}" -type d) if [ -d "${INITRD_DECOMPRESSED}" ]; then du -sm "${INITRD_DECOMPRESSED}" | awk '{print $1}' > "${kdumpdir}/size_${INITRD_FNAME}" sync "${kdumpdir}/size_${INITRD_FNAME}" fi rm -rf "${INITRD_TMPDIR}" else mkinitramfs_return="$?" rm -f "$kdumpdir/initrd.img-${version}.new" echo "update-initramfs: failed for $kdumpdir/initrd.img-${version} with $mkinitramfs_return." >&2 rm -rf "${INITRD_TMPDIR}" exit $mkinitramfs_return fi