# This script deletes the used backout data for a patch package
# and removes the deletes file entries.
#
# directory format options.
#
#pragma ident	"@(#)patch_postinstall	1.12	10/07/19 SMI"
#
# Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
#

# Definitions for override safety mechanism
PATCH_OVERRIDE_LIB="${PKG_INSTALL_ROOT}/usr/lib/patch/patch_override_lib"

# Check if we messaging is ready. Returns 0 on success, 1 on failure
# On successful run it leaves MSG_FILENAME variable defined
# 
# Usage:
#
# check_patch_script_messaging
#
check_patch_script_messaging()
{
	TMP_DIRNAME="/var/run"
	MSG_FILENAME="${TMP_DIRNAME}/patchrm_msg_file_${ACTIVE_PATCH}"

	if [ -w "${MSG_FILENAME}" ] ; then
		unset TMP_DIRNAME
		return 0
	else
		unset TMP_DIRNAME
		unset MSG_FILENAME
		return 1
	fi
}

# This function prepares a message to be printed to stdout towards the end
# of postpatch execution. If the message file is not ready, it at least tries
# immediate output to stdout which is currently know to work only in patch
# level scripts.
#
# Usage:
#
# print_patch_message "text_of_message_to_be_printed_out"
#
print_patch_message()
{
	if check_patch_script_messaging; then
		echo "$*" >> "${MSG_FILENAME}"
	else
		echo "$*"
	fi

	return 0
}

