#!/bin/sh 



script_dir=$(dirname $0)
script_dir=$(cd $script_dir;pwd)
script_name=$(basename $0)
. $script_dir/vars $script_dir

rpm_target_cpu=$(rpm --eval '%{_target_cpu}')

check_ipoib_conf(){
        n_total_lines=$(cat $ipoib_conf |grep -v "^$"|grep -v "^#"|wc -l)
        n_ib_lines=$(cat $ipoib_conf |grep -v "^$"|grep -v "^#"|cut -f1 -d:|grep  ib|wc -l)
        if [ $n_ib_lines -lt $n_total_lines ] ; then
                echo error: $ipoib_conf has wrong syntax. not all lines start with ib.
                exit 1
        fi
        n_ib_lines_uniq=$(cat $ipoib_conf |grep -v "^$"|grep -v "^#"|cut -f1 -d:|grep  ib|sort -u |wc -l)
        if [ $n_ib_lines_uniq -ne $n_ib_lines ] ; then
                echo error: $ipoib_conf has wrong syntax. not all lines are unique.
                exit 1
        fi
#still need to check if each line is valid
}


parse_ipoib_conf(){
        for line in `cat $ipoib_conf |grep -v "^$"|grep -v "^#"` ; do
                ib_if=$(echo $line|cut -f1 -d:)
                network=$(echo $line|cut -f2 -d:)
                if [ $network != "dhcp" ] ; then
                        eth_if=$(echo $line|cut -f3 -d:)
                        ib-config-as-eth -ib $ib_if -eth $eth_if -network $network -nocolor
                else
                        ib-config-as-eth -ib $ib_if -dhcp -nocolor
                fi
        done
}

check_lock(){
	if [ -f $lock_file ] ; then
		if [ $uninstall -eq 1 ] ; then
			if [ -x /usr/voltaire/uninstall.sh ] ; then
				/usr/voltaire/uninstall.sh
			else
				echo missing or non-executable /usr/voltaire/uninstall.sh
				exit 1
			fi
		else
			echo "Previous installation of GridStack was not completely removed. Please run /usr/voltaire/uninstall.sh"
			exit 1
		fi
	fi
}

validate_time_of_day(){
	machine_date=$(date +%s)
	package_date=$(date +%s -r $script_dir/$script_name)
	if [ $package_date -gt $machine_date ] ; then
		echo "Package date is in the future. It should be at least $(date -r $script_dir/$script_name)"
		echo Until you set the correct date, you can fix this temporarily by
		echo date -s \"$(date -r install/install.sh)\"
		exit 1
	fi
}
	
get_os_vars(){
		
	
	K_VER=$(uname -r)
	ARCH=$(uname -m)

	if [ -f /etc/redhat-release -o -f /etc/chaos-release -o -f /etc/rocks-release ] ; then
		OS=rhas
	elif [ -f /etc/SuSE-release -o -f /etc/UnitedLinux-release ] ; then
		OS=sles
	else
		echo unknownm OS 
		OS="unknown"
	fi

}

