#!/bin/bash
#
# Script to set up alternatives(8) for MPI files which clash between OpenMPI and LAM
#
# Usage:
#     mpi_alternatives < install | display | remove | set > [ lam | openmpi ]
#
# Based on openmpi.spec file that uses alternatives by 
# Orion Poplawski<orion@cora.nwra.com>
#
# Copyright(C) Jason Vas Dias <jvdias@redhat.com>, Red Hat, Inc. 2006 
# Freely distributable under the terms of the GNU Public License(GPL)
# as published at: http://www.gnu.org/licenses/gpl.html
#
bindir=/usr/bin;	# RPM _bindir macro during openmpi build
sysconfdir=/etc;        # RPM _sysconfdir macro during openmpi build
datadir=/usr/share;     # RPM _datadir macro during openmpi build
ompfx=om-;	        # RPM OpenMPI OMbinpfx macro during openmpi build
lampfx=lam-;	        # RPM lam LAMbinpfx macro during openmpi build
if [ `whoami` != 'root' ]; then
    echo "You must be root to set the MPI alternatives.";
    exit 1;
fi;
if [ ! -x /usr/sbin/alternatives ]; then
    echo "/usr/sbin/alternatives not installed. Install the chkconfig package.";
    exit 1;
fi;
case $1 in
    install)
	# Install alternative for MPI :

	/usr/sbin/alternatives --display mpi;
	if [ $? -eq 0 ]; then
	    echo "cannot install alternative for ${b##*/}: already exists.";
	    exit 0;
	fi;

	for b in mpirun mpiexec mpicc mpic++ mpif77; do
	    if [ ! -e ${bindir}/${lampfx}$b ]; then
		echo "Error: cannot install mpi alternatives: ${bindir}/${lampfx}$b does not exist.";
		echo "       check that the lam RPM is installed.";
		exit 1;
	    fi;	    
	    if [ ! -e ${bindir}/${ompfx}${b} ]; then
		echo "Error: cannot install mpi alternatives: ${bindir}/${ompfx}$b does not exist.";
		echo "       check that the openmpi RPM is installed.";
		exit 1;
	    fi;
	    if [ -e ${bindir}/$b ]; then
		if [ ! -L ${bindir}/$b ]; then
		    echo "Error: cannot install mpi alternatives: ${bindir}/$b exists and is not a link.";
		    echo "       check that the lam RPM version >= 7.1.1-11 is installed.";
		    exit 1;
		fi;
		rm -f ${bindir}/$b; # alternatives will create the link
	    fi;
	done;
	if [ ! -e ${datadir}/openmpi/ld.conf ]; then
	    echo "Error: cannot install mpi alternatives: ${datadir}/openmpi/ld.conf does not exist.";
	    echo "       check that the openmpi RPM is installed.";
	fi;
	if [ ! -e ${datadir}/lam/ld.conf ]; then
	    echo "Error: cannot install mpi alternatives: ${datadir}/lam/ld.conf does not exist.";
	    echo "       check that the lam RPM version >= 7.1.1-11 is installed.";
	fi;
	if [ -e ${sysconfdir}/ld.so.conf.d/mpi.conf ]; then
	    if [ ! -L ${sysconfdir}/ld.so.conf.d/mpi.conf ]; then
		echo "Error: cannot install mpi alternatives: ${sysconfdir}/ld.so.conf.d/mpi.conf exists and is not a link.";
		exit 1;
	    fi;
	    rm -f ${sysconfdir}/ld.so.conf.d/mpi.conf;
	fi;
	/usr/sbin/alternatives \
	    --install ${sysconfdir}/ld.so.conf.d/mpi.conf mpi ${datadir}/openmpi/ld.conf 50 \
	    --slave   ${bindir}/mpirun  mpirun  ${bindir}/${ompfx}mpirun \
	    --slave   ${bindir}/mpiexec mpiexec ${bindir}/${ompfx}mpiexec \
	    --slave   ${bindir}/mpicc   mpicc   ${bindir}/${ompfx}mpicc \
	    --slave   ${bindir}/mpic++  mpic++  ${bindir}/${ompfx}mpic++ \
	    --slave   ${bindir}/mpiCC   mpiCC   ${bindir}/${ompfx}mpic++ \
	    --slave   ${bindir}/mpif77  mpif77  ${bindir}/${ompfx}mpif77;

	retval=$?;
	if [ $retval -ne 0 ]; then
	    echo "Installation of OpenMPI MPI alternative failed.";
	    exit $retval;
	fi;

	/usr/sbin/alternatives \
	    --install ${sysconfdir}/ld.so.conf.d/mpi.conf mpi ${datadir}/lam/ld.conf 50 \
	    --slave   ${bindir}/mpirun  mpirun  ${bindir}/${lampfx}mpirun \
	    --slave   ${bindir}/mpiexec mpiexec ${bindir}/${lampfx}mpiexec \
	    --slave   ${bindir}/mpicc   mpicc   ${bindir}/${lampfx}mpicc \
	    --slave   ${bindir}/mpic++  mpic++  ${bindir}/${lampfx}mpic++ \
	    --slave   ${bindir}/mpiCC   mpiCC   ${bindir}/${lampfx}mpic++  \
	    --slave   ${bindir}/mpif77  mpif77  ${bindir}/${lampfx}mpif77;

	retval=$?;
	if [ $retval -ne 0 ]; then
	    echo "Installation of LAM MPI alternative failed.";
	    exit $retval;
	fi;

	prefMPI=lam
	if [ -n "$2" ] ; then
	    if [ $2 =~ '[Oo].*[Mm]' ]; then
		prefMPI=openmpi;
	    fi;
	fi;

	/usr/sbin/alternatives --set mpi ${datadir}/$prefMPI/ld.conf;

	retval=$?;
	if [ $retval -ne 0 ]; then
	    echo "Selection of default LAM alternative failed.";
	    exit $retval;
	fi;
	ldconfig;
	exit $retval;
	;;
   display)

	/usr/sbin/alternatives --display mpi;

	if [ $? -ne 0 ]; then
	    echo 'No alternatives set up for mpi - run "mpi_alternatives install".';
	    exit 1;
	fi;
	exit 0;
	;;
   remove)

	/usr/sbin/alternatives --remove mpi ${datadir}/lam/ld.conf

	retval=$?;
	if [ $retval -ne 0 ]; then 
	    echo "Removal of mpi alternative ${datadir}/lam/ld.conf failed.";
	    exit $retval;
	fi;	

	/usr/sbin/alternatives --remove mpi ${datadir}/openmpi/ld.conf

	retval=$?;
	if [ $retval -ne 0 ]; then 
	    echo "Removal of mpi alternative ${datadir}/openmpi/ld.conf failed.";
	    exit $retval;
	fi;	
	
	# set mpi.conf back to default (LAM):
	
	if [ ! -e ${sysconfdir}/ld.so.conf.d/mpi.conf ]; then
	    if [ -e ${datadir}/lam/ld.conf ]; then
		ln -s ${datadir}/lam/ld.conf ${sysconfdir}/ld.so.conf.d/mpi.conf;
	    elif [ -e ${datadir}/openmpi/ld.conf ]; then
		ln -s ${datadir}/openmpi/ld.conf ${sysconfdir}/ld.so.conf.d/mpi.conf;
	    else
		echo "Warning: no ${sysconfdir}/ld.so.conf.d/mpi.conf exists!";	       
            fi;
	fi;
	ldconfig;
	exit $?;
	;;
    set)	
	prefMPI=''
	case "$2" in
	    *[Ll][aA][mM]*)
	        prefMPI=lam
		;;
	    *[Oo]*[Mm]*)
	        prefMPI=openmpi
		;;
	    *)
		echo 'Usage: mpi_alternatives set < lam | openmpi >';
		;;
	esac;

	/usr/sbin/alternatives --set mpi ${datadir}/$prefMPI/ld.conf

	retval=$?;
	if [ $retval -ne 0 ]; then 
	    echo "Setting MPI alternative to ${datadir}/$prefMPI/ld.conf failed.";
	    exit $retval;
	fi;	
	ldconfig;
	exit $?;
	;;
   *)
	echo 'Usage: mpi_alternatives < install | display | remove | set>';
	echo '    Sets up alternatives for MPI (Message Passing Interface) between LAM and OpenMPI implementations.'
	exit 1;
	;;
esac;