# script in a fucntion so that it can be overridden if needed.
patch_postinstall()
{
	SED="/usr/bin/sed"
	CP="/usr/bin/cp"
	RM="/usr/bin/rm -f"
	TRUE="/usr/bin/true"
	EXPR="/usr/bin/expr"
	BASENAME="/usr/bin/basename"
	DIRNAME="/usr/bin/dirname"
	NAWK="/usr/bin/nawk"
	PATH=/usr/sadm/bin:$PATH
	THIS_DIR=`dirname $0`
	RMF="/usr/sbin/removef"
	XARGS="/usr/bin/xargs"
	PATCH_COMMON_LIB="/usr/lib/patch/patch_common_lib"
	SAFEMODE_FAILED="Exiting! Patch deferred activation failed"
	INST_DIR="$INST_DATADIR/$PKG/install"

	# Set LC_ALL to avoid risk of undefined behavior
	LC_ALL=C
	export LC_ALL

	if [ "$SAFEMODE_INSTALL" = "true" ] ; then
	        if [ ! -s "$PATCH_COMMON_LIB" ]; then
	                puttext "$SAFEMODE_FAILED"
	                exit 1
	        fi
	        . $PATCH_COMMON_LIB
	        InitSafemode || {
	                puttext $SAFEMODE_FAILED
	                exit 1
	        }
	fi


	# Handle the pkg_* scripts in the undo package.
	#	pkg_* scripts are patched CAS 
	#       pkg_* scripts are copied to the destination directory
	#       after stripping out the pkg_ from the file name.
	#
	PKGDB="/var/sadm/pkg/$PKGINST"
	PSPOOL_PKG="$PKGDB/save/pspool/$PKGINST"

	for script in $INST_DIR/*; do
		srcscript=`$BASENAME $script`
		targscript=`echo $srcscript | $NAWK '
			/^pkg_/ {
				print "pspool";
				next;
			}
			/^pkgrm_/ {
				print "install";
				next;
			}
			{ print "dont_use" } '`
		if [ "$targscript" = "dont_use" ]; then
			continue
		fi
		if [ "$targscript" = "pspool" ]; then
			script=`echo $srcscript | $SED 's/pkg_//'`
			if [ -d "$PKG_INSTALL_ROOT$PSPOOL_PKG/install" ] ; then
				$CP $INST_DIR/$srcscript $PKG_INSTALL_ROOT$PSPOOL_PKG/install/$script
			fi
		elif [ "$targscript" = "install" ]; then
			script=`echo $srcscript | $SED 's/pkgrm_//'`
			if [ -d "$PKG_INSTALL_ROOT$PKGDB/install" ] ; then
				$CP $INST_DIR/$srcscript $PKG_INSTALL_ROOT$PKGDB/install/$script
			fi
		fi
	done

	Our_Deletes=$THIS_DIR/deletes

	#
	# Delete the used backout data
	#
	#
	# If this is a safemode patch package and it has a deletes file in it
	# handle the deletion of an object for safemode patching.
	#
	if [ -f $Our_Deletes ]; then
		PSPOOL_DIR="/var/sadm/pkg/$PKGINST/save/pspool/$PKGINST/install"
		UNREGISTER_LIST=/var/run/.$$.unregister.paths.$$
		UNREGISTER_BATCH=/var/run/.$$.unregister.batch.$$
		/usr/bin/rm -f $UNREGISTER_LIST

		cat $Our_Deletes | while read path; do
			Dir=`$DIRNAME "$path"`
			if [ "$Dir" = "$PSPOOL_DIR" ]; then
				path="${PKG_INSTALL_ROOT:-/}$path"
				if [ -f "$path" ]; then
					$RM "$path"
				fi
				continue
			fi
			# If path is relative, we are going to prepend
			# $CLIENT_BASEDIR. Absolute path is unchanged.
			echo "$path" | $NAWK -v Client_Basedir="$CLIENT_BASEDIR" '
					/^\// { print $0;
						next;
					      }
					      { conc = Client_Basedir "/" $0;
						gsub("//","/",conc);
						print conc;
					      }
					' >> $UNREGISTER_LIST
		done


		if [ -s "$UNREGISTER_LIST" ]; then
			if [ "$SAFEMODE_INSTALL" = "true" ]; then

				# We need to group the deletes entries for
				# performance reasons. Only 100 entries are
				# taken in a single batch, since we don't want
				# to exceed the number of arguments passed
				# during removef program invocation, and 100
				#  seems to a good tradeoff.

				batch_start_line=1
				batch_end_line=100
				while $TRUE ; do
					$SED -n "$batch_start_line,$batch_end_line p"\
					     $UNREGISTER_LIST > $UNREGISTER_BATCH
					[ -s $UNREGISTER_BATCH ] || break

					# Handle deletion of an object for
					# safemode patching
					# We do not use xargs here because xargs
					# can't handle shell function calls
 	
					HandleSafemodeDeleteObject $PKGINST "`/usr/bin/tr '\n' ' ' < $UNREGISTER_BATCH`" 

					batch_start_line=`$EXPR $batch_start_line + 100`
					batch_end_line=`$EXPR $batch_end_line + 100`
				done
			else

				# Remove the file only if it's OK'd by removef
				# We don't need to group deletes entries here
				# because xargs does it for us

				$XARGS $RMF $PKGINST < $UNREGISTER_LIST | \
				while read path ; do
					$RM "$path"
				done
			fi
			$RMF -f $PKGINST
		fi
		$RM $UNREGISTER_LIST $UNREGISTER_BATCH

		$RM $Our_Deletes
	fi

	#
	# Remove the deletes file, checkinstall and the postinstall
	#
	$RM -r $PKGSAV/$ACTIVE_PATCH
	$RM $THIS_DIR/checkinstall $THIS_DIR/postinstall $THIS_DIR/pkg_* $THIS_DIR/pkgrm_*
}

#
# The IB Unified Driver (UD) project changed the device tree underneath
# the IB HCA node.  As part of the ibud post upgrade script, we replaced
# obsolete lines in /etc/path_to_inst with their replacement lines (example
# shown below).  This script is has to revert those entries to the older hermon driver form, so that the downgrade of the driver, retained the infiniband cofiguration as is.
#
# Here is an example of the new paths
#
#	"/pci8086,3410@9/pci15b3,673c@0" 0 "mcxnex"
#	"/pci8086,3410@9/pci15b3,673c@0/hermon@0" 0 "hermon"
#	"/pci8086,3410@9/pci15b3,673c@0/hermon@0/ibport@1,ffff,ipib" 0 "ibd"
#	"/pci8086,3410@9/pci15b3,673c@0/hermon@0/ibport@2,ffff,ipib" 1 "ibd" 
#
# which is replaced by the old/legacy paths:
#
#	"/pci8086,3410@9/pci15b3,673c@0" 0 "hermon"
#	"/pci8086,3410@9/pci15b3,673c@0/ibport@1,ffff,ipib" 0 "ibd"
#	"/pci8086,3410@9/pci15b3,673c@0/ibport@2,ffff,ipib" 1 "ibd"
#
# Also, we want to retain the old mcxnex entry created for mcxe, that has
# vendorid,devid = pciex15b3,6750
# and pciex15b3,11 or...
#
# Additionally, this script also reverts the modifications done to the /etc/driver_aliases while adding new driver mcxnex
# With this change mcxnex driver is eliminated as nexus and hermon is updated as driver for all cards except for mcxe.
#
revert_ib_pathtoinst_driveraliases_entries()
{
	# Description:
	#       revert /etc/path_to_inst entries for older IB driver(see 16213784)
	#
	# Parameters:
	#       none
	#
	# Globals set:
	#	TYPE
	#

	PATHTOINST="${PKG_INSTALL_ROOT}/etc/path_to_inst"
	MV="/usr/bin/mv"
	EGREP="/usr/bin/egrep"
	NAWK="/usr/bin/nawk"

	HERMON_ALIAS="\
	\"pciex15b3,6340\" \
	\"pciex15b3,634a\" \
	\"pciex15b3,6732\" \
	\"pciex15b3,673c\" \
	\"pciex15b3,6746\" \
	"

	# revert the "mcxnex" entries in /etc/driver_aliases file
	$EGREP "^mcxnex " $BASEDIR/etc/name_to_major > /dev/null 2>&1
	if [ $? -eq 0 ] ; then
		rem_drv -b "${BASEDIR}" mcxnex > /dev/null 2>&1
		for i in ${HERMON_ALIAS}
		do
			update_drv -b "${BASEDIR}" -a -i "${i}" hermon > /dev/null 2>&1
		done
	fi

	#
	# Check to see if there is a need to downgrade from the new unified driver
	# (mcxnex/hermon) to legacy driver(hermon).  The condition is that
	# there exist paths for the hermon driver that have the
	# "hermon@" substring.
	#
	$EGREP 'hermon@' $PATHTOINST >/dev/null
	if [ $? -eq 1 ]; then
		# No new unified driver entries "hermon@", so no need to do anything.
		return
	fi
	# We're doing the "one time" device path conversion.

	#
	# Find all new ConnectX (mcxnex) entries, and destroy them.
	# Find all old/legacy ConnectX (hermon) entries, and convert them back.
	# Only reatain mcxnex entries that were found on earlier releases on i386 
	# for Mellanox ethernet cardsnd, with device id" of "pciex15b3,6750".
	#
	$NAWK -F' ' '
	$0 ~ /pciex15b3,6750@.+\"\ .+\ \"mcxnex\"/ ||
	$0 ~     /pci15b3,11@.+\"\ .+\ \"mcxnex\"/ ||
	$0 ~       /ethernet@.+\"\ .+\ \"mcxnex\"/ {
		#
		# Discard it unless it is pciex15b3,6750 (which was
		# previously supported by mcxnex ethernet on i386).
		#
		#print "[DEBUG] retain old mcxnex(mcxe) entries",$1;
		print $0;
		next;
	}
	/\"mcxnex\"/ {
		# skip other mcxnex entries
		next;
	}
	/\/hermon@./{
		#
		# remove the new hermon@ string in both hermon, ibport entries
		#print "[DEBUG] Old entry", $0;
		sub("\/hermon@[0-9]+","");
		print $0;
		next;
	}
	#
	# The path is something else, so just pass it
	# forward.  This includes all comment lines.
	#
	{ print $0 }' $PATHTOINST > $PATHTOINST.tmp

	# replace old p2i with updated IB entries   
	$MV $PATHTOINST.tmp $PATHTOINST
	chmod 444 $PATHTOINST
}

# load the override lib if it exists
if [ -f "${PATCH_OVERRIDE_LIB}" -a -r "${PATCH_OVERRIDE_LIB}" ] ; then
   . "${PATCH_OVERRIDE_LIB}"
fi

# execute the script function
patch_postinstall "$@"
revert_ib_pathtoinst_driveraliases_entries

exit 0
