#!/bin/bash
# 
# diskdump	This starts, stops, and reloads the diskdump
#		and crashdump facility
#
# chkconfig: - 04 94
# description: Save dump file if previous system crashed and initialize diskdump module.
# config: /etc/sysconfig/diskdump
#
# $Id: diskdump.sh,v 1.2 2004/06/07 19:21:13 anderson Exp $

# Source function library.
. /etc/rc.d/init.d/functions

CONF_DISKDUMP="/etc/sysconfig/diskdump"
DISKDUMPFMT="/usr/sbin/diskdumpfmt"
SAVECORE="/usr/sbin/savecore"
DISKDUMPCTL="/usr/sbin/diskdumpctl"
PROC_DISKDUMP="/proc/diskdump"
SCSI_UNIQUE_ID="/usr/bin/scsi_unique_id"
HDPARM="/sbin/hdparm -i"
MODPROBE="/sbin/modprobe"

# Source Dump Device
[ -f $CONF_DISKDUMP ] || exit 1
. $CONF_DISKDUMP
[ -z $DEVICE ] && {
	echo $"Device not specified in $CONF_DISKDUMP" 1>&2
	exit 1
}

RETVAL=0

start_device() {
	local dev=$1

	if $SCSI_UNIQUE_ID $dev >/dev/null 2>&1; then
		initlog -c "$MODPROBE scsi_dump"
		if [ $? != 0 ]; then
			RETVAL=$?
			return
		fi
	elif $HDPARM $dev >/dev/null 2>&1; then
		initlog -c "$MODPROBE ide-dump"
		if [ $? != 0 ]; then
			RETVAL=$?
			return
		fi
	fi

	initlog -c "$DISKDUMPCTL $dev"
	if [ $? != 0 ]; then
		RETVAL=$?
		return
	fi
}

show_result() {
	local string=$1
	local good=$2
	local bad=$3

	if [ $bad -eq 0 ]; then
		success $string
	elif [ $good -eq 0 ]; then
		failure $string
	else
		warning $string
	fi
	echo
}

start() {
	local dev
	local good_devices
	local bad_devices
	local savecore_devices
	local reformat_devices
	declare -i local good_count=0
	declare -i local bad_count=0

	for dev in $(echo $DEVICE | tr ':' ' '); do
		$DISKDUMPFMT -c $dev
		if [ $? -eq 0 ]; then
			good_devices="$good_devices $dev"
		elif [ $? -eq 1 ]; then
			savecore_devices="$savecore_devices $dev"
		else
			# delay error message later
			bad_devices="$bad_devices $dev"
		fi
	done

	if [ ! -z "$savecore_devices" ]; then
		echo -n $"Saving panic dump: "

		for dev in $savecore_devices; do
			initlog -c "$SAVECORE $dev"
			if [ $? -eq 0 ]; then
				good_count=good_count+1
				reformat_devices="$reformat_devices $dev"
			else
				bad_count=bad_count+1
				if [ -z $PRESERVEDUMP ]; then
					reformat_devices="$reformat_devices $dev"
				fi
			fi
		done

		show_result "saving" $good_count $bad_count
	fi

	good_count=0; bad_count=0

	if [ ! -z "$reformat_devices" ]; then
		echo -n $"Formatting dump device: "

		for dev in $reformat_devices; do
			initlog -c "$DISKDUMPFMT $dev"
			if [ $? -eq 0 ]; then
				good_devices="$good_devices $dev"
				good_count=good_count+1
			else
				bad_count=bad_count+1
			fi
		done

		show_result "formatting" $good_count $bad_count
	fi

	good_count=0

	echo -n $"Starting diskdump: "
	for dev in $bad_devices; do
		initlog -n "diskdump" -s $"$dev is not a dump device"
		bad_count=bad_count+1
	done
	for dev in $good_devices; do
		start_device $dev
		if [ $RETVAL -eq 0 ]; then
			good_count=good_count+1
		else
			bad_count=bad_count+1
		fi
	done

	show_result "activating" $good_count $bad_count
}

stop_device() {
	local dev=$1

	initlog -c "$DISKDUMPCTL -u $dev"
}

stop() {
	if test -f $PROC_DISKDUMP; then
		grep -v '^#' $PROC_DISKDUMP | while read dev sector; do
			stop_device $dev
		done

		if grep ^scsi_dump /proc/modules > /dev/null; then
			rmmod scsi_dump
		fi
		if grep ^ide-dump /proc/modules > /dev/null; then
			rmmod ide-dump
		fi
		if grep ^diskdump /proc/modules > /dev/null; then
			rmmod diskdump
		fi
	fi
}

format() {
	for dev in $(echo $DEVICE | tr ':' ' '); do
		$DISKDUMPFMT $dev
	done
}

initialformat() {
	for dev in $(echo $DEVICE | tr ':' ' '); do
		$DISKDUMPFMT -f $dev
	done
}

status() {
	if test -f $PROC_DISKDUMP; then
		echo $"diskdump enabled"
		RETVAL=0
	else
		echo $"diskdump not enabled"
		RETVAL=3
	fi
}

restart() {
	stop
	start
}

case "$1" in
	start) start ;;
	stop) stop ;;
	format) format ;;
	initialformat) initialformat ;;
	status) status ;;
	restart|reload) restart ;;
	*) echo $"Usage: $0 {start|stop|format|initialformat|status|restart|reload}"
	exit 1
esac

exit $RETVAL
