#!/bin/sh
#
#  diskdumpctl.sh
#
#  Copyright (C) 2004, 2005  FUJITSU LIMITED
#
# $Id: diskdumpctl.sh,v 1.12 2006/03/31 21:39:44 akira Exp $

KERNEL=$(uname -r | awk '{print substr($0,1,3);}')

if [ "$KERNEL" = "2.4" ]; then
	DISKDUMPCTL_PROC="/sbin/diskdumpctl_proc"
	exec $DISKDUMPCTL_PROC "$@"
	echo "$PROGRAM_NAME: exec $DISKDUMPCTL_PROC failed!" >&2
	exit 1
fi

# VERSION is given when "make install" is executed.
VERSION="1.4.1"
PROGRAM_NAME="diskdumpctl"

usage()
{
	echo "Usage: $PROGRAM_NAME [-u] device" >&2
	echo "       $PROGRAM_NAME -V" >&2
	echo "Available options:" >&2
	echo "	-u:   unregister the device" >&2
	echo "	-V:   show $PROGRAM_NAME version and exit" >&2

	exit 1
}

version()
{
	echo "$PROGRAM_NAME version $VERSION" >&2
	exit 0
}

invalid_option()
{
	opt=$1
	opt=$(echo $opt | sed 's/-//g')

	echo "$PROGRAM_NAME: invalid option -- $opt" >&2
}

# Check argument
if [ $# -le 0 -o $# -ge 3 ]; then
	usage
fi

# Check option
if [ $# = 2 ]; then
	case "$1" in
		"-u")	DEVFILE=$2
			CMD="delete" ;;
		"-"*)	invalid_option $1
			usage ;;
		*) 	usage ;;
	esac
elif [ $# = 1 ]; then
	case "$1" in
		"-V")	version ;;
		"-"*)	invalid_option $1
			usage ;;
		*)	DEVFILE=$1
			CMD="add" ;;
	esac
else
	usage
fi

if [ ! -e $DEVFILE ]; then
	echo "$PROGRAM_NAME: $DEVFILE does not exist!" >&2
	exit 1
fi

if [ -L $DEVFILE ]; then
	DEVFILE=$(readlink $DEVFILE)
fi

if [ ! -b $DEVFILE ]; then
	echo "$PROGRAM_NAME: $DEVFILE is not block device!" >&2
	exit 1
fi

# Get sysfs mounted point
SYSFSROOT=$(grep -w -m1 sysfs /proc/mounts | cut -d\  -f2)
if [ ! -d $SYSFSROOT ]; then
	echo "$PROGRAM_NAME: sysfs is not mounted!" >&2
	exit 1
fi

DEVNUM=$(printf "%d:%d" $(stat --format='0x%t 0x%T' $DEVFILE))

# Walk through /sys/block class and find the device which matches the specified
# device number.
for dnum in $(find $SYSFSROOT/block -name dev); do
	devnum=$(cat $dnum)
	if [ "$devnum" = "$DEVNUM" ]; then
		block_device=$(dirname $dnum)
		if [ -e "$block_device/device" ]; then
			# Whole Device
			DEV="$block_device"
			PARTNO=0
		else
			# Partition
			# Partition# = partition minor# - device minor#
			#
			DEV=$(dirname $block_device)
			PART_MINOR=${devnum##*:}

			base_devnum=$(cat $DEV/dev)
			DEV_MINOR=${base_devnum##*:}

			PARTNO=$((PART_MINOR - DEV_MINOR))

		fi
		break
	fi
done

if [ -z "$PARTNO" ]; then
	echo "$PROGRAM_NAME: $DEVFILE does not exist in /sys" >&2
	exit 1
fi

DUMPFILE="$DEV/device/dump"
if [ ! -f $DUMPFILE ]; then
	echo "$PROGRAM_NAME: $DEVFILE is not supported!" >&2
	exit 1
fi

if [ "$CMD" = "add" ]; then
	sign=""
	compval=0
	devstat="already"
	act="add"
else
	sign="-"
	compval=1
	devstat="not"
	act="remove"
fi

grep -w `basename $DEVFILE` $DUMPFILE > /dev/null
if [ $? -eq $compval ]; then
	echo "$PROGRAM_NAME: $DEVFILE is $devstat registered!" >&2
	exit 1
fi

echo $sign$PARTNO > $DUMPFILE
grep -w `basename $DEVFILE` $DUMPFILE > /dev/null
if [ $? -ne $compval ]; then
	echo "$PROGRAM_NAME: failed to $act $DEVFILE!" >&2
	exit 1
fi
