#!/bin/sh
#
# This hotplug script gets called by udev (xsigo.rules)
#
#
export PATH=/sbin:/usr/sbin:/usr/bin:$PATH

if cat /etc/redhat-release |grep "Oracle" > /dev/null
then
	XEN_PLATFORM=oracle
else
        exit 0;
fi


LOGFILE=/var/log/xsigo-hotplug.log
NBSCR=/etc/xen/scripts/network-bridge
CMD_IP=/sbin/ip

LCKFILE=/tmp/xsigo-hotplug.lck

log_print() {
	printf "`date`: $*" >> $LOGFILE
}


xs_set_if_mtu()
{
	# odd delays like these help preventing the next error condition!
	sleep 2
	if [ ! -d $2 ]; then
		log_print "$1: No bridge interface found\n"
		return 1
	fi
	mtu=0
	for i in `ls $2`
	do
		if echo $i | grep ^peth > /dev/null 2>&1
		then
			mtu=`cat /sys/class/net/$i/mtu`
			log_print "$1: bound to $i, set MTU to $mtu\n"
			${CMD_IP} link set $1 mtu $mtu >> $LOGFILE 2>&1
			# Seen the above operation occasionally fail, so retry.
			# There's some clash with the vif bridge configuration script
			# which this workaround hopefully suffices.
			nmtu=$(ip link show $1 | sed -n 's/.* mtu \([0-9]\+\).*/\1/p')
			if [ $nmtu != $mtu ]; then
				log_print "$1: retrying setting MTU to $mtu\n"
				sleep 30
				${CMD_IP} link set $1 mtu $mtu >> $LOGFILE 2>&1
				if [ ! $? -eq 0 ]; then
					log_print "$1: retry operation failed!\n"
					exit 1
				else
					log_print "$1: retry MTU setting success\n"
				fi
			fi
		fi
	done
	if [ $mtu -eq 0 ]; then
		log_print "$1: Could not find peth interface\n"
	fi
}

xs_set_vif_mtu()
{
	brifdir=/sys/class/net/$1/brport/bridge/brif
	xs_set_if_mtu $1 $brifdir 
	return $?
}

xs_set_br_mtu()
{
	brifdir=/sys/class/net/$1/brif
	xs_set_if_mtu $1 $brifdir
	return $?
}


handle_add_remove() {
	vif_num=$2
	bridge=xenbr$vif_num
	#
	# handle eth interfaces for setting up the bridge and MTU,
	# and vif interfaces for setting MTU only.
	#
	if echo $1 | grep '^eth*' > /dev/null 2>&1
	then
		mtu=`cat /sys/class/net/$1/mtu`
		log_print "$1: netbridge $ACTION vifnum=$vif_num\n"
		$NBSCR $3 vifnum=$vif_num bridge=xenbr$vif_num netdev=$1
		if [ "$3" = "stop" ]; then
                        ifconfig $bridge down
                        brctl delbr $bridge
			return 0
		fi
		# set MTU on the bridge
		log_print "xenbr${vif_num}: set MTU to $mtu\n"
		${CMD_IP} link set xenbr$vif_num mtu $mtu >> $LOGFILE 2>&1

		# the following mtu setting may be attempted on the vnic
		# itself but with a lingering confusion on whether the
		# interface name is logical or physical, it is Ok to do this
		# as the vnic driver doesn't support mtu setting and it will
		# be a harmless thing to do.
		#
		log_print "$1: set MTU to $mtu\n"
		${CMD_IP} link set $1 mtu $mtu >> $LOGFILE 2>&1

		# set MTU for all vif interfaces.
		for i in `print_bridge_vifs $vif_num`
		do
			log_print "$i: set MTU to $mtu\n"
			${CMD_IP} link set $i mtu $mtu >> $LOGFILE 2>&1
		done
	elif echo $1 | grep '^vif' > /dev/null 2>&1
	then
		if [ "$3" = "stop" ]; then
			return 0
		fi
		xs_set_vif_mtu $1
	elif echo $1 | grep '^xenbr' > /dev/null 2>&1
	then
		if [ "$3" = "stop" ]; then
			return 0
		fi
		xs_set_br_mtu $1
	fi
	exit 0
}

print_bridge_vifs() {
	vif_no=$1
	brctl show | gawk -v br="xenbr$vif_no" '
	 	function pvif(str)
	 	{
			if (index(str, "vif") == 1)
				print str
		}
		{
			if ( $1 == br ) {
				$1=$4
				# choose only vif interfaces
				do pvif($1); while ((getline == 1) && (NF == 1))
			}
		}'
}

#
# Check if xend is running. On startup we want xend to configure our bridges
#
x=`ps aux | grep xend | grep -v grep | wc -l`
if [ $x == 0 ] ; then
        exit 0
fi

#
# Creat log file
#

touch $LOGFILE

exec	8>$LCKFILE

#
# Lock the transaction
# Exit will close the descriptor to release the lock
#
flock -x 8


log_print "`basename $0` args=$1,$2 action=$ACTION\n"

case	"$ACTION" in
	'add')
	handle_add_remove $1 $2 start
	;;
	'remove')
	handle_add_remove $1 $2 stop
	;;
	*)
	exit 0
	;;
esac
