#!/bin/sh
#
# dmraid-activate: Script to reformat the output of dmraid to be useful with
# udev.
#
# (c) 2008 Canonical Ltd.
#
# 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.

# Arguments: $1 = Name of array you want activated.
activate_array ()
{
	Raid_Setinfo=$(dmraid -i -si "$1")
	if [ -z "$Raid_Setinfo" ]; then
		log_error "Cannot retrieve RAID set information for $1"
		return 1
	fi

	Raid_Type=$(dmraid -i -si -ct "$1")
	Raid_Nodevs=$(dmraid -i -si -cd "$1")

	case "$Raid_Type" in
		stripe)
			if [ "$Raid_Nodevs" -lt 2 ]; then
				if [ -n "$Degraded" ]; then
					log_error "Cannot bring up a RAID0 array in degraded mode, not all devices present."
				fi
				return 2
			fi
			;;
		mirror)
			if [ "$Raid_Nodevs" -lt 2 ]; then
				if [ -z "$Degraded" ]; then
					log_error "Raid set $Raid_Name is degraded. Not activating"
					return 2
				else
					log_warning "Activating $Raid_Name in degraded mode"
					Return_Val=3
				fi
			fi
			;;
		raid5_*)
			modprobe -q dm_raid45
			if [ "$Raid_Nodevs" -lt 3 ]; then
				if [ -z "$Degraded" ]; then
					log_error "Raid set $Raid_Name is degraded. Not activating"
					return 2
				else
					log_warning "Activating $Raid_Name in degraded mode"
					Return_Val=3
				fi
			fi
			;;
	esac

	# At this point we have the required number of devs, or the user wants the
	# array brought up in degraded mode, except in the case of striped arrays.
	dmraid -i -ay -Z "$1"
	return $Return_Val
}

log_warning()
{
	if type logger > /dev/null ; then
		logger -t dmraid-activate "WARNING: $1"
	else
		echo "dmraid-activate: WARNING: $1"
	fi
}

log_error()
{
	if type logger > /dev/null ; then
		logger -t dmraid-activate "ERROR: $1"
	else
		echo "dmraid-activate: ERROR: $1"
	fi
}

modprobe -q dm_mod

if [ -z "$1" ] || [ "$1" = "--degraded" ] && [ "$#" -lt 2 ]; then
	echo "Node name not specified." >&2
	exit 1
fi

if [ "$1" = "--degraded" ]; then
	Degraded=1
	Node_Name=$2
else
	Node_Name=$1
fi

Raid_Name=$(dmraid -i -r -cr /dev/$Node_Name | grep -vi "No RAID disks")

if [ -z "$Raid_Name" ]; then
	exit 0
fi

# We need a special case for isw arrays, since it is possible to have several
# subsets of a RAID group, of varying RAID types.
case "$Raid_Name" in
	isw_*)
		Isw_Group_Name=$(echo "$Raid_Name" | cut -f 1-2 -d _)
		Isw_Subsets=$(dmraid -i -n "/dev/$Node_Name" | grep volume | sed 's/.*volume: " *\(.*\)"$/\1/')

		for isw_subset in $Isw_Subsets
		do
			activate_array "${Isw_Group_Name}_${isw_subset}"
		done
		break
		;;
	*)
		activate_array "$Raid_Name"
		break
		;;
esac

exit $Return_Val