fix_ib_symvers(){

	if [ ! -f $script_dir/$IBED_DIR/RPMS/*/kernel-ib-[0-9]* ] ; then
		echo no need to update file Module.symvers
		return 0
	fi
	rm -rf /tmp/gs-syms.$$
	mkdir /tmp/gs-syms.$$
	pushd /tmp/gs-syms.$$
	for f in `rpm -qlp $script_dir/$IBED_DIR/RPMS/*/kernel-ib-[0-9]*` ; do 
		mkdir -p ./$(dirname $f); 
	done
	rpm2cpio $script_dir/$IBED_DIR/RPMS/*/kernel-ib-[0-9]* |cpio -i
	rm -f /tmp/syms
	n_mods=0
	for mod in $(find -name *.ko) ; do
		nm -o $mod |grep __crc >> /tmp/syms
		n_mods=$((n_mods+1))
	done

	n_syms=$(wc -l /tmp/syms |cut -f1 -d" ")
	echo found $n_syms InfiniBand symbols in $n_mods InfiniBand modules
	n=1

	MOD_SYMVERS_IB=./Module.symvers.ib
	MOD_SYMVERS_PATCH=./Module.symvers.patch
	if [ -f /lib/modules/$K_VER/source/Module.symvers ] ; then
		MOD_SYMVERS_KERNEL=/lib/modules/$K_VER/source/Module.symvers
	elif [ -f /lib/modules/$K_VER/build/Module.symvers ] ; then
		MOD_SYMVERS_KERNEL=/lib/modules/$K_VER/build/Module.symvers
	else
		echo file Module.symvers not found
	fi
	if [ ! -z $MOD_SYMVERS_KERNEL ] ; then 
		
		rm -f $MOD_SYMVERS_IB

		while [ $n -le $n_syms ] ; do
			line=$(head -$n /tmp/syms|tail -1)
                        line1=$(echo $line|cut -f1 -d:)
                        line2=$(echo $line|cut -f2 -d:)
                        file=$(echo $line1|cut -f6- -d/)
                        file=$(echo $file|cut -f1 -d.)

			crc=$(echo $line2|cut -f1 -d" ")
			crc=${crc:8}
			sym=$(echo $line2|cut -f3 -d" ")
			sym=${sym:6}
			echo -e  "0x$crc\t$sym\t$file" >> $MOD_SYMVERS_IB
			if [ -z $allsyms ] ; then
				allsyms=$sym
			else
				allsyms="$allsyms|$sym"
			fi
			n=$((n+1))
		done
		egrep -v "$allsyms" $MOD_SYMVERS_KERNEL >> $MOD_SYMVERS_IB
		diff -u $MOD_SYMVERS_KERNEL $MOD_SYMVERS_IB > $MOD_SYMVERS_PATCH
		patch -d $(dirname $MOD_SYMVERS_KERNEL)  < $MOD_SYMVERS_PATCH
		mkdir -p /usr/voltaire/backup
		cp $MOD_SYMVERS_PATCH /usr/voltaire/backup
	fi

}	

fix_ofed_conf(){

	case $OS in 
		sles)
			rpm -q kernel-source > /dev/null
			if [ $? -eq  0 ] ; then
				echo rpm kernel-source is installed. Leaving OFED configuration as is.
				fix_for_ib_devel=0
			else
				fix_for_ib_devel=1
			fi
		;;
		rhas)
			rpm -q kernel-devel > /dev/null
			if [ $? -eq 0 ] ; then
				echo rpm kernel-devel is installed. Leaving OFED configuration as is.
				fix_for_ib_devel=0
			else
				fix_for_ib_devel=1
			fi
		;;
		*)
			echo Unknown Linux distribution. Leaving OFED configuration as is.
			fix_for_ib_devel=0
		;;
	esac
	if [ $fix_for_ib_devel -ne 0 ] ; then
		sed -e {s/kernel_ib_devel=y/kernel_ib_devel=n/g} $ofed_conf > $ofed_conf.tmp
		mv $ofed_conf.tmp $ofed_conf
		echo kernel_ib_devel was droped from OFED configuraion
	fi

	rpm -q tcl-devel > /dev/null
	if [ $? -eq 0 ] ; then
		echo tcl-devel is installed. Leaving OFED configuration as is.
	else
		sed -e {s/ibutils=y/ibutils=n/g} $ofed_conf > $ofed_conf.tmp
		mv $ofed_conf.tmp $ofed_conf

		echo ibutils was droped from OFED configuraion
		
	fi

}
save_os_vars(){
	OS_VAR_FILE=$1
	rm -f  $OS_VAR_FILE
	echo OS=$OS		>> $OS_VAR_FILE
	echo K_VER=$K_VER	>> $OS_VAR_FILE
	echo ARCH=$ARCH		>> $OS_VAR_FILE
}
make_bin_package(){
	echo making binary package
	if [ ! -f $lock_file ] ; then
		echo Installation does not seem to be complete. full installation is required before packing binary files.
		exit 1
	fi
	cd $script_dir/..

	GS_VER=$(cat /usr/voltaire/version)

	n_dirs_in_path=$(echo $script_dir|tr "/" " "|wc -w)
	n_dirs_in_path=$((n_dirs_in_path+1))
	GS_DIR=$(echo $script_dir|cut -f$n_dirs_in_path -d/)
	BIN_NAME=$GS_VER-$OS-k$K_VER-$ARCH
	
	rm -rf $BIN_NAME $BIN_NAME.tar.bz2 $BIN_NAME.md5sum
	
	cp -a $GS_DIR $BIN_NAME
	OFED_DIR=$(basename $(ls -d $BIN_NAME/$IBED_DIR ))
	save_os_vars $BIN_NAME/bin-info
	
	GS_SRC_RPMS=$(ls $BIN_NAME/SRPMS/*)
	echo GS_SRC_RPMS=$GS_SRC_RPMS
	OFED_SRC_RPMS=$(ls $BIN_NAME/$OFED_DIR/SRPMS/* |egrep -v "ofed-docs|ofed-scripts|openmpi|ibutils")
	echo OFED_SRC_RPMS=$OFED_SRC_RPMS
	mv $BIN_NAME/$OFED_DIR/SOURCES $BIN_NAME/$OFED_DIR/SOURCES.0
	mkdir $BIN_NAME/$OFED_DIR/SOURCES
	cp  $BIN_NAME/$OFED_DIR/SOURCES.0/propel.sh $BIN_NAME/$OFED_DIR/SOURCES
	rm -rf $GS_SRC_RPMS $OFED_SRC_RPMS $BIN_NAME/$OFED_DIR/SOURCES.0
	patch -p1 -d $BIN_NAME/$OFED_DIR/ < $BIN_NAME/install/ofed_install_bin.patch
	
	# remove all the *src.rpm's and .svn from the binary directory	
	#rm -rf `find $BIN_NAME -name \*src.rpm `
	rm -rf `find $BIN_NAME -name \.svn`

	tar jcvf $BIN_NAME.tar.bz2 $BIN_NAME

	md5sum $BIN_NAME.tar.bz2 > $BIN_NAME.md5sum
	echo Binary package: $(pwd)/$BIN_NAME.tar.bz2
	echo Binary package checksum: $(pwd)/$BIN_NAME.md5sum
	cd - > /dev/null
}

copy_voltaire_patches(){
        cd $script_dir/$IBED_DIR/SOURCES
	openib_tar=$(ls openib*.tgz)
        openib_dir=$(tar ztf $openib_tar|head -1)
        echo openib_tar=$openib_tar
        echo openib_dir=$openib_dir
        if [ ! -f $openib_tar ] ; then
                echo "error: file $openib_tar not found"
                exit 1
        fi
        if [ -f $openib_tar.orig ] ; then
                cp $openib_tar.orig     $openib_tar
        else
                cp $openib_tar $openib_tar.orig
        fi
        echo unpacking $openib_tar
        tar zxvf $openib_tar > /dev/null  2>&1
        echo copying kernel patches
        num_patches=$(ls $script_dir/patches/fixes/kernel/|wc -w)
        if [ $num_patches -ne 0 ] ; then
                echo $num_patches patches found under $script_dir/patches/fixes/kernel
                cp $script_dir/patches/fixes/kernel/* $openib_dir/kernel_patches/fixes/
        else
                echo no patches under $script_dir/patches/fixes/kernel
        fi
	
        if [ -d $script_dir/patches/$(uname -r) ] ; then
                num_patches=$(ls $script_dir/patches/$(uname -r)/|wc -w)
                if [ $num_patches -ne 0 ] ; then
                        echo $num_patches patches found under $script_dir/patches/$(uname -r)/
                        cp $script_dir/patches/$(uname -r)/* $openib_dir/kernel_patches/fixes/
                else
                        echo no patches under $script_dir/patches/$(uname -r)/
                fi
        else
                echo no patch directory for kernel $(uname -r)
        fi

        echo copying user patches
        num_patches=$(ls $script_dir/patches/fixes/user/|wc -w)
        if [ $num_patches -ne 0 ] ; then
                echo $num_patches patches found under $script_dir/patches/fixes/user
                cp $script_dir/patches/fixes/user/* $openib_dir/user_patches/fixes/
        else
                echo no patches under $script_dir/patches/fixes/user
        fi

	if [ $Altix_patches == 1 ] ; then
	    	echo copying Altix patches
		num_patches=$(find $script_dir/patches/Altix/ -name \*.diff |wc -w)
		if [ $num_patches -ne 0 ] ; then
		    echo $num_patches patches found under $script_dir/patches/Altix
		    if [ $(find $script_dir/patches/Altix/user/ -name \*.diff |wc -w) != 0 ] ; then
		    	cp $script_dir/patches/Altix/user/* $openib_dir/user_patches/fixes/
		    fi
		    uname -r | grep '2.6.5-7'
		    if [ $? == 1 ] ; then 
                        #not sles9 sp3 
			if [ $(find $script_dir/patches/Altix/kernel/ -name \*.diff |wc -w) != 0 ] ; then
			    cp $script_dir/patches/Altix/kernel/* $openib_dir/kernel_patches/fixes/
			fi
		    else
		 	if [ $(find $script_dir/patches/Altix/Backport/2_6_5-7_244 -name \*.diff |wc -w) != 0 ] ; then
			    cp $script_dir/patches/Altix/Backport/2_6_5-7_244/* $openib_dir/kernel_patches/backport/2.6.5-7.244/
			fi
		    fi
		else
			echo no patches under $script_dir/patches/Altix
		fi
	fi

        echo re-packing $openib_tar
        tar zcvf $openib_tar $openib_dir > /dev/null  2>&1
	rm -rf $openib_dir

}


build_enhanced_services(){
	if [ ! -f $script_dir/RPMS/$rpm_target_cpu/ib-enhanced-services-[0-9]*.rpm ] ; then
		echo Building ib-enhanced-services
		rpmbuild --define "_topdir $script_dir" --rebuild $script_dir/$IB_ENHANCED_SERVICES_FILE_NAME
		if [ $? -ne 0 ] ; then
			echo "Building of $IB_ENHANCED_SERVICES_RPM_NAME failed"
			exit 1
		fi
	fi
	rpm -q $IB_ENHANCED_SERVICES_RPM_NAME
	if [ $? -eq 0 ] ; then
		rpm -e $IB_ENHANCED_SERVICES_RPM_NAME
	fi

	rpm -ivh $script_dir/RPMS/$rpm_target_cpu/ib-enhanced-services-[0-9]*.rpm
	if [ $? -ne 0 ] ; then
		echo "Installation of $script_dir/RPMS/$rpm_target_cpu/ib-enhanced-services-[0-9]*.rpm failed"
		exit 1
	fi
}

build_v_mpi() {
	if [ -z $STACK_PREFIX ] ; then
		echo "ERROR: cant find OFED installation"
		exit 1
	fi
	export IBHOME=$STACK_PREFIX
	if [ ! -f $script_dir/RPMS/$rpm_target_cpu/vltmpi-OPENIB-[0-9]*.rpm ] ; then
		echo Building Voltaire MPI
		rpmbuild --define "_topdir $script_dir" --rebuild $script_dir/$VLT_MPI_FILE_NAME
		if [ $? -ne 0 ] ; then
			echo "Building of $VLT_MPI_FILE_NAME failed"
			exit 1
		fi
	fi
	rpm -q $VLT_MPI_RPM_NAME
	if [ $? -eq 0 ] ; then
		rpm -e $VLT_MPI_RPM_NAME
	fi

	rpm -ivh $script_dir/RPMS/$rpm_target_cpu/vltmpi-OPENIB-[0-9]*.rpm
	if [ $? -ne 0 ] ; then
		echo "Installation of $script_dir/RPMS/$rpm_target_cpu/vltmpi-OPENIB-[0-9]*.rpm failed"
		exit 1
	fi
	
}
	
usage(){
       echo Usage: $(basename $0) [--no-v-mpi] [--with-v-iser] [--v-mpi-compiler-ifc path-to-ifc] \
                               [--v-mpi-compiler-icc path-to-icc] [--v-mpi-compiler-path path-to-pathscale] \
                               [--v-mpi-compiler-pgi path-to-pgi] [--make-bin-package] [--config config-name] \
                               [--ipoib-conf ipoib-conf-file] [--dont-patch] [--Altix] [--uninstall]
}

v_mpi=1
v_iser=0
dont_patch=0
uninstall=0
make_bin=0
Altix_patches=0

while [[ ! -z "$1" ]] ; do
        case $1 in
                --no-v-mpi)
			v_mpi=0;
                        shift
                ;;
                --with-v-iser)
                        v_iser=1;
                        shift
                ;;
                --v-mpi-compiler-ifc)
			export IFC=$2
			export PATH=$IFC/bin:$PATH
                        shift
                        shift
                ;;
                --v-mpi-compiler-icc)
			export ICC=$2
			export PATH=$ICC/bin:$PATH
                        shift
                        shift
                ;;
                --v-mpi-compiler-path)
			export PATHSCALE=$2
			export PATH=$PATHSCALE/bin:$PATH
                        shift
                        shift
                ;;
                --v-mpi-compiler-pgi)
			export PGI=$2
			export PATH=$PGI/linux86-64/6.1/bin:$PATH
                        shift
                        shift
                ;;
                --dont-patch)
			dont_patch=1
                        shift
                ;;
                --make-bin-package)
			make_bin=1
			shift
                ;;
                --config)
			conf=$2
			shift
			shift
                ;;
                --ipoib-conf)
			ipoib_conf=$2
			if [ ! -f $ipoib_conf ] ; then
				echo no such file $ipoib_conf
			fi
			check_ipoib_conf
			shift
			shift
                ;;
		--Altix)
                        Altix_patches=1
                        shift
                ;;

                --uninstall)
			uninstall=1
			shift
                ;;
                -h|--help|*)
			usage
                        exit
                ;;
        esac
done




ibhost_name=$(rpm -q ibhost-hpc)
if [ $? -eq 0 ] ; then
	echo Please remove first old InfiniBand stack $ibhost_name
	exit 1
fi
ibhost_name=$(rpm -q ibhost-biz)
if [ $? -eq 0 ] ; then
	echo Please remove first old InfiniBand stack $ibhost_name
	exit 1
fi

validate_time_of_day
get_os_vars
check_lock


if [ -f /usr/voltaire/version ] ; then
	if [ $uninstall -eq 1 ] ; then
		if [ -x /usr/voltaire/uninstall.sh ] ; then
			/usr/voltaire/uninstall.sh

		else
			echo /usr/voltaire/uninstall.sh is missing
			exit 1
		fi
	else
		version=$(cat /usr/voltaire/version)
		echo Please remove previous installation: $version
		exit 1
	fi
fi

mkdir -p /usr/voltaire/
rm -rf /usr/voltaire/workarounds/
cp -a workarounds /usr/voltaire/
for wa in /usr/voltaire/workarounds/*.wa  ; do 
		echo running workaround $wa
		$wa install
done

if [ -z $conf ] ; then
	if [ -e /etc/redhat-release ] ; then
		conf=rh4
	elif [ -e /etc/SuSE-release ] ; then
		conf=suse`cat /etc/SuSE-release |grep VERSION |cut -f3 -d" "`
	else
		conf=default
	fi
	arch=$(uname -m)
	case $arch in
		ia64)
			conf=$conf-ia64
		;;
		x86_64)
			conf=$conf-x86_64
		;;
                ppc64)
                        conf=$conf-ppc64
                ;;
		i*86)
			conf=$conf-x86
		;;
		*)
			conf=$conf-noarch
		;;
	esac
fi

if [ -f $script_dir/bin-info ] ; then
	dont_patch=1
	if [ $make_bin -ne 0 ] ; then
		echo ERROR: cant make binnary package from binary package
		exit 1
	fi

	save_os_vars	/tmp/bin-info
	diff $script_dir/bin-info /tmp/bin-info > /dev/null
	if [ $? -ne 0 ] ; then
		echo "Binary package doesn't seem to match this system."
		echo "Please look at $script_dir/bin-info for system requirements."
		exit 1
	fi
fi
	
if [ ! -f $script_dir/install/ofed.conf.$conf ] ; then
	echo $script_dir/install/ofed.conf.$conf does not exist. using $script_dir/install/ofed.conf.default-noarch
	conf=default-noarch
fi

echo using configuration: $conf

ofed_conf=/tmp/ofed.conf.$conf
cp $script_dir/install/ofed.conf.$conf $ofed_conf
fix_ofed_conf 
echo using ofed configuration $ofed_conf


mkdir -p $script_dir/BUILD
mkdir -p $script_dir/RPMS/$rpm_target_cpu


# Open and install OFED
if [ $dont_patch -eq 1 ] ; then
	echo installation will continue without applying patches
else
	copy_voltaire_patches
fi

cd $script_dir/$IBED_DIR


OPENIB_PARAMS="--without-modprobe --without-ipoibconf" ./install.sh -c $ofed_conf
if [ $? -ne 0 ] ; then
	echo "Installaion of IBED failed"
	exit 1
fi

fix_ib_symvers

if [ -f /etc/infiniband/openib.conf ] ; then
	sed -e {s/IPATH_LOAD=yes/IPATH_LOAD=no/g} /etc/infiniband/openib.conf > /tmp/openib.conf
	cp /tmp/openib.conf /etc/infiniband/openib.conf
	sed -e {s/DMA_UCM_LOAD=no/DMA_UCM_LOAD=yes/g} /etc/infiniband/openib.conf > /tmp/openib.conf
	cp /tmp/openib.conf /etc/infiniband/openib.conf
else
	echo /etc/infiniband/openib.conf is missing after OFED installation
fi

grep "alias net-pf-27           ib_sdp" /etc/modprobe.conf > /dev/null
if [ $? -ne 0 ] ; then
	echo "alias net-pf-27           ib_sdp" >> /etc/modprobe.conf
fi

rpm -q opensm > /dev/null
if [ $? -eq 0 ] ; then
	rpm -e --nodeps opensm opensm-devel
fi

depmod -a
cd ..
STACK_PREFIX=$(test -x /etc/infiniband/info && /etc/infiniband/info |grep prefix|cut -f2 -d=)

# Install Enhanced Services
build_enhanced_services

#Install Voltaire MPI
if [ $v_mpi -ne 0 ] ; then
	build_v_mpi
fi

#Install Voltaire Iser
if [ $v_iser -ne 0 ] ; then
        cd $script_dir/vlt-iser
	./open-iscsi-iser.sh -i
	if [ $? != 0 ] ; then
		echo "error: VLT Iser install Failed"
                exit 1
        fi
	mkdir -p /usr/voltaire/vlt-iser
	cp $script_dir/vlt-iser/open-iscsi-iser.sh /usr/voltaire/vlt-iser/
else
	rm -rf /usr/voltaire/vlt-iser
fi

cp $script_dir/vars /usr/voltaire/
cp $script_dir/uninstall.sh /usr/voltaire/

if [ -f /etc/SuSE-release ] ; then
	patch  -p1 -d /etc/sysconfig/network/scripts/ < /usr/voltaire/functions-ib.diff
fi
if [ -f /etc/redhat-release ] ; then
	if [ ! -f /sbin/ifup-pre-local ] ; then
		echo "#!/bin/bash" > /sbin/ifup-pre-local
	fi
	echo "/etc/sysconfig/network-scripts/ifup-pre-ib \$1" >> /sbin/ifup-pre-local
	chmod +x /sbin/ifup-pre-local
	if [ ! -f /sbin/ifdown-pre-local ] ; then
		echo "#!/bin/bash" > /sbin/ifdown-pre-local
	fi
	echo "/etc/sysconfig/network-scripts/ifdown-post-ib \$1" >> /sbin/ifdown-pre-local
	chmod +x /sbin/ifdown-pre-local
fi



if [ ! -z $ipoib_conf ] ; then
	parse_ipoib_conf
fi


chkconfig openibd off
chkconfig gridstack on

if [ ! -f /etc/dhclient.conf ] ; then 
	cp /usr/voltaire/dhclient.conf /etc/dhclient.conf
fi
mkdir -p $(dirname $lock_file)

touch $lock_file



if [ $make_bin -ne 0 ] ; then
	make_bin_package
fi	


echo "Installation finished"
echo "Please logout from the shell and login again in order to update your PATH environment variable"
