#!/bin/sh
### BEGIN INIT INFO
# Provides: dumpconf
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start:  1 2 3 4 5
# Default-Stop: 0 6
# Short-Description: Configure s390 dump feature
# Description: Configures the s390 dump feature. It uses the configuration file
#              /etc/sysconfig/dumpconf
### END INIT INFO

# chkconfig: 12345 01 99

DUMP_CONFIG_FILE=/etc/sysconfig/dumpconf

RETVAL=0

check_environment()
{
	if [ ! -f $DUMP_CONFIG_FILE ]; then
		echo "no config file found: $DUMP_CONFIG_FILE"
		exit 1
	fi

	if [ "$(cat /proc/filesystems|grep sysfs)" = "" ]; then
		echo "no sysfs found" >&2
		exit 1 
	fi

	SYSFSDIR=$(cat /proc/mounts|awk '$3=="sysfs"{print $2; exit}')
	if [ "$SYSFSDIR" = "" ]; then
		echo "sysfs not mounted" >&2
		exit 1
	fi

	DUMP_CONFIG_DIR=/$SYSFSDIR/firmware/dump
	ON_PANIC_CONFIG_FILE=/$SYSFSDIR/firmware/shutdown_act\
ions/on_panic

	if [ ! -d $DUMP_CONFIG_DIR ]; then
		echo "kernel has no dump on panic support"
		exit 0
	fi
	. $DUMP_CONFIG_FILE
}

printhelp()
{
    cat <<EOF
Usage: dumpconf [OPTIONS]

This script can be used to configure the dump device which is used by the
Linux kernel in case of a kernel panic.

It uses the configuration file /etc/sysconfig/dumpconf as input.

Options:

        -h, --help       print this help
        -v, --version    print version information
        start            enable configuration defined in /etc/sysconfig/dumpconf
        stop             disable dump on panic
        status           show current dump on panic configuration
EOF
}

printversion()
{
    cat <<EOF
dumpconf: zSeries dump configuration script version 1.0.
Copyright IBM Corp. 2006.
EOF
}

print_invalid_option()
{
    cat <<EOF
dumpconf: invalid option -- $1
Try 'dumpconf --help' for more information.
EOF
}

sanity_check() {
	DUMP_TYPE_CHECK=$(cat $DUMP_CONFIG_DIR/dump_type)
	ON_PANIC_CHECK=$(cat $ON_PANIC_CONFIG_FILE)
	if [ "$ON_PANIC_CHECK" == "dump" -a "$DUMP_TYPE_CHECK" == "none" ]; then
		echo "WARNING: on_panic is set to dump, but no dump configuration exists." >&2
		echo "         Are you sure, that this is really what you want?" >&2
	fi
}

# $1: dump device bus id (e.g. 0.0.4711)
verify_ccw_dump_device()
{
	line=$(lsdasd $1)
	if [ "$line" == "" ]; then
		echo "WARNING: device $1 not found!"
		return 1
	fi
	found=false
	for i in $line
	do
		if [ $found == true ]; then
			break
		fi
		if [ "$i" == "is" ]; then
			found=true
		fi
	done
	zgetdump -d /dev/$i > /dev/null 2>&1
	if [ $? == 0 ]; then
		return 0
	else
		echo "WARNING: $1 is no valid dump device!"
		return 1
	fi
}

