#!/bin/bash
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

. /usr/lib/kdump/setup-kdump.functions

kdump_get_config || return 1

KERNELVERSION=
FORCE=0
QUIET=0
DEBUG=false
DRACUT=/usr/bin/dracut
UPDATE_BOOTLOADER=/sbin/update-bootloader

#
# Prints usage.                                                              {{{
function usage()
{
    echo "mkdumprd - Create an initrd for kdump"
    echo ""
    echo "This script uses dracut(8) internally. Options:"
    echo ""
    echo "   -k <version>     Kernel to create the initrd for."
    echo "                    Defaults to the running kernel."
    echo "   -K <kernel>      Kernel binary to create the initrd for."
    echo "                    If you specify that option, also specify -I."
    echo "   -I <initrd>      Resulting initrd."
    echo "                    If you specify that option, also specify -K."
    echo "   -f               Force regeneration even if the configuration"
    echo "                    did not change."
    echo "   -q               Quiet (don't print status messages)."
    echo "   -d               Output debug information of the initrd build process."
    echo "   -h               Print this help."
}                                                                          # }}}

#
# Quiet message                                                              {{{
function status_message()
{
    local msg=$1

    if (( ! $QUIET )) ; then
        echo ">>> $msg"
    fi
}                                                                          # }}}

#
# Create a new initrd using dracut                                           {{{
function run_dracut()
{
    DRACUT_ARGS="--force --hostonly --no-hostonly-default-device --omit 'plymouth resume usrmount' $@"

    if [ -z "$KERNELVERSION" ]
    then
	KERNELVERSION=$(get_kernel_version "$KERNEL")
    fi

    DRACUT_ARGS="$DRACUT_ARGS --add 'kdump' $INITRD $KERNELVERSION"
    $DEBUG && DRACUT_ARGS="--debug $DRACUT_ARGS"
    echo "Regenerating kdump initrd ..." >&2
    eval "bash -$- $DRACUT $DRACUT_ARGS"
}                                                                          # }}}

#
# Rebuild all initrds                                                        {{{
function build_fadumprd()
{
    # With fadump, this script has no control over which kernel will
    # be booted after a crash, but any installed kernel can be used
    # to save the dump. Consequently, let dracut regenerate initrd
    # for all installed kernels.

    DRACUT_ARGS="--force --regenerate-all"
    $DEBUG && DRACUT_ARGS="--debug $DRACUT_ARGS"
    echo "Regenerating all initrds ..." >&2
    eval "bash -$- $DRACUT $DRACUT_ARGS && type -P $UPDATE_BOOTLOADER &> /dev/null && $UPDATE_BOOTLOADER --refresh"
}                                                                          # }}}

#
# Build $INITRD with dump capture support using dracut                       {{{
function build_initrd()
{
    if [ "$KDUMP_FADUMP" = "yes" ] ; then
        build_fadumprd
    else
        run_dracut --compress \'xz -0 --check=crc32\'
    fi
}                                                                          # }}}


# Option parsing                                                             {{{
while getopts "hfqk:K:I:d" name ; do
    case $name in
        k)  KERNELVERSION=$OPTARG
            ;;

        f)  FORCE=1
            ;;

        h)  usage
            exit 0
            ;;

        q)  QUIET=1
            ;;

        K)  KERNEL=$OPTARG
            ;;

        I)  INITRD=$OPTARG
            ;;
        
	d)  DEBUG=true
            ;;

        ?)  usage
            exit 1
            ;;
    esac
done
shift $(($OPTIND -1))
                                                                           # }}}

#
# if we don't have specified -K <file>, then get the kernel from the version
# if $KERNELVERSION is non-zero and use the default kernel for kdump
# if $KERNELVERSION is zero.
if [ -z "$KERNEL" ] ; then
    if [ -n "$KERNELVERSION" ] ; then
        KERNEL=/boot/vmlinuz-$KERNELVERSION
        test -f "$KERNEL" || KERNEL=/boot/image-$KERNELVERSION
        test -f "$KERNEL" || KERNEL=/boot/Image-$KERNELVERSION
        test -f "$KERNEL" || KERNEL=/boot/vmlinux-$KERNELVERSION
    else
        output=$(kdumptool find_kernel $find_kernel_args)
        KERNEL=$(echo "$output" | grep ^Kernel | cut -f 2)
        INITRD=$(echo "$output" | grep ^Initrd | cut -f 2)
    fi
fi

if ! [ -f "$KERNEL" ] ; then
    echo "Kernel $KERNEL does not exist."
    exit 1
fi

#
# if we don't have specified -I <file>, then get the kernel from the version
if [ -z "$INITRD" ] ; then
    INITRD=/boot/initrd-$KERNELVERSION

    if ! echo $KERNELVERSION | grep -q kdump ; then
        INITRD=$INITRD-kdump
    fi
fi

#
# check if we need to regenerate it?
if (( ! $FORCE )) ; then
    if [ -f "$INITRD" ] && \
            [ "$KDUMP_CONFIG" -ot "$INITRD" ] && \
            [ /root/.ssh/id_dsa.pub -ot "$INITRD" ] && \
            [ /root/.ssh/id_dsa -ot "$INITRD" ] && \
            [ /etc/hosts -ot "$INITRD" ] && \
            [ /etc/nsswitch.conf -ot "$INITRD" ] && \
            [ "$KERNEL" -ot "$INITRD" ] ; then
        status_message "Not regenerating kdump initrd. Use mkdumprd -f to force regeneration."
        exit 0
    fi
fi

build_initrd

exit $?

# vim: set ts=4 sw=4 et fdm=marker: :collapseFolds=1:
