Package: makedumpfile Version: 1:1.6.1-1 Severity: wishlist Tags: patch Hi,
Some users might want to store core dumps in the same place as kernel dumps (especially when storing them on a remote machine). To avoid having to configure two scripts, add a dump-core script to kdump-tools. It will use the same configuration file as kdump-tools. Set /proc/sys/kernel/core_pattern to pipe the core dumps to dump-core. You can use following sysctl configuration file: $ cat /etc/sysctl.d/50-dump-core.conf kernel.core_pattern = |/usr/share/kdump-tools/dump-core %e-pid%p-sig%s-%t # 2 = "suidsafe": Any binary which normally would not be dumped (see "0") # is dumped readable by root only. fs.suid_dumpable = 2 $ sysctl -p /etc/sysctl.d/50-dump-core.conf A patch is attached. Please review it carefully. Some could is duplicated and probably should be placed in a shell library file. -- Benjamin Drung System Developer Debian & Ubuntu Developer ProfitBricks GmbH Greifswalder Str. 207 D - 10405 Berlin Email: [email protected] URL: http://www.profitbricks.com Sitz der Gesellschaft: Berlin. Registergericht: Amtsgericht Charlottenburg, HRB 125506B. Geschäftsführer: Andreas Gauger, Achim Weiss.
>From 593ccd06abec57d55dcb116226df6375f03b2ca2 Mon Sep 17 00:00:00 2001 From: Benjamin Drung <[email protected]> Date: Thu, 9 Mar 2017 19:33:00 +0100 Subject: [PATCH] Add dump-core script Some users might want to store core dumps in the same place as kernel dumps (especially when storing them on a remote machine). To avoid having to configure two scripts, add a dump-core script to kdump-tools. It will use the same configuration file as kdump-tools. Set /proc/sys/kernel/core_pattern to pipe the core dumps to dump-core. You can use following sysctl configuration file: $ cat /etc/sysctl.d/50-dump-core.conf kernel.core_pattern = |/usr/share/kdump-tools/dump-core %e-pid%p-sig%s-%t # 2 = "suidsafe": Any binary which normally would not be dumped (see "0") # is dumped readable by root only. fs.suid_dumpable = 2 $ sysctl -p /etc/sysctl.d/50-dump-core.conf --- debian/dump-core | 283 +++++++++++++++++++++++++++++++++++++++++++++ debian/kdump-tools.install | 1 + 2 files changed, 284 insertions(+) create mode 100755 debian/dump-core diff --git a/debian/dump-core b/debian/dump-core new file mode 100755 index 0000000..2e0d15a --- /dev/null +++ b/debian/dump-core @@ -0,0 +1,283 @@ +#!/bin/bash +set -u + +# Copyright (C) 2017, ProfitBricks GmbH +# Authors: Benjamin Drung <[email protected]> +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# This tool can be used to store core dumps the same way as kernel dumps. +# Set /proc/sys/kernel/core_pattern to pipe the core dumps to this tool. +# You can use following sysctl configuration file: +# +# $ cat /etc/sysctl.d/50-dump-core.conf +# kernel.core_pattern = |/usr/share/kdump-tools/dump-core %e-pid%p-sig%s-%t +# # 2 = "suidsafe": Any binary which normally would not be dumped (see "0") +# # is dumped readable by root only. +# fs.suid_dumpable = 2 +# $ sysctl -p /etc/sysctl.d/50-dump-core.conf + +exec > >(logger -t "${0}" -p syslog.info) 2> >(logger -t "${0}" -p syslog.warn) + +echo "Called with parameters: $@" + +# Global Setup +KDUMP_DEFAULTS=/etc/default/kdump-tools +[ -r $KDUMP_DEFAULTS ] && . $KDUMP_DEFAULTS + +# Set up defaults +KDUMP_COREDIR=${KDUMP_COREDIR:=/var/crash} +NFS_TIMEO=${NFS_TIMEO:=600} +NFS_RETRANS=${NFS_RETRANS:=3} +KDUMP_STAMP=${1-$(date -u +%Y%m%d-%H%M%S.%N)} + + +# +# Return the name of the subdirectory to store core file. +# Will add hostname/IP according to the value of +# HOSTTAG if networked dump is selected + +define_stampdir() +{ + STAMP=$1 + HOSTTAG="${HOSTTAG:=ip}" + + if [ -z "${SSH-}" ] && [ -z "${NFS-}" ] && [ -z "${FTP-}" ]; then + echo "$KDUMP_COREDIR/$STAMP" + elif [ "$HOSTTAG" = "hostname" ];then + echo "$KDUMP_COREDIR/$(hostname)-$STAMP" + else + # Looping to give time to network to settle + local counter=0 + while [ $counter -lt 5 ];do + THIS_HOST="$(ip addr show up | grep -w inet | tail -n1 | awk '{print $2}' | cut -f1 -d'/')" + set -- $THIS_HOST + THIS_HOST=$1 + if [ -z "$THIS_HOST" ]; then + sleep 1 + counter=$(($counter + 1)) + else + break + fi + done + if [ -z "$THIS_HOST" ]; then + # Send log msg to stderr to avoid polluting + # the result of the function + echo "Unable to get IP from network" >&2 + echo "Reverting to HOSTTAG=hostname" >&2 + THIS_HOST="$(hostname)" + fi + echo "$KDUMP_COREDIR/$THIS_HOST-$STAMP" + fi +} + +compress() { + if [ "$KDUMP_COMPRESSION" = "bzip2" ]; then + bzip2 -c + elif [ "$KDUMP_COMPRESSION" = "gzip" ]; then + gzip -c + elif [ "$KDUMP_COMPRESSION" = "lz4" ]; then + lz4 -c + elif [ "$KDUMP_COMPRESSION" = "xz" ]; then + /usr/bin/xz -c + else + cat + fi +} + +compression_extension() { + if [ "$KDUMP_COMPRESSION" = "bzip2" ]; then + echo ".bz2" + elif [ "$KDUMP_COMPRESSION" = "gzip" ]; then + echo ".gz" + elif [ "$KDUMP_COMPRESSION" = "lz4" ]; then + echo ".lz4" + elif [ "$KDUMP_COMPRESSION" = "xz" ]; then + echo ".xz" + fi +} + +dump_local() +{ + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) + KDUMP_CORETEMP="$KDUMP_STAMPDIR/coredump-incomplete$(compression_extension)" + KDUMP_COREFILE="$KDUMP_STAMPDIR/coredump.$KDUMP_STAMP$(compression_extension)" + + # If we use NFS, verify that we can mount the FS + # + if [ -n "${NFS-}" ];then + echo "Mounting NFS mountpoint $NFS ..." + mount -t nfs -o nolock -o tcp -o soft -o timeo=${NFS_TIMEO} -o retrans=${NFS_RETRANS} $NFS $KDUMP_COREDIR + ERROR=$? + if [ $ERROR -ne 0 ];then + echo "Unable to mount remote NFS directory $NFS. Cannot save core dump" >&2 + return 1; + fi + + # FS is mounted, see if we can write to it + # + mkdir -p $KDUMP_STAMPDIR + ERROR=$? + + if [ $ERROR -ne 0 ];then + echo "Unable to write to the remote NFS directory $NFS. Cannot save core dump" >&2 + umount $KDUMP_COREDIR + UMNT_ERROR=$? + if [ $UMNT_ERROR -ne 0 ];then + echo "Unable to cleanly unmount the NFS file system" >&2 + fi + else + echo "Dumping to NFS mountpoint $NFS/$KDUMP_STAMP" + fi + else + mkdir -p $KDUMP_STAMPDIR + fi + + compress > $KDUMP_CORETEMP + ERROR=$? + + # did we succeed? + if [ $ERROR -eq 0 ]; then + mv $KDUMP_CORETEMP $KDUMP_COREFILE + echo "saved core dump in $KDUMP_STAMPDIR" + sync + else + echo "failed to save core dump in $KDUMP_STAMPDIR" >&2 + fi + + # If we use NFS, umount the remote FS + # + if [ -n "$NFS" ];then + umount $KDUMP_COREDIR + UMNT_ERROR=$? + if [ $UMNT_ERROR -ne 0 ] ; then + echo "Unable to cleanly unmount the NFS file system" >&2 + fi + fi + + return $ERROR +} + +dump_to_ftp() +{ + KDUMP_REMOTE_HOST="${FTP%%:*}" + local fqdn=$(host "${KDUMP_REMOTE_HOST}" | grep -v "not found" | tail -n 1 | cut -d " " -f 1 || echo "${KDUMP_REMOTE_HOST}") + KDUMP_COREDIR="${FTP#*:}" + if [ "$KDUMP_COREDIR" = "$FTP" ]; then + # No colon in FTP specified. Assuming / as path + KDUMP_COREDIR="/" + fi + + KDUMP_STAMPDIR=$(define_stampdir "") + + KDUMP_COREFILE="${KDUMP_STAMPDIR}$KDUMP_STAMP$(compression_extension)" + KDUMP_PACKAGES_FILE="${KDUMP_STAMPDIR}${KDUMP_STAMP}-packages.txt" + ERROR=0 + + FTPPUT_ARGS="" + if [ -n "${FTP_USER-}" ]; then + FTPPUT_ARGS="$FTPPUT_ARGS -u $FTP_USER" + fi + if [ -n "${FTP_PASSWORD-}" ]; then + FTPPUT_ARGS="$FTPPUT_ARGS -p $FTP_PASSWORD" + fi + if [ -n "${FTP_PORT-}" ]; then + FTPPUT_ARGS="$FTPPUT_ARGS -P $FTP_PORT" + fi + + compress | busybox ftpput $FTPPUT_ARGS $KDUMP_REMOTE_HOST $KDUMP_COREFILE - + ERROR=$? + + # did we succeed? + if [ $ERROR -ne 0 ]; then + echo "failed to save vmcore via FTP in $fqdn:$KDUMP_COREFILE" >&2 + else + echo "saved core dump via FTP in $fqdn:$KDUMP_COREFILE" + fi + + # dump the package list + dpkg-query -f='${Package}=${Version}\n' -W | busybox ftpput $FTPPUT_ARGS $KDUMP_REMOTE_HOST $KDUMP_PACKAGES_FILE - + ERROR=$? + # did we succeed? + if [ $ERROR == 0 ]; then + echo "saved installed packages list via FTP in $fqdn:$KDUMP_PACKAGES_FILE" + else + echo "failed to save saved installed packages via FTP in $fqdn:$KDUMP_PACKAGES_FILE" >&2 + fi + + return $ERROR +} + +dump_to_ssh() +{ + KDUMP_SSH_KEY="${SSH_KEY:=/root/.ssh/kdump_id_rsa}" + KDUMP_REMOTE_HOST="$SSH" + + KDUMP_STAMPDIR=$(define_stampdir $KDUMP_STAMP) + + KDUMP_CORETEMP="$KDUMP_STAMPDIR/coredump-incomplete$(compression_extension)" + KDUMP_COREFILE="$KDUMP_STAMPDIR/coredump.$KDUMP_STAMP$(compression_extension)" + KDUMP_PACKAGES_FILE="${KDUMP_STAMPDIR}/installed-packages.txt" + ERROR=0 + + ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST mkdir -p $KDUMP_STAMPDIR + ERROR=$? + # If remote connections fails, no need to continue + if [ $ERROR -ne 0 ] ; then + echo "Unable to reach remote server $KDUMP_REMOTE_HOST. No reason to continue" >&2 + return 1 + fi + + echo "sending makedumpfile $MAKEDUMP_ARGS $vmcore_file to $KDUMP_REMOTE_HOST : $KDUMP_CORETEMP" + compress | ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST dd of=$KDUMP_CORETEMP + ERROR=$? + if [ $ERROR -ne 0 ] ; then + echo "makedumpfile scp failed. The core dump file will not be available" >&2 + else + ERROR=0 + fi + + # did we succeed? + if [ $ERROR -ne 0 ]; then + echo "failed to save core dump in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR" >&2 + sync + else + ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST mv $KDUMP_CORETEMP $KDUMP_COREFILE + echo "saved vmcore in $KDUMP_REMOTE_HOST:$KDUMP_STAMPDIR" + fi + + # dump the package list + dpkg-query -f='${Package}=${Version}\n' -W | ssh -i $KDUMP_SSH_KEY $KDUMP_REMOTE_HOST dd of=$KDUMP_PACKAGES_FILE + ERROR=$? + # did we succeed? + if [ $ERROR == 0 ]; then + echo "saved installed packages list via SSH in $KDUMP_REMOTE_HOST:$KDUMP_PACKAGES_FILE" + else + echo "failed to save saved installed packages via SSH in $KDUMP_REMOTE_HOST:$KDUMP_PACKAGES_FILE" >&2 + fi + + return $ERROR +} + +if test -n "${KDUMP_TASKSET_CORES-}"; then + taskset -p -c "${KDUMP_TASKSET_CORES}" $$ || true +fi + +if [ -n "${FTP-}" ]; then + dump_to_ftp +elif [ -n "${SSH-}" ]; then + dump_to_ssh +else + dump_local +fi +exit $? diff --git a/debian/kdump-tools.install b/debian/kdump-tools.install index 86ef7e4..fb54352 100644 --- a/debian/kdump-tools.install +++ b/debian/kdump-tools.install @@ -1 +1,2 @@ debian/kdump-config /usr/sbin +debian/dump-core /usr/share/kdump-tools -- 2.9.3