start()
{
	# setup dump config

	ERRMSG="Dump configuration failed!"
	if [ "$DUMP_TYPE" == "" ]; then
		echo none > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
	elif [ "$DUMP_TYPE" == "none" ]; then
		echo none > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
	elif [ ! -d $DUMP_CONFIG_DIR/$DUMP_TYPE ]; then
		ERRMSG="dumptype '$DUMP_TYPE' not supported on this machine!"
		RETVAL=1
	elif [ "$DUMP_TYPE" == "ccw" ]; then
		echo $DEVICE > $DUMP_CONFIG_DIR/ccw/device || RETVAL=1
		echo ccw > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
	elif [ "$DUMP_TYPE" == "fcp" ]; then
		echo $DEVICE > $DUMP_CONFIG_DIR/fcp/device || RETVAL=1
		echo $WWPN > $DUMP_CONFIG_DIR/fcp/wwpn || RETVAL=1
		echo $LUN > $DUMP_CONFIG_DIR/fcp/lun || RETVAL=1
		echo $BOOTPROG > $DUMP_CONFIG_DIR/fcp/bootprog || RETVAL=1
		echo $BR_LBA > $DUMP_CONFIG_DIR/fcp/br_lba || RETVAL=1
		echo fcp > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
	fi

	# check for errors

	if [ $RETVAL -eq 1 ]; then
		echo none > $DUMP_CONFIG_DIR/dump_type
		echo stop > $ON_PANIC_CONFIG_FILE
		echo "ERROR: $ERRMSG Check $DUMP_CONFIG_FILE!" >&2
		return $RETVAL
	fi

	# print message

	CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type)

	if [ "$CONF_DUMP_TYPE" == "none" ]; then
		echo -n "No dump device configured. "
	else
		echo -n "$CONF_DUMP_TYPE dump device configured. "
	fi

	# setup on_panic

	if [ "$ON_PANIC" == "" ]; then
		ON_PANIC="stop"
	fi 
	echo $ON_PANIC > $ON_PANIC_CONFIG_FILE || RETVAL=1
	if [ $RETVAL -eq 1 ]; then
		echo stop > $ON_PANIC_CONFIG_FILE
		echo
		echo "ERROR: Invalid setting for on_panic '$ON_PANIC'! Please check $DUMP_CONFIG_FILE!" >&2
		return $RETVAL
	fi

	echo "\"$ON_PANIC\" on panic configured."

	sanity_check

	return $RETVAL
}

stop()
{
	echo none > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
	echo stop > $ON_PANIC_CONFIG_FILE || RETVAL=1
	if [ $RETVAL -eq 0 ]; then
		echo "Dump on panic is disabled now"
	else
		echo "Disabling dump on panic failed" >&2
	fi
	return $RETVAL
}

status()
{
	CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
	if [ "$CONF_DUMP_TYPE" == "none" ]; then
		echo "type....: no dump device configured"
	elif [ "$CONF_DUMP_TYPE" == "ccw" ]; then
		echo "type....: $(cat $DUMP_CONFIG_DIR/dump_type)" || RETVAL=1
		device=$(cat $DUMP_CONFIG_DIR/ccw/device)
		echo "device..: $device" || RETVAL=1
	elif [ "$CONF_DUMP_TYPE" == "fcp" ]; then
		echo "type....: $(cat $DUMP_CONFIG_DIR/dump_type)" || RETVAL=1
		echo "device..: $(cat $DUMP_CONFIG_DIR/fcp/device)" || RETVAL=1
		echo "wwpn....: $(cat $DUMP_CONFIG_DIR/fcp/wwpn)" || RETVAL=1
		echo "lun.....: $(cat $DUMP_CONFIG_DIR/fcp/lun)" || RETVAL=1
		echo "bootprog: $(cat $DUMP_CONFIG_DIR/fcp/bootprog)" || RETVAL=1
		echo "br_lba..: $(cat $DUMP_CONFIG_DIR/fcp/br_lba)" || RETVAL=1
	else
		echo "ERROR: Unknown dump device type '$TYPE'!" >&2
		echo "       Please check if you have the latest dumpconf package!" >&2
	fi

	ON_PANIC=$(cat $ON_PANIC_CONFIG_FILE) || RETVAL=1
	echo "on_panic: $ON_PANIC"
	if [ "$CONF_DUMP_TYPE" == "ccw" ]; then
		verify_ccw_dump_device $device
	fi
	sanity_check
}

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
	printhelp
	exit 0
elif [ "$1" = "-v" ] || [ "$1" = "--version" ]; then
	printversion
	exit 0
fi

check_environment

# See how we were called.
case "$1" in
	start|restart|reload|force-reload|try-restart)
		start
		;;
	stop)
		stop
		;;
	status)
		status
		;;
	*)
		print_invalid_option $1
		RETVAL=1
esac

exit $RETVAL
