#!/usr/bin/perl
## BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]

#

#============================================================================
# initialization
use strict;
use Term::ANSIColor;
use Term::ANSIColor qw(:constants);
use File::Basename;
use Math::BigInt;
use Cwd;

#Setup some defaults
my $exit_code=0;

my $Force_Install = 0;# force option used to force install on unsupported distro
my $GPU_Install = 0;

# some options specific to OFED builds
my $OFED_force_rebuild=0;
my $OFED_user_configure_options="";
my $OFED_kernel_configure_options="";
my $OFED_prefix="/usr";
my $OFED_debug = 0;	# if 1 build a debug version of modules

my $CUR_OS_VER = `uname -r`;
chomp $CUR_OS_VER;
# firmware and data files
my $OLD_BASE_DIR = "/etc/opa";
my $BASE_DIR = "/etc/opa";
# iba editable config scripts
my $OPA_CONFIG_DIR = "/etc/opa";

my $UVP_CONF_FILE = "$BASE_DIR/uvp.conf";
my $UVP_CONF_FILE_SOURCE = "uvp.conf";
my $DAT_CONF_FILE_SOURCE = "dat.conf";
my $NETWORK_CONF_DIR = "/etc/sysconfig/network-scripts";
my $ROOT = "/";	# TBD prepared to make this "" removes some // prompts and logs

my $BIN_DIR = "/usr/sbin";

#This string is compared in verify_os_rev for correct revision of
#kernel release.
my $CUR_DISTRO_VENDOR = "";
my $CUR_VENDOR_VER = "";	# full version (such as ES5.1)
my $CUR_VENDOR_MAJOR_VER = "";    # just major number part (such as ES5)
my $ARCH = `uname -m | sed -e s/ppc/PPC/ -e s/powerpc/PPC/ -e s/i.86/IA32/ -e s/ia64/IA64/ -e s/x86_64/X86_64/`;
chomp $ARCH;
my $ARCH_VENDOR=`grep vendor_id /proc/cpuinfo | tail -1`;
chomp $ARCH_VENDOR;
if ($ARCH eq "X86_64")
{
	if ((-f "$ROOT/etc/redhat-release" || -f "$ROOT/etc/rocks-release") && $ARCH_VENDOR =~ /.*GenuineIntel.*/ && substr($CUR_OS_VER,0,3) eq "2.4")
	{
		$ARCH = "EM64T";
	}
}
my $DRIVER_SUFFIX=".o";
if (substr($CUR_OS_VER,0,3) eq "2.6" || substr($CUR_OS_VER,0,2) eq "3.")
{
	$DRIVER_SUFFIX=".ko";
}
my $DBG_FREE="release";


# Command paths
my $LSPCI = "/sbin/lspci";
my $RPM="/bin/rpm";

# a few key commands to verify exist
my @verify_cmds = ( "uname", "mv", "cp", "rm", "ln", "cmp", "yes", "echo", "sed", "chmod", "chown", "chgrp", "mkdir", "rmdir", "grep", "diff", "awk", "find", "xargs", "sort", $RPM, "chroot", $LSPCI );

sub Abort(@);
sub NormalPrint(@);
sub LogPrint(@);
sub HitKeyCont();
# ============================================================================
# General utility functions

# verify the given command can be found in the PATH
sub check_cmd_exists($)
{
	my $cmd=shift();
	return (0 == system("which $cmd >/dev/null 2>/dev/null"));
}

sub check_root_user()
{
	my $user;
	$user=`/usr/bin/id -u`;
	if ($user != 0)
	{
		die "\n\nYou must be \"root\" to run this install program\n\n";
	}

	# verify basic commands are in path
	foreach my $cmd ( @verify_cmds ) {
		if (! check_cmd_exists($cmd)) {
			die "\n\n$cmd not found in PATH.\nIt is required to login as root or su - root.\nMake sure the path includes /sbin and /usr/sbin\n\n";
		}
	}
}

sub my_tolower($)
{
	my($str) = shift();

	$str =~ tr/[A-Z]/[a-z]/;
	return "$str";
}

sub ROOT_is_set()
{
	return ("$ROOT" ne "/" && "$ROOT" ne "");
}

# ============================================================================
# Version and branding

# version string is filled in by prep, special marker format for it to use
my $VERSION = "THIS_IS_THE_ICS_VERSION_NUMBER:@(#)10.5.1.0.2% 000B000";
$VERSION =~ s/THIS_IS_THE_ICS_VERSION_NUMBER:@\(#\)//;
$VERSION =~ s/%.*//;
my $INT_VERSION = "THIS_IS_THE_ICS_INTERNAL_VERSION_NUMBER:@(#)10_5_1_0_2% 000B000";
$INT_VERSION =~ s/THIS_IS_THE_ICS_INTERNAL_VERSION_NUMBER:@\(#\)//;
$INT_VERSION =~ s/%.*//;
my $BRAND = "THIS_IS_THE_ICS_BRAND:Intel%                    ";
# backslash before : is so patch_brand doesn't replace string
$BRAND =~ s/THIS_IS_THE_ICS_BRAND\://;
$BRAND =~ s/%.*//;

# convert _ and - in version to dots
sub dot_version($)
{
	my $version = shift();

	$version =~ tr/_-/./;
	return $version;
}

# ============================================================================
# installation paths

# where to install libraries
my $LIB_DIR = "/lib";
my $UVP_LIB_DIR = "/lib";
my $USRLOCALLIB_DIR = "/usr/local/lib";
my $OPTIBALIB_DIR = "/usr/lib/opa/lib";
my $USRLIB_DIR = "/usr/lib";
# if different from $LIB_DIR, where to remove libraries from past release
my $OLD_LIB_DIR = "/lib";
my $OLD_USRLOCALLIB_DIR = "/usr/local/lib";
my $OLD_UVP_LIB_DIR = "/lib";

sub set_libdir()
{
	if ( -d "$ROOT/lib64" )
	{
		$LIB_DIR = "/lib64";
		$UVP_LIB_DIR = "/lib64";
		$UVP_CONF_FILE_SOURCE = "uvp.conf.64";
		$DAT_CONF_FILE_SOURCE = "dat.conf.64";
		$USRLOCALLIB_DIR = "/usr/local/lib64";
		$OPTIBALIB_DIR = "/usr/lib/opa/lib64";
		$USRLIB_DIR = "/usr/lib64";
	}
}

# determine the os vendor release level based on build system
# this script is stolen from funcs-ext.sh and should
# be maintained in parallel
sub os_vendor_version($)
{
	my $vendor = shift();

	my $rval = "";
	my $mn = "";
	if ( -e "/etc/os-release" ) {
		$rval=`cat /etc/os-release | grep VERSION_ID | cut -d'=' -f2 | tr -d [\\"\\.0]`;
		chop($rval);
		$rval="ES".$rval;
		if ( -e "/etc/redhat-release" ) {
			if (!system("grep -qi centos /etc/redhat-release")) {
				$rval = `cat /etc/redhat-release | cut -d' ' -f4`;
				$rval =~ m/(\d+).(\d+)/;
				$rval="ES".$1.$2;
			}	
		}
	} elsif ($vendor eq "apple") {
		$rval=`sw_vers -productVersion|cut -f1-2 -d.`;
		chop($rval);
	} elsif ($vendor eq "rocks") {
		$rval=`cat /etc/rocks-release | cut -d' ' -f3`;
		chop($rval);
	} elsif ($vendor eq "scyld") {
		$rval=`cat /etc/scyld-release | cut -d' ' -f4`;
		chop($rval);
	} elsif ($vendor eq "mandrake") {
		$rval=`cat /etc/mandrake-release | cut -d' ' -f4`;
		chop($rval);
	} elsif ($vendor eq "fedora") {
		$rval=`cat /etc/fedora-release | cut -d' ' -f4`;
		chop($rval);
	} elsif ($vendor eq "redhat") {
		if (!system("grep -qi advanced /etc/redhat-release")) {
			$rval=`cat /etc/redhat-release | cut -d' ' -f7`;
			chop($rval);
		} elsif (!system("grep -qi centos /etc/redhat-release")) {
			# Find a number of the form "#.#" and output the portion
			# to the left of the decimal point.
			$rval = `cat /etc/redhat-release`;
			$rval =~ m/(\d+).(\d+)/;
			$rval="ES".$1.$2;
		} elsif (!system("grep -qi Scientific /etc/redhat-release")) {
			# Find a number of the form "#.#" and output the portion
			# to the left of the decimal point.
			$rval = `cat /etc/redhat-release`;
			$rval =~ m/(\d+).(\d+)/;
			$rval="ES".$1;
		} elsif (!system("grep -qi enterprise /etc/redhat-release")) {
			# Red Hat Enterprise Linux Server release $a.$b (name)
			#PR 110926
			$rval=`cat /etc/redhat-release | cut -d' ' -f7 | cut -d'.' -f1`;
			$mn=`cat /etc/redhat-release | cut -d' ' -f7 | cut -d'.' -f2`;
			chop($rval);
			if ( (($rval >= 7) && ($mn > 0)) ||
				(($rval == 6) && ($mn >= 7)) ) {
				chomp($mn);
				$rval=join "","ES","$rval","$mn";
			} else {
				$rval="ES".$rval;
			}
		} else {
			$rval=`cat /etc/redhat-release | cut -d' ' -f5`;
			chop($rval);
		}
	} elsif ($vendor eq "UnitedLinux") {
		$rval=`grep United /etc/UnitedLinux-release | cut -d' ' -f2`;
		chop($rval);
	} elsif ($vendor eq "SuSE") {
		if (!system("grep -qi enterprise /etc/SuSE-release")) {
			$rval=`grep -i enterprise /etc/SuSE-release | cut -d' ' -f5`;
			chop($rval);
			$rval="ES".$rval;
		} else {
			$rval=`grep SuSE /etc/SuSE-release | cut -d' ' -f3`;
			chop($rval);
		}
	} elsif ($vendor eq "turbolinux") {
		$rval=`cat /etc/turbolinux-release | cut -d' ' -f3`;
		chop($rval);
	}
	return $rval;
}

# Get OS distribution, vendor and vendor version
# set CUR_DISTRO_VENDOR, CUR_VENDOR_VER, CUR_VENDOR_MAJOR_VER
sub determine_os_version()
{
	# we use the current system to select the distribution
	# TBD we expect client image for diskless client install to have these files
	if ( -e "/etc/redhat-release" && !(-l "/etc/redhat-release") ) 
	{
		$CUR_DISTRO_VENDOR = "redhat";
	} elsif ( -s "/etc/centos-release" ) {
		$CUR_DISTRO_VENDOR = "redhat";
	} elsif ( -s "/etc/UnitedLinux-release" ) {          
		$CUR_DISTRO_VENDOR = "UnitedLinux";
		$NETWORK_CONF_DIR = "/etc/sysconfig/network";
	} elsif ( -s "/etc/SuSE-release" ) {          
		$CUR_DISTRO_VENDOR = "SuSE";
		$NETWORK_CONF_DIR = "/etc/sysconfig/network";
	} else {
		# autodetermine the distribution
		open DISTRO_VENDOR, "ls /etc/*-release|grep -v lsb\|^os 2>/dev/null |"
			|| die "Unable to open pipe\n";
		$CUR_DISTRO_VENDOR="";
		while (<DISTRO_VENDOR>) {
			chop;
			if (!(-l $_)) {
				my $CDV  = fileparse($_, '-release');
				if ( "$CDV" ne "rocks" ) {
					$CUR_DISTRO_VENDOR = $CDV;
				}
			}
		}
		close DISTRO_VENDOR;
		if ( $CUR_DISTRO_VENDOR eq "" )
		{            
			NormalPrint "Unable to determine current Linux distribution.\n";
			Abort "Please contact your support representative...\n";
		} elsif ($CUR_DISTRO_VENDOR eq "SuSE") {
			$NETWORK_CONF_DIR = "/etc/sysconfig/network";
		} elsif ($CUR_DISTRO_VENDOR eq "centos") {
			$CUR_DISTRO_VENDOR = "redhat";
		}
	}

	$CUR_VENDOR_VER = os_vendor_version($CUR_DISTRO_VENDOR);
	$CUR_VENDOR_MAJOR_VER = $CUR_VENDOR_VER;
	$CUR_VENDOR_MAJOR_VER =~ s/\..*//;	# remove any . version suffix
}

# verify distrib of this system matches files indicating supported
#  arch, distro, distro_version
sub verify_distrib_files
{
	my $supported_arch=`cat ./arch 2>/dev/null`;
	chomp($supported_arch);
	my $supported_distro_vendor=`cat ./distro 2>/dev/null`;
	chomp($supported_distro_vendor);
	my $supported_distro_vendor_ver=`cat ./distro_version 2>/dev/null`;
	chomp($supported_distro_vendor_ver);

	if ( "$supported_arch" eq "" || $supported_distro_vendor eq ""
		|| $supported_distro_vendor_ver eq "") {
		NormalPrint "Unable to proceed: installation image corrupted or install not run as ./INSTALL\n";
		NormalPrint "INSTALL must be run from within untar'ed install image directory\n";
		Abort "Please contact your support representative...\n";
	}

	my $archname;
	my $supported_archname;
	if ( "$supported_arch" ne "$ARCH"
		|| "$supported_distro_vendor" ne "$CUR_DISTRO_VENDOR"
		|| ("$supported_distro_vendor_ver" ne "$CUR_VENDOR_VER"
			&& "$supported_distro_vendor_ver" ne "$CUR_VENDOR_MAJOR_VER"))
	{
		#LogPrint "Unable to proceed, $CUR_DISTRO_VENDOR $CUR_VENDOR_VER not supported by $INT_VERSION media\n";

		$archname=$ARCH;
		if ( $ARCH eq "IA32") {
			$archname="the Pentium Family";
		} 
		if ( $ARCH eq "IA64" ) {
			$archname="the Itanium family";
		} 
		if ( $ARCH eq "X86_64" ) {
			$archname="the EM64T or Opteron";
		} 
		if ( $ARCH eq "PPC64" ) {
			$archname="the PowerPC 64 bit";
		} 
		if ( $ARCH eq "PPC" ) {
			$archname="the PowerPC";
		} 
		
		NormalPrint "$CUR_DISTRO_VENDOR $CUR_VENDOR_VER for $archname is not supported by this installation\n";
		NormalPrint "This installation supports the following Linux Distributions:\n";
		$supported_archname=$ARCH;
		if ( $supported_arch eq "IA32") {
			$supported_archname="the Pentium Family";
		} 
		if ( $supported_arch eq "IA64" ) {
			$supported_archname="the Itanium family";
		} 
		if ( $supported_arch eq "X86_64" ) {
			$supported_archname="the EM64T or Opteron";
		} 
		if ( $supported_arch eq "PPC64" ) {
			$supported_archname="the PowerPC 64 bit";
		} 
		if ( $supported_arch eq "PPC" ) {
			$supported_archname="the PowerPC";
		} 
		NormalPrint "For $supported_archname: $supported_distro_vendor.$supported_distro_vendor_ver\n";
		if ( $Force_Install ) {
			NormalPrint "Installation Forced, will proceed with risk of undefined results\n";
			HitKeyCont;
		} else {
			Abort "Please contact your support representative...\n";
		}
	}
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# Installation logging

my $LogLevel = 0;	# 0 = normal/quiet, 1=verbose, 2=very verbose
my $LogFile = "/dev/null";	# set when open_log

sub open_log(;$)
{
	my($logfile) = shift();
	if ( "$logfile" eq "" ) {
		$logfile="$ROOT/var/log/opa.log";
	}
	$LogFile = $logfile;
	open(LOG_FD, ">>$logfile");
	print LOG_FD "-------------------------------------------------------------------------------\n";
	print LOG_FD my_basename($0) . " $INT_VERSION Run " . `/bin/date`;
	print LOG_FD "$0 @ARGV\n";
	print LOG_FD "Current Dir: " .  getcwd() . "\n";
}

sub close_log()
{
	close LOG_FD;
}

# output to log and screen and die
sub Abort(@)
{
	print(LOG_FD @_);
	die(@_);
}

# output to log and screen
sub NormalPrint(@)
{
	print(@_);
	print(LOG_FD @_);
}

# output to log only
sub LogPrint(@)
{
	print(LOG_FD @_);
}

sub VerbosePrintEnabled()
{
	return ($LogLevel >= 1);
}

sub VerbosePrint(@)
{
	if (VerbosePrintEnabled() ) {
		print(LOG_FD @_);
	}
}
sub DebugPrintEnabled()
{
	return ($LogLevel >= 2);
}

sub DebugPrint(@)
{
	if (DebugPrintEnabled() ) {
		print(LOG_FD @_);
	}
}

# ============================================================================
# Basic input and prompting routines
my $KEY_ESC=27;
my $KEY_CNTL_C=3;
my $KEY_ENTER=13;

my $Default_Prompt=0;	 # use default values at prompts, non-interactive

sub getch()
{
	my $c;
	system("stty -echo raw");
	$c=getc(STDIN);
	system("stty echo -raw");
	print "\n";
	return $c;
}

sub HitKeyCont()
{
	if ( $Default_Prompt )
	{
		return;
	}

	print "Hit any key to continue...";
	getch();
	return;
}

sub remove_whitespace($)
{
	my $string=shift();
	chomp($string);
	$string =~ s/^[[:space:]]*//;	# remove leading
	$string =~ s/[[:space:]]*$//;	# remove trailing
	return $string;
}

# return numeric value: minimum <= value <= maximum
sub GetNumericValue($$$$)
{
	my($retval) = 0;

	my($Question) = $_[0];
	my($default) = $_[1];
	my($minvalue) = $_[2];
	my($maxvalue) = $_[3];

        if ( $Default_Prompt ) {
		NormalPrint "$Question -> $default\n";
		if (($default ge $minvalue) && ($default le $maxvalue)) {
			return $default;
		}
		# for invalid default, fall through and prompt
	}

	while (1)
	{
		NormalPrint "$Question [$default]: ";
		chomp($retval = <STDIN>);
		$retval=remove_whitespace($retval);

		if (length($retval) == 0) {
			$retval=$default;
		}
		if (($retval >= $minvalue) && ($retval <= $maxvalue)) {
			LogPrint "$Question -> $retval\n";
			return $retval;
		}
		else {
			NormalPrint "Value Out-of-Range\n";
                }
	}        
}

#return 0 for no, 1 for yes
sub GetYesNo($$)
{
	my($Question) = shift();
	my($default) = shift();

	my($retval) = 1;
	my($answer) = 0;

	if ( $Default_Prompt ) {
		NormalPrint "$Question -> $default\n";
		if ( "$default" eq "y") {
			return 1;
		} elsif ("$default" eq "n") {
			return 0;
		}
		# for invalid default, fall through and prompt
	}

	while ($answer == 0)
	{
		print "$Question [$default]: ";
		chomp($_ = <STDIN>);
		$_=remove_whitespace($_);
		if ("$_" eq "") {
			$_=$default;
		}
		if (/^[Nn]/) 
		{
			LogPrint "$Question -> n\n";
			$retval = 0;
			$answer = 1;
		} elsif (/^[Yy]/ ) {
			LogPrint "$Question -> y\n";
			$retval = 1;
			$answer = 1;
		}
	}        
	return $retval;
}

# we keep answers in text format.  This way we can later enhance the command
# line argument list to allow answers to more complex questions
my %AnswerMemory = ();	# keep track of past answers to yes/no questions

my @AnswerHelp = ();	# help test for each keyword

# process_args and Usage call occurs before source_comp.  So when we put
# this call in comp.pl, INSTALL has the "built version" of the usage
# which may be out of sync with the "installed version".  Only impacts questions
# asked during uninstall, especially for downgrade case, so that is
# acceptable
sub AddAnswerHelp($$)
{
	my($Keyword) = shift();
	my($help) = shift();

	# check for duplicates, skip if already in list
	foreach my $ans (@AnswerHelp)
	{
		if ($ans =~ m/^$Keyword -/)
		{
			return;
		}
	}
	@AnswerHelp = (@AnswerHelp, "$Keyword - $help");
}

sub showAnswerHelp()
{
	if (scalar(@AnswerHelp) != 0) {
	 	printf STDERR "       --answer keyword=value - provide an answer to a question which might\n";
	 	printf STDERR "            occur during the operation.  answers to questions which are not\n";
	 	printf STDERR "            asked are ignored.  Invalid answers will result in prompting\n";
	 	printf STDERR "            for interactive installs or use of the default for non-interactive.\n";
		printf STDERR "       Possible Questions:\n";
		foreach my $help (@AnswerHelp) {
			printf STDERR "         $help\n";
		}
	} else {
	 	printf STDERR "       --answer keyword=value - presently ignored\n";
	}
}

# similar to GetYesNo, except if the question has already been answered
# (or defaulted on the command line), the question is not asked, instead the
# previous answer is provided
sub GetYesNoWithMemory($$$$)
{
	my($Keyword) = shift();	# unique keyword to identify question
	my($remember) = shift(); # remember answer for use next time
	my($Question) = shift(); # the question shown to user
	my($default) = shift();	# the default to use if not already remembered
	my($retval);

	if ( exists $AnswerMemory{"$Keyword"})
	{
		$_ = $AnswerMemory{"$Keyword"};
		if (/^[Nn]/) 
		{
			NormalPrint "$Keyword: $Question -> n\n";
			$retval = 0;
		} elsif (/^[Yy]/ ) {
			NormalPrint "$Keyword: $Question -> y\n";
			$retval = 1;
		} else {
			# invalid answer, now what?  prompt?
			NormalPrint "$Keyword: $Question -> Invalid answer: $_\n";
			delete $AnswerMemory{"$Keyword"};
		}
	}
	if ( ! exists $AnswerMemory{"$Keyword"})
	{
		$retval = GetYesNo($Question, $default);
		if ($remember) {
			my($ans);
			if ( $retval ) {
				$ans = "y";
			} else {
				$ans = "n";
			}
			$AnswerMemory{"$Keyword"} = $ans;
		}
	}
	return $retval;
}

sub set_answer($$)
{
	my($Keyword) = shift();	# unique keyword to identify question
	my($answer) = shift(); # answer to question

	$AnswerMemory{"$Keyword"} = $answer;
}

sub clear_answer($)
{
	my($Keyword) = shift();

	delete $AnswerMemory{"$Keyword"};
}

sub clear_all_answers($)
{
	my $Keyword;

	foreach $Keyword (keys(%AnswerMemory))
	{
		delete $AnswerMemory{"$Keyword"};
	}
}


#return choice
sub GetChoice($$@)
{
	my($Question) = shift();
	my($default) = shift();
	my(@choices) = @_;	# single character choices

	my $c;

	if ( $Default_Prompt ) {
		NormalPrint "$Question -> $default\n";
		foreach $c ( @choices )
		{
			if (my_tolower("$default") eq my_tolower("$c")) {
				return $c;
			}
		}
		# for invalid default, fall through and prompt
	}

	while (1)
	{
		print "$Question [$default]: ";
		chomp($_ = <STDIN>);
		$_=remove_whitespace($_);
		if ("$_" eq "") {
			$_=$default;
		}
		$_ = my_tolower($_);
		foreach $c ( @choices )
		{
			if ("$_" eq my_tolower("$c")) {
				LogPrint "$Question -> $c\n";
				return $c;
			}
		}
	}        
	# NOTREACHED
}

sub print_separator()
{
	print "-------------------------------------------------------------------------------\n";
}

# based on files on install media update DBG_FREE
# if both release and debug are available on media, prompt user
# This routine checks both the location for IbAccess and Open IB FF installs
sub select_debug_release($)
{
	my($srcdir) = shift();
	my $inp;

	# check current directory to determine if Debug available
	if ( (! -d "$srcdir/bin/$ARCH/$CUR_OS_VER/debug") 
	    and (! -d "$srcdir/bin/$ARCH/$CUR_DISTRO_VENDOR.$CUR_VENDOR_VER/lib/debug")
	    and (! -d "$srcdir/bin/$ARCH/$CUR_DISTRO_VENDOR.$CUR_VENDOR_MAJOR_VER/lib/debug") )
	{
		# no choice, only release available
		$DBG_FREE="release";
	}
	elsif ( (! -d "$srcdir/bin/$ARCH/$CUR_OS_VER/release")
			and (! -d "$srcdir/bin/$ARCH/$CUR_DISTRO_VENDOR.$CUR_VENDOR_VER/lib/release")
			and (! -d "$srcdir/bin/$ARCH/$CUR_DISTRO_VENDOR.$CUR_VENDOR_MAJOR_VER/lib/release") )
	{
		# no choice, only debug available
		$DBG_FREE="debug";
	} elsif ( $Default_Prompt ) {
		$DBG_FREE="release";
		printf ("Installing $DBG_FREE Software\n");
	} else {
		printf ("Both Release and Debug versions are available\n\n");
		printf ("Please select which version should be used for install or upgrade operations:\n\n");
		printf ("1) Release Software\n");
		printf ("2) Debug Software\n");

		$inp = getch();

		if ($inp == 1)
		{
			$DBG_FREE="release";
		}
		elsif ($inp == 2)
		{
			$DBG_FREE="debug";
		}
		else 
		{
			printf ("Invalid Choice...\n");
			HitKeyCont;
			return;
		}
	}
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ===========================================================================
# Basic file/directory install/remove

my $OWNER = "root";
my $GROUP = "root";

# remove any directory prefixes from path
sub my_basename($)
{
	my($path) = shift();

	$path =~ s/.*\/(.*)$/$1/;
	return $path;
}

# check for a file using a glob pattern
# return 1st filename to match pattern
# return "" if no match
sub file_glob($)
{
	my $globpat = shift();	# glob pattern to expand

	my $file;
	# there is a little perl trick here, glob returns a list of matching
	# files.  If we simply assigned glob to a scalar it would retain
	# the rest of the list and return subsequent entries on future glob calls
	# then it would return "" after the last matched name.
	# Hence even if glob matched only 1 name, it would return a 2nd ""
	# value to a future caller.  real subtle problem to figure out.
	
	# the list assignment below allows glob to return a list
	# and all extra list entries are discarded.  Hence this returns the
	# first filename which matches or "" if none are matched
	( $file) = glob("$globpat");

	return "$file";
}

sub make_dir($$$$)
{
	my($dir) = shift();
	my($owner) = shift();
	my($group) = shift();
	my($mode) = shift();

	system "mkdir -p -m $mode $ROOT$dir";
	system "chown $owner $ROOT$dir";
	system "chgrp $group $ROOT$dir";
}

sub check_dir($)
{
	my($dir) = shift();
	if (! -d "$ROOT$dir" ) 
	{
		#Creating directory 

		make_dir("$dir", "$OWNER", "$GROUP", "ugo=rx,u=rwx");
	}
}

sub isDirectoryEmpty($)
{
	my($dir) = shift();
	my $filecount=0;
	if ( -e $dir and -d $dir )
	{
		$filecount=`ls -la $dir| wc -l`;
		if ( $filecount < 4 )
		{
	    	return 1;
		}       
	}
	return 0;
}

sub copy_file($$$$$)
{
	my($src) = shift();
	my($dest) = shift();
	my($owner) = shift();
	my($group) = shift();
	my($mode) = shift();
	# only copy file if source exists, this keep all those cp errors for litering
	# install for development.

	if ( -e $src)
	{               
		system "cp -rf $src $ROOT$dest";
		system "chown $owner $ROOT$dest";
		system "chgrp $group $ROOT$dest";
		system "chmod $mode $ROOT$dest";
	}
}

# Copy file and set security context if SELINUX is enabled;
# If SELINUX is disabled, it will behave like copy_file()
sub copy_file_context($$$$$$)
{
	my($src) = shift();
	my($dest) = shift();
	my($owner) = shift();
	my($group) = shift();
	my($mode) = shift();
	my($context) = shift();
	# only copy file if source exists, this keep all those cp errors for litering
	# install for development.

	if ( -e $src)
	{
		# If the destination file exists, somehow the context will not be
		# overwritten using the "--context" option. Remove the file first.
		if ( -e "$ROOT$dest" ) {
			system "rm -rf $ROOT$dest";
		}
		system "cp -rf --context=$context $src $ROOT$dest 2>/dev/null";
		system "chown $owner $ROOT$dest";
		system "chgrp $group $ROOT$dest";
		system "chmod $mode $ROOT$dest";
	}
}

sub symlink_usrlocal($$)
{
	my($src) = shift();
	my($dest) = shift();
}

sub copy_all_files($$$$$;$)
{
	my($src_dir)=shift();
	my($dest_dir)=shift();
	my($owner) = shift();
	my($group) = shift();
	my($mode) = shift();
	my($symlink_dir) = shift();	# optional argument
	my(@files);
	my $f;
	my $d;

	if (!-d "$src_dir" )
	{
	 	return;	
	}
	if (!-d "$ROOT$dest_dir")
	{
		return;
	}
	@files = glob("$src_dir/*");
	foreach $f (@files)
	{
		$d= my_basename($f);
		if (!-d $f)
		{
			copy_file($f, "$dest_dir/$d", $owner, $group, $mode);
			if ( "$symlink_dir" ne "") {
				symlink_usrlocal("$dest_dir/$d", "$symlink_dir/$d");
			}
		} else {
			check_dir("$dest_dir/$d");
				copy_all_files($f, "$dest_dir/$d", $owner, $group, $mode,"");
			}
		}
	}

sub remove_file($)
{
	my($file) = shift();
	system "rm -f $ROOT$file";
}

sub copy_driver_file($$)
{
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=r,u=rw");
}

sub copy_data_file($$)
{
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=r,u=rw");
}

sub copy_all_data_files($$;$)
{
	copy_all_files("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=r,u=rw","$_[2]");
}

sub copy_arlib_file($$)
{
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=r,u=rw");
}

sub copy_systool_file($$)
{
	# Administrator execution only
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ug=rx,u=rwx");
}

sub copy_all_systool_files($$;$)
{
	copy_all_files("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=r,ug=rx,u=rwx", "$_[2]");
}

sub copy_bin_file($$)
{
	# general user execution
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=rx,u=rwx");
}

sub remove_oldarlib($)
{
	my($libbase) = shift();
	if ( "$LIB_DIR" ne "$OLD_LIB_DIR" )
	{
		system "rm -f $ROOT$libbase";
	}
}

#
# Removes a list of files from a directory
# arg0 : target directory
# arg1 : space delimited list of file names.
#
sub remove_file_list($@)
{
	my($dir)=shift();
	my $f;

	foreach $f (@_)
	{
		remove_file("$dir/$f");
	}
}

# remove the files built from source or installed
# (as listed in .files and .dirs)
# $0 = dirname relative to $ROOT
sub remove_installed_files($)
{
	my $dirname = shift();

	# remove files we installed or user compiled, however do not remove
	# any logs or other files the user may have created
	if ( -d "$ROOT/$dirname" ) {
		system "cd $ROOT/$dirname; for dir in `cat .dirs 2>/dev/null`; do ( cd \$dir; make clobber ) >/dev/null 2>&1; done";
		system "cd $ROOT/$dirname; cat .files 2>/dev/null|xargs rm -f 2>/dev/null";
		system "cd $ROOT/$dirname; cat .files 2>/dev/null|sort -r|xargs rmdir 2>/dev/null";
		system "rm -f $ROOT/$dirname/.files 2>/dev/null";
		system "rm -f $ROOT/$dirname/.dirs 2>/dev/null";
		system "rmdir $ROOT/$dirname/ 2>/dev/null";
	}
}

# ===========================================================================
# Shared Libaries
my $RunLdconfig=0;

sub copy_shlib_file($$)
{
	$RunLdconfig=1;
	copy_file("$_[0]", "$_[1]", "$OWNER", "$GROUP", "ugo=rx,u=rw");
}

sub copy_shlib($$$)
{
	my($src) = shift();
	my($libbase) = shift();
	my($version) = shift();

	system "rm -f $ROOT${libbase}.so";
	if ( ! -e $src )
	{
		if ( -e "$src.so.${version}" )
		{
			$src="$src.so.${version}";
		}
		elsif ( -e "$src.so" )
		{
			$src="$src.so";
		}
	}
	if ( -e $src)
	{
		copy_shlib_file("$src", "${libbase}.so.${version}");
		# source dir is not $ROOT so that when boot root, it will work properly
		system "rm -f " . " $ROOT${libbase}.so";
		system "ln -s " . my_basename("${libbase}.so.${version}") . " $ROOT${libbase}.so";
	}
}

sub symlink_usrlocal_shlib($$$)
{
	# a /usr/lib/opa path w/o suffix (eg. a previous dest for copy_shlib)
	my($src) = shift();
	my($libbase) = shift();
	my($version) = shift();

	symlink_usrlocal("${src}.so.${version}", "${libbase}.so.${version}");
	symlink_usrlocal("${src}.so.${version}", "${libbase}.so");
}

sub remove_shlib($)
{
	my($libbase) = shift();
	$RunLdconfig=1;
	system "rm -f $ROOT${libbase}.so $ROOT${libbase}.so.*";
}

sub remove_oldshlib($)
{
	if ( "$LIB_DIR" ne "$OLD_LIB_DIR" )
	{
		remove_shlib("$_[0]");
	}
}

sub check_ldconfig()
{
	if ($RunLdconfig == 1 )
	{
		print_separator;
		print "Updating dynamic linker cache...\n";
		# this is how /etc/rc.sysinit runs ldconfig
		#LogPrint "Updating dynamic linker cache: /sbin/ldconfig -n /lib\n";
		#system "chroot /$ROOT /sbin/ldconfig -n /lib > /dev/null 2>&1";
		LogPrint "Updating dynamic linker cache: /sbin/ldconfig\n";
		system "chroot /$ROOT /sbin/ldconfig > /dev/null 2>&1";
		$RunLdconfig=0;
		return 1;
	}
	return 0;
}

# ===========================================================================
# Will Reboot be required
my $NeedReboot=0;
sub need_reboot()
{
	$NeedReboot=1;
}

sub check_need_reboot()
{
	if ($NeedReboot == 1 )
	{
		print_separator;
		print BOLD, RED, "A System Reboot is recommended to activate the software changes\n", RESET;
		LogPrint "A System Reboot is recommended to activate the software changes\n";
		return 1;
	}
	return 0;
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

#

use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ========================================================================
# Basic configuration files

my $CONFIG_DIR = "/etc"; # general driver config
my $OFED_CONFIG_DIR = "/etc/infiniband"; # general driver config
my $OFED_CONFIG = "$OFED_CONFIG_DIR/openib.conf";
my $OPA_CONFIG_DIR = "/etc/rdma"; 
my $OPA_CONFIG = "$OPA_CONFIG_DIR/rdma.conf";
my %KeepConfig = (); # keep track of past questions to config questions
my $Default_RpmConfigKeepOld=0; # -O option used to select current rpm config file
my $Default_RpmConfigUseNew=0; # -N option used to select new rpm config file

my $TMP_CONF="/tmp/conf.$$";	# scratch file

sub check_config_dirs()
{
	check_dir("$BASE_DIR");
	check_dir("$OPA_CONFIG_DIR");
}

sub check_keep_config($$$)
{
	my($configFile) = shift();
	my($configDesc) = shift();
	my($default) = shift();

	my($prompt) = "";
	my $keep;

	if ("$configDesc" eq "")
	{
		$prompt="$ROOT$configFile";
	} else {
		$prompt="$configDesc ($ROOT$configFile)";
	}

	if (! exists $KeepConfig{"$ROOT$configFile"})
	{
		$keep=system "diff $ROOT$configFile $ROOT$configFile-sample > /dev/null 2>&1";
		if ($keep != 0)
		{
			NormalPrint "You have a modified $ROOT$configFile configuration file\n";
			$KeepConfig{"$ROOT$configFile"} = GetYesNo("Do you want to keep $prompt?", "$default");
		} else {
			$KeepConfig{"$ROOT$configFile"} = $keep;
		}
	}
	return $KeepConfig{"$ROOT$configFile"};
}

# This is to update the old path when upgrading from 10.3 to newer version
sub replace_old_path_in($)
{
	my $filename = shift();
	open(FILE, "<$filename") || die "\nUnable to locate $filename\n";
	my @lines = <FILE>;
	close(FILE);

	# Replace /etc/sysconfig/opa/ with /etc/opa/
	my @newlines;
	foreach(@lines) {
		$_ =~ s/\/etc\/sysconfig\/opa\//\/etc\/opa\//g;
		push(@newlines,$_);
	}

	open(FILE, ">$filename") || die "\nUnable to locate $filename\n";
	print FILE @newlines;
	close(FILE);
}

# This subroutine is used to check if we should keep a modified rpm config file
# Optional second parameter used to check if a file exist in a previous (now deprecated)
# file location.
sub check_rpm_config_file($;$)
{
	my($config) = shift();
	my($old_config_dir) = shift();
	my($file_name) = basename($config);

	if ( $old_config_dir ne "" && !$Default_RpmConfigUseNew) {
		if ( -e "$old_config_dir/$file_name") {
			if ($Default_RpmConfigKeepOld || GetYesNo ("$file_name found in old file path $old_config_dir, move to new location?", "y")) {
				# This is to update the old path when upgrading from 10.3 to newer version
				replace_old_path_in ("$old_config_dir/$file_name");
				system "mv -f $old_config_dir/$file_name $config";
				return;
			}
		} elsif ( -e "$old_config_dir/$file_name.rpmsave") {
			if ($Default_RpmConfigKeepOld || GetYesNo ("$file_name.rpmsave found in old file path $old_config_dir, move to new location?", "y")) {
				# This is to update the old path when upgrading from 10.3 to newer version
				replace_old_path_in ("$old_config_dir/$file_name.rpmsave");
				system "mv -f $old_config_dir/$file_name.rpmsave $config";
				return;
			}
		}
	}

	if ( -e "$config.rpmsave") {
		if ($Default_RpmConfigKeepOld) {
			system "mv -f $config.rpmsave $config";
		} elsif ($Default_RpmConfigUseNew){
			system "rm -f $config.rpmsave";
		} elsif (GetYesNo ("Do you want to keep $config?", "y")) {
			system "mv -f $config.rpmsave $config";
		} else {
			system "rm -f $config.rpmsave";
		}
	} elsif ( -e "$config.rpmnew") {
		if ($Default_RpmConfigKeepOld) {
			system "rm -f $config.rpmnew";
		} elsif ($Default_RpmConfigUseNew){
			system "mv -f $config.rpmnew $config";
		} elsif (GetYesNo ("Do you want to keep $config?", "y")) {
			system "rm -f $config.rpmnew";
		} else {
			system "mv -f $config.rpmnew $config";
		}
	}
}

sub clear_keep_config($)
{
	my($configFile) = shift();

	delete $KeepConfig{"$ROOT$configFile"};
}

sub remove_conf_file($$)
{
	my($WhichDriver) = shift();
	my($ConfFile) = shift();

	if (-e "$ROOT$ConfFile") 
	{
		if (check_keep_config("$ConfFile", "$WhichDriver configuration file", "y"))
		{
			NormalPrint "Keeping $WhichDriver configuration file ($ROOT$ConfFile) ...\n";
		} else {
			system "rm -rf $ROOT$ConfFile";
		}
	}
	system "rm -rf $ROOT${ConfFile}-sample";
}

# remove a config file where a previous release used a different name for
# the file
sub remove_renamed_conf_file($$;@)
{
	my($WhichDriver) = shift();
	my($ConfFile) = shift();
	my(@OldConfFile_list) = @_;	# old config file names

	foreach my $OldConfFile ( @OldConfFile_list) {
		remove_conf_file("$WhichDriver", "$OldConfFile");
	}
	remove_conf_file("$WhichDriver", "$ConfFile");
}

sub install_conf_file($$$;@)
{
	my($WhichDriver) = shift();
	my($ConfFileDest) = shift();
	my($ConfFileSrc) = shift();
	my(@OldConfFileDest_list) = @_;	# optional
	my $diff_src_dest;
	my $diff_src_sample;
	my $diff_dest_sample;
	my $keep;
	my $need_copy = 1;

	# install an appropriate file into $ConfFileDest
	foreach my $OldConfFileDest ( @OldConfFileDest_list, $ConfFileDest ) {
		DebugPrint("Checking $ROOT$OldConfFileDest\n");
		next if ( ! -e "$ROOT$OldConfFileDest" );

		$diff_src_dest = system "diff $ConfFileSrc $ROOT$OldConfFileDest > /dev/null 2>&1";

		if ( ! -e "${OldConfFileDest}-sample" )
		{
			DebugPrint("No $ROOT${OldConfFileDest}-sample\n");
			$diff_src_sample=1;
			$diff_dest_sample=1;
		} else {
			$diff_src_sample = system "diff $ConfFileSrc $ROOT${OldConfFileDest}-sample > /dev/null 2>&1";
			$diff_dest_sample = system "diff $OldConfFileDest $ROOT${OldConfFileDest}-sample > /dev/null 2>&1";
		}
		DebugPrint("Comparisons: src vs old=$diff_src_dest, src vs oldsample=$diff_src_sample, old vs oldsample=$diff_dest_sample\n");

		if ($diff_src_dest != 0)
		{
			if ($diff_dest_sample == 0)
			{
				NormalPrint "You have an unmodified $WhichDriver configuration file from an earlier install\n";
				$keep =check_keep_config("$OldConfFileDest", "", "n");
			} elsif ($diff_src_sample != 0)
			{
				NormalPrint "You have a $WhichDriver configuration file from an earlier install\n";
				$keep=check_keep_config("$OldConfFileDest", "", "y");
			} else {
				NormalPrint "You have a modified $WhichDriver configuration file\n";
				$keep=check_keep_config("$OldConfFileDest", "", "y");
			}
			if ( $keep ) {
				if ("$OldConfFileDest" ne "$ConfFileDest") {
					# we are working on an old config file
					copy_data_file("$ROOT$OldConfFileDest", "$ConfFileDest");
					NormalPrint "Using $ROOT$OldConfFileDest as $ROOT$ConfFileDest...\n";
				} else {
					# we are working against the new supplied config file
					NormalPrint "Leaving $ROOT$OldConfFileDest unchanged...\n";
				}
				$need_copy=0;
				last;
			} # otherwise onto next file, if needed will copy new file below
		}
	}
	if ( $need_copy) {
		# no old files kept (or not found), use new release version
		NormalPrint "Updating $ROOT$ConfFileDest ...\n";
		copy_data_file("$ConfFileSrc", "$ConfFileDest");
	}
	foreach my $OldConfFileDest ( @OldConfFileDest_list ) {
		system "rm -rf $ROOT${OldConfFileDest}-sample";
	}
	copy_file("$ConfFileSrc", "${ConfFileDest}-sample", "$OWNER", "$GROUP", "ugo=r,u=r");
}

# after doing an rpm install, config files will be either installed (if new)
# or retained with the new version in .rpmnew
# this allows user to select which to keep as their present config file
sub copy_rpm_conf_file($$;@)
{
	my($WhichDriver) = shift();
	my($ConfFileDest) = shift();
	my(@OldConfFileDest_list) = @_;	# optional
	my($ConfFileSrc) = "$ROOT$ConfFileDest.rpmnew";

	if ( ! -e "$ROOT$ConfFileDest.rpmnew" )
	{
		# must be first install, Dest is the newest file
		# save a copy in case we overwrite it with an OldConfFileDest below
		system("cp $ROOT$ConfFileDest $TMP_CONF");
		$ConfFileSrc="$TMP_CONF"
	}
	install_conf_file($WhichDriver, $ConfFileDest, $ConfFileSrc, @OldConfFileDest_list);
	system("rm -f $ConfFileSrc");
}

# After an RPM install, config files from previous install (denoted via .rpmsave)
# may need to be preserved. Ask the user if they want to keep.
sub preserve_prev_rpm_conf($)
{
	my($ConfFileDest) = shift();
	my($ConfFileSave) = "$ROOT$ConfFileDest.rpmsave";
	
	if ( -e "$ConfFileSave" )
	{
		#install_conf_file($WhichDriver, $ConfFileDest, $ConfFileSave);
		#system("rm -f $ConfFileSave");
		my $diff_src_dest = system "diff $ROOT$ConfFileDest $ConfFileSave > /dev/null 2>&1";
		if ($diff_src_dest != 0) {
			printf("You have a modified $ROOT$ConfFileDest configuration file \n");
			my $keep = GetYesNo("Do you want to keep $ROOT$ConfFileDest?", "y");
			if ($keep) {
				printf("Using the modified $ConfFileDest file \n");
				copy_data_file("$ConfFileSave", "$ROOT$ConfFileDest");
			}
			else {
				printf("Using the new $ConfFileDest file \n");
			}
		}

		system "rm -f $ConfFileSave"
	}
}

# install a config file where a previous release used a different name for
# the file
sub install_renamed_conf_file($$$;@)
{
	my($WhichDriver) = shift();
	my($ConfFileDest) = shift();
	my($ConfFileSrc) = shift();
	my(@OldConfFileDest_list) = @_;	# in order that we consider them

	my $diff_src_dest;
	my $diff_src_sample;
	my $diff_dest_sample;

	if (! -e "$ROOT$ConfFileDest") {
		# first upgrade install, we consider old files as relevant
		# we want to do the install_conf_file algorithm
		# but use OldConfFileDest for all but file destination of copy
		install_conf_file("$WhichDriver","$ConfFileDest","$ConfFileSrc",@OldConfFileDest_list);
	} else {
		# don't touch old (if any), just perform normal upgrade/install
		foreach my $OldConfFileDest ( @OldConfFileDest_list ) {
			system "rm -rf $ROOT${OldConfFileDest}-sample";
		}
		install_conf_file("$WhichDriver","$ConfFileDest","$ConfFileSrc");
	}
}

# ===========================================================================
# functions to insert/remove config file additions bounded by markers

# 
# Deletes contents from start marker to end marker
# arg0 : Start marker
# arg1 : End Marker
# arg2 : Leave Marks in file after removing contents
# arg3 : Filename to operate on
#

sub del_marks($$$$)
{
	my($StartMark) = shift();
	my($EndMark) = shift();
	my($LeaveMarks) = shift();
	my($FileName) = shift();

	my($found_mark)=0;

	open (INPUT, "$FileName");
	open (OUTPUT, ">>$TMP_CONF");

	select (OUTPUT);
	while (($found_mark == 0) && ($_=<INPUT>)) {
		if (/$StartMark/) {
			$found_mark=1;
			if ($LeaveMarks) {
				print $_;
			}
		} else {
			print $_;
		}
	}

	while (($found_mark == 1) && ($_=<INPUT>)) {
		if (/$EndMark/) {
			$found_mark = 0;
			if ($LeaveMarks) {
				print $_;
			}
		} 
	}

	while ($_=<INPUT>) {
		print $_;
	}

	select(STDOUT);

	close (INPUT);
	close (OUTPUT);

	system "mv $TMP_CONF $FileName";
}

sub ins_marks($$$$)
{
	my($StartMark) = shift();
	my($EndMark) = shift();
	my($Contents) = shift();
	my($FileName) = shift();

	my($found_mark)=0;
	my($ReadEnd) = "";

	open (INPUT, "$FileName");
	open (OUTPUT, ">>$TMP_CONF");

	select (OUTPUT);
	while (($found_mark == 0) && ($_=<INPUT>)) {
		if (/$StartMark/) {
			$found_mark=1;
			print $_;
		} else {
			print $_;
		}
	}

	while (($found_mark == 1) && ($_=<INPUT>)) {
		if (/$EndMark/) {
			$found_mark = 0;
			$ReadEnd = $_;
		} 
	}

	print $Contents;
	print $ReadEnd;

	while ($_=<INPUT>) {
		print $_;
	}

	select(STDOUT);

	close (INPUT);
	close (OUTPUT);

	system "mv $TMP_CONF $FileName";
}

# gets contents including marks and compares to specified file
# returns 0 on match, 1 if different
sub compare_marks($$$$)
{
	my($StartMark) = shift();
	my($EndMark) = shift();
	my($FileName) = shift();
	my($CompareTo) = shift();

	my $is_different;
	my $found_inf;

	system "awk '/$StartMark/, /$EndMark/ {print}' $FileName > /tmp/tmp.conf";
	$found_inf = `diff /tmp/tmp.conf $CompareTo`;
	system "rm -f /tmp/tmp.conf";

	if ($found_inf eq "") 
	{
		$is_different = 0;
	} else 
	{
		$is_different = 1;
	}
	return $is_different
}

sub	edit_conf_file($$$$$)
{
	my($SourceFile) = shift();
	my($DestFile) = shift();
	my($FileDesc) = shift();
	my($StartMarker) = shift();
	my($EndMarker) = shift();

	my $is_different;
	my $found_inf;

	if (! -e "$ROOT$DestFile")
	{
		Abort "$FileDesc file $ROOT$DestFile is missing";
	}

	NormalPrint "Updating $FileDesc...\n";
	$found_inf = `grep "$StartMarker" $ROOT$DestFile`;

	# if the iba section does not exist then just add and then return
	if ($found_inf eq "") 
	{
		system "cat $SourceFile >> $ROOT$DestFile";
		return;
	}

	# found an iba section so lets extract the iba section and compare it to the new section
	$is_different = compare_marks ("$StartMarker", "$EndMarker", "$ROOT$DestFile", "$SourceFile");

	if ($is_different) 
	{
		NormalPrint "You have $FileDesc entries for IB drivers from an earlier install\n";
		if (check_keep_config($DestFile, "", "y"))
		{
			NormalPrint "Leaving $ROOT$DestFile unchanged...\n";
		} 
		else
		{
			# delete old section and markers
			del_marks ("$StartMarker", "$EndMarker", 0, "$ROOT$DestFile");
			# add in the new
			system "cat $SourceFile >> $ROOT$DestFile";
		}
	}
}

# ===========================================================================
# functions to edit simple config files

# This function supports reading parameters from config file which are
# actually shell scripts.  openib.conf, opafastfabric.conf and the Linux network
# config files are examples of such.
# If the file or parameter does not exist, returns ""
sub read_simple_config_param($$)
{
	my $config_file=shift();
	my $parameter=shift();

	if ( ! -e "$config_file" ) {
		return "";
	}
	my $value=`. $config_file >/dev/null 2>/dev/null; echo \$$parameter`;
	chomp($value);
	return "$value";
}

sub edit_simple_config_file($$)
{
	my($FileName) = shift();
	my($changes) = shift();	# set of sed commands

	my $rc;

	$rc = system("sed $changes < $FileName > $TMP_CONF");
	if ($rc != 0) {
		system ("rm -rf $TMP_CONF >/dev/null 2>&1");
		return $rc;
	}

	$rc = system "mv $TMP_CONF $FileName";
	return $rc;
}

# ==========================================================================
# configuration file

# OFED & OPA configuration files are structured as a list of lines of the form:
# 	parameter=value
# There may be additional comment and whitespace lines
sub change_conf_param($$$)
{
	my $parameter=shift();
	my $newvalue=shift();
	my $conf=shift();

	VerbosePrint("edit $conf: '$parameter=$newvalue'\n");
	if (0 != system("grep '^$parameter=' $conf >/dev/null 2>/dev/null")) {
		# add parameter to file
		system ("echo '$parameter=$newvalue' >> $conf 2>/dev/null");;
	} else {
		return edit_simple_config_file("$conf",
			"-e 's/^$parameter=.*/$parameter=$newvalue/g'");
	}
}

sub change_openib_conf_param($$)
{
	my $p1=shift();
	my $p2=shift();
	change_conf_param($p1,$p2,"$ROOT/$OFED_CONFIG");
}

sub change_opa_conf_param($$)
{
	my $p1=shift();
	my $p2=shift();
	change_conf_param($p1,$p2,"$ROOT/$OPA_CONFIG");
}

sub read_openib_conf_param($$)
{
	my $parameter=shift();
	my $config_file=shift();	# if "", defaults to standard file

	if ( "$config_file" eq "" ) {
		$config_file="$ROOT/$OFED_CONFIG";
	}
	return read_simple_config_param($config_file, $parameter);
}

sub read_opa_conf_param($$)
{
	my $parameter=shift();
	my $config_file=shift();	# if "", defaults to standard file

	if ( "$config_file" eq "" ) {
		$config_file="$ROOT/$OPA_CONFIG";
	}
	return read_simple_config_param($config_file, $parameter);
}
# Function to setup environment variable. used to setup environment variables for RPM post install
# configuration
sub setup_env($$)
{
        my ($env_type) = shift();  # environment variable
        my ($env_value) = shift(); # value to be set
        $ENV{$env_type}="$env_value";
}

sub prompt_conf_param($$$$;$)
{
	my $parameter=shift();
	my $parameterDesc=shift();
	my $default=shift();
	my $conf=shift();
	my $OPA_INSTALL_ENV=shift();

	my $prompt;
	my $value;
	my $env_value;

	if ("$parameterDesc" eq "") {
		$prompt="$parameter";
	} else {
		$prompt="$parameterDesc ($parameter)";
	}
	if (GetYesNo("Enable $prompt?", $default) == 1) {
		$value="yes";
		$env_value=1;
	} else {
		$value="no";
		$env_value=0;
	}
        # some configuation parameter are configured directly, some are by RPM. for RPM we will setup env variable.
        if ( $OPA_INSTALL_ENV == "OPA_SRPHA_ENABLE" || $OPA_INSTALL_ENV == "OPA_RENICE_IB_MAD" || $OPA_INSTALL_ENV == "OPA_SET_IPOIB_CM" ) {
            change_conf_param($parameter, $value, $conf);
        } else {
            # setup env variable, RPM installation will configure these
           setup_env("$OPA_INSTALL_ENV", $env_value);
        }
}

sub prompt_openib_conf_param($$$;$)
{
	my $parameter=shift();
	my $parameterDesc=shift();
	my $default=shift();
	my $OPA_INSTALL_ENV=shift();

	prompt_conf_param($parameter, $parameterDesc, $default, 
		"$ROOT/$OFED_CONFIG", $OPA_INSTALL_ENV);
}

sub prompt_opa_conf_param($$$;$)
{
	my $parameter=shift();
	my $parameterDesc=shift();
	my $default=shift();
	my $OPA_INSTALL_ENV=shift();

	prompt_conf_param($parameter, $parameterDesc, $default, 
		"$ROOT/$OPA_CONFIG", $OPA_INSTALL_ENV);
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ===========================================================================
# startup scripts

# on Some Os's this configures startup file dependencies, especially for
# parallel startup optimizations
my $INSSERV_CONF="/etc/insserv.conf";
# where master copy of init scripts are installed
my $INIT_DIR = "/etc/init.d";
my $SYSTEMCTL_EXEC = system("command -v systemctl > /dev/null 2>&1");
# Components and Sub-Components which user has asked to stop
# these could be utilities or drivers
my %StopFacility = ();

sub disable_autostart($)
{
	my($WhichStartup) = shift();

	# disable autostart but leave any kill scripts so stopped on shutdown
	# Note on SLES off removes kill scripts too, on redhat they remain
	if($SYSTEMCTL_EXEC eq 0 && 
		($WhichStartup eq "opafm" || $WhichStartup eq "opa" || $WhichStartup eq "ibacm"))
	{
		system "systemctl disable $WhichStartup >/dev/null 2>&1";
	} else {
		system "chroot /$ROOT /sbin/chkconfig $WhichStartup off > /dev/null 2>&1";
	}
}

sub enable_autostart($)
{
	my($WhichStartup) = shift();

	# cleanup to be safe
	if($SYSTEMCTL_EXEC eq 0 && 
		($WhichStartup eq "opafm" || $WhichStartup eq "opa" || $WhichStartup eq "ibacm"))
	{
		system "systemctl enable $WhichStartup >/dev/null 2>&1";
	} else {
		system "chroot /$ROOT /sbin/chkconfig --del $WhichStartup > /dev/null 2>&1";
		system "chroot /$ROOT /sbin/chkconfig --add $WhichStartup > /dev/null 2>&1";
		# make sure its enabled now
		system "chroot /$ROOT /sbin/chkconfig $WhichStartup on > /dev/null 2>&1";
	}
}

# Is given startup script currently configured to autostart
sub IsAutostart($)
{
	my($WhichStartup) = shift();

	if($SYSTEMCTL_EXEC eq 0 &&
	   ($WhichStartup eq "opafm" || $WhichStartup eq "opa" || $WhichStartup eq "ibacm"))
	{
		my($isEnabled) = `systemctl is-enabled $WhichStartup 2>/dev/null`;
		chomp($isEnabled);
		if($isEnabled eq "disabled" || $isEnabled eq "")
		{
			return 0;
		} else {
			return 1;
		}
	} else {
		my $logoutput;
		open(CHKCONFIG,"chroot /$ROOT /sbin/chkconfig --list $WhichStartup 2> /dev/null |") || Abort "Couldn't open a pipe for chkconfig\n";
		$logoutput = <CHKCONFIG>;
		close(CHKCONFIG);
		# remove startup name from output, this way opamon is not mistaken for "on"
		$logoutput=~s/^$WhichStartup//;
		if (grep /:on/, $logoutput)
		{
			return 1;
		} elsif ( `ls $ROOT/etc/rc.d/rc3.d/S*$WhichStartup 2>/dev/null` ne "" ) {
			# this case is an old install being updated
			return 1;
		} else {
			return 0;
		}
	}
}

# remove startup dependency
sub del_insserv_conf($$)
{
	my($WhichStartup) = shift();	# our startup script
	my($dependent) = shift();		# start up which must preceed it

	if ( -e "$ROOT/$INSSERV_CONF" )
	{
		system "sed -e '/^\$$dependent\[ \\t\]/s/\[ \\t\]+\\+$WhichStartup//' > $TMP_CONF < $ROOT/$INSSERV_CONF";
		system "mv $TMP_CONF $ROOT/$INSSERV_CONF";
		system "chmod 444 $ROOT/$INSSERV_CONF";
	}
}

# add startup dependency
sub add_insserv_conf($$)
{
	my($WhichStartup) = shift();	# our startup script
	my($dependent) = shift();		# startup which must preceed it

	if ( -e "$ROOT/$INSSERV_CONF" )
	{
		del_insserv_conf("$WhichStartup", "$dependent");
		system "sed -e '/^\$$dependent\[ \\t\]/s/\$/ +$WhichStartup/' > $TMP_CONF < $ROOT/$INSSERV_CONF";
		system "mv $TMP_CONF $ROOT/$INSSERV_CONF";
		system "chmod 444 $ROOT/$INSSERV_CONF";
	}
}

# Determine if the specified utility is running.
# Use 'pgrep' to check for a matching utility name.
#
# input:
#	[0] = name of utility as output by 'ps'.
# output:
#	0 == named utility not running (reported by pgrep).
#	1 == named utility is running.

sub IsUtilityRunning($)
{
	my($WhichUtility) = shift();

	my $result;

	if ( ROOT_is_set() )
	{
		return 0;
	}

	$result = system("/usr/bin/pgrep $WhichUtility >/dev/null 2>/dev/null");
	if ($result != 0 )
	{
		return 0;
	} else {
		return 1;
	}
}

# prompts and stops a driver or autostart utility
sub check_stop_facility($$)
{
	my($WhichFacility) = shift();
	my($prompt) = shift();

	if ( ROOT_is_set() )
	{
		return 0;
	}
	if (! exists $StopFacility{$WhichFacility})
	{
		$StopFacility{$WhichFacility} = GetYesNo("Stop $prompt now?", "n");
	}
	return $StopFacility{$WhichFacility};
}

sub stop_utility($$$)
{
	my($UtilityDesc) = shift();
	my($WhichUtility) = shift();	# utility executable in ps
	my($InitScript) = shift();

	my($retval)=0;
	my $prompt;

	if ( ROOT_is_set() )
	{
		return;
	}
	if ( "$UtilityDesc" eq "" )
	{
		$prompt="$WhichUtility";
	} else {
		$prompt="$UtilityDesc ($WhichUtility)";
	}
	if (IsUtilityRunning("$WhichUtility") == 1) 
	{
		if (check_stop_facility("$WhichUtility", "$prompt") == 1)
		{
			if (-e "$INIT_DIR/$InitScript" )
			{
				if($SYSTEMCTL_EXEC eq 0 && ($InitScript eq "opafm" || $InitScript eq "opa"))
				{
					system "systemctl stop $InitScript >/dev/null 2>&1";
				} else {
					system "$INIT_DIR/$InitScript stop";
				}
				$retval=1;
			} else {
				system "/usr/bin/pkill $WhichUtility";
				$retval=1;
			}
			$StopFacility{$WhichUtility} = 0;	# ask again if find still running
		}
	}
	return $retval;
}

sub start_utility($$$$)
{
	my($UtilityDesc) = shift();
	my($UtilityDir) = shift();
	my($WhichUtility) = shift();	# executable in $UtilityDir and found in ps
	my($InitScript) = shift();

	my $prompt;

	if ( ROOT_is_set() )
	{
		return;
	}
	if ( "$UtilityDesc" eq "" )
	{
		$prompt="$WhichUtility";
	} else {
		$prompt="$UtilityDesc ($WhichUtility)";
	}
	if (-e "/$UtilityDir/$WhichUtility" )
	{
		if (IsUtilityRunning("$WhichUtility") == 1) 
		{
			print "$prompt already started...\n";
			if (GetYesNo("Restart $prompt now?", "n") == 1)
			{
				if (-e "$INIT_DIR/$InitScript" )
				{
					if($SYSTEMCTL_EXEC eq 0 && ($InitScript eq "opafm" || $InitScript eq "opa"))
					{
						system "systemctl restart $InitScript >/dev/null 2>&1";
					} else {
						system "$INIT_DIR/$InitScript restart";
					}
				} else {
					system "/usr/bin/pkill $WhichUtility";
				}
			}
		} else {
			if (GetYesNo("Start $prompt now?", "n") == 1)
			{
				if (-e "$INIT_DIR/$InitScript" )
				{
					if($SYSTEMCTL_EXEC eq 0 && ($InitScript eq "opafm" || $InitScript eq "opa"))
					{
						system "systemctl start $InitScript >/dev/null 2>&1";
					} else {
						system "$INIT_DIR/$InitScript start";
					}
				} else {
					system "/usr/bin/pkill $WhichUtility";
				}
			}
		}
	}
}

sub remove_startup($)
{
	my($WhichStartup) = shift();

	# test added to avoid duplicate message
	if ( -e "$ROOT$INIT_DIR/$WhichStartup" )
	{
		print "Removing $WhichStartup init scripts...\n";
	}
	# to be safe, remove and disable it even if missing
	disable_autostart($WhichStartup);
	if($SYSTEMCTL_EXEC ne 0)
	{
		system "chroot /$ROOT /sbin/chkconfig --del $WhichStartup > /dev/null 2>&1";
		system "rm -f $ROOT$INIT_DIR/$WhichStartup";
	}
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ============================================================================
# Driver file management

# path to source directories for each set of kernel drivers,
# such as <./bin/$ARCH/*>;
my @supported_kernels;
my @module_dirs = ();

my $RunDepmod=0;	# do we need to run depmod
sub	verify_modtools()
{
	my $look_str;
	my $look_len;
	my $ver;
	my $mod_ver;

	$look_str = "insmod version ";
	$look_len = length ($look_str);
	$ver = `$ROOT/sbin/insmod -V 2>&1 | grep \"$look_str\"`;
	chomp $ver;
	$mod_ver = substr ($ver, $look_len - 1, length($ver)-$look_len+1);
	$_ = $mod_ver;
	/2\.[34]\.[0-9]+/;
	#$MOD_UTILS_REV;
	if ($& eq "")
	{
		NormalPrint "Unable to proceed, modutils tool old: $mod_ver\n";
		Abort "Install newer version of modutils 2.3.15 or greater" ;
	}
}

sub check_depmod()
{
	if ($RunDepmod == 1 )
	{
		print_separator;
		print "Generating module dependencies...\n";
		LogPrint "Generating module dependencies: /sbin/depmod -aev\n";
		system "chroot /$ROOT /sbin/depmod -aev > /dev/null 2>&1";
		$RunDepmod=0;
		return 1;
	}
	return 0;
}

# is the given driver available on the install media
sub available_driver($$)
{
	my($srcdir) = shift();
	my($WhichDriver) = shift();

	$WhichDriver .= $DRIVER_SUFFIX;
	return ( -e "$srcdir/$CUR_OS_VER/$DBG_FREE/$WhichDriver" );
}

# is the given driver installed on this system
sub installed_driver($$)
{
	my($WhichDriver) = shift();
	my($subdir) = shift();
	$WhichDriver .= $DRIVER_SUFFIX;
	return (-e "$ROOT/lib/modules/$CUR_OS_VER/$subdir/$WhichDriver" );
}

# create iba kernel module directory
sub create_driver_dirs($)
{
	my($subdir) = shift();

	my $supported_kernel;
	foreach my $supported_kernel_path ( @supported_kernels ) 
	{    
		$supported_kernel = my_basename($supported_kernel_path);
		if ( -d "$ROOT/lib/modules/$supported_kernel" )
		{
			make_dir("/lib/modules/$supported_kernel/$subdir", "$OWNER", "$GROUP", "ugo=rx,u=rwx");
		}
	}
}

# remove iba kernel module directories
sub remove_driver_dirs($)
{
	my($subdir) = shift();

	my $supported_kernel;
	if ( "$subdir" ne "" ) {
		foreach my $supported_kernel_path ( @supported_kernels ) 
		{    
			$supported_kernel = my_basename($supported_kernel_path);
			if ( -d "$ROOT/lib/modules/$supported_kernel/$subdir" )
			{
				system "rm -rf $ROOT/lib/modules/$supported_kernel/$subdir";
			}
		}
	}

	# remove SDK stuff
	system "rm -rf $ROOT/etc/iba";
}

sub copy_driver($$$)
{
	# TBD put drivers in /lib/modules instead of /lib/modules/iba
	my($WhichDriver) = shift();
	my($subdir) = shift();
	my($verbosity) = shift(); # verbose or silent

	$WhichDriver .= $DRIVER_SUFFIX;

	if ( "$verbosity" ne "silent" ) {
		print ("Copying ${WhichDriver}...\n");
	}
	$RunDepmod=1;
	need_reboot();
	my $supported_kernel;

	foreach my $supported_kernel_path ( @supported_kernels ) 
	{    
		$supported_kernel = my_basename($supported_kernel_path);

		if ( -d "$ROOT/lib/modules/$supported_kernel" )
		{             
			copy_driver_file( "$supported_kernel_path/$DBG_FREE/$WhichDriver",
								"/lib/modules/$supported_kernel/$subdir" );
		}
	}
}

# copy a single driver from srcdir for current OS only
sub copy_driver2($$$$)
{
	my($WhichDriver) = shift();
	my($srcdir) = shift();
	my($subdir) = shift();
	my($verbosity) = shift();	# verbose or silent

	$WhichDriver .= $DRIVER_SUFFIX;

	if ( "$verbosity" ne "silent" ) {
		printf ("Copying ${WhichDriver}...\n");
	}
	$RunDepmod=1;
	need_reboot();
	copy_driver_file( "$srcdir/$WhichDriver", "/lib/modules/$CUR_OS_VER/$subdir" );
}

sub remove_driver($$$)
{
	my($WhichDriver) = shift();
	my($subdir) = shift();
	my($verbosity) = shift();	# verbose or silent

	my $dd;

	$WhichDriver .= $DRIVER_SUFFIX;
	if ( "$verbosity" ne "silent" ) {
		print ("Removing ${WhichDriver}...\n");
	}
	LogPrint ("Removing $subdir/${WhichDriver}...\n");
	$RunDepmod=1;
	need_reboot();
	foreach $dd (@module_dirs)
	{
		if ( -e "$ROOT$dd/$subdir/$WhichDriver" )
		{
			system "rm -rf $ROOT$dd/$subdir/$WhichDriver";  
		}
		if ( "$subdir" ne "" && isDirectoryEmpty("$ROOT$dd/$subdir") )
		{
	    	system "rm -rf $ROOT$dd/$subdir"
		}
	}
}

# Determine if the specified kernel module is loaded.
# Scan output of 'lsmod' for a matching module name.
#
# input:
#	[0] = name of module as output by 'lsmod'.
# output:
#	0 == named module not loaded (reported by lsmod).
#	1 == named module is loaded.

sub IsModuleLoaded($)
{
	my($WhichModule) = shift();

	my($found) = 0;
	my($TmpFile) = "/usr/tmp/lsmod.out";

	if ( ROOT_is_set() ) {
		return 0;
	}

	system("/sbin/lsmod > ".$TmpFile);

	open (INPUT, $TmpFile) || return 0;
	while ( ($_=<INPUT>) ) {
		if (/^$WhichModule\s/) {
			$found=1;
			last;
		}
	}
	close(INPUT);

	system("rm -f ".$TmpFile);

	return $found;
}

sub stop_driver($$$)
{
	my($DriverName) = shift();	# descriptive name of driver
	my($WhichDriver) = shift();	# actual linux module name
	my($InitScript) = shift();	# if "" use rmmod on WhichDriver

	my($retval)=0;
	my $prompt;

	if ( ROOT_is_set() ) {
		return;
	}
	if ( "$DriverName" eq "" ) {
		$prompt="$WhichDriver";
	} else {
		$prompt="$DriverName ($WhichDriver)";
	}
	if (IsModuleLoaded("$WhichDriver") == 1) 
	{
		if (check_stop_facility("$WhichDriver", "$prompt driver") == 1)
		{
			if (-e "$INIT_DIR/$InitScript" )
			{
				system "$INIT_DIR/$InitScript stop";
				$retval=1;
			} else {
				system "/sbin/rmmod $WhichDriver";
				$retval=1;
			}
			$StopFacility{$WhichDriver} = 0;	# ask again if find still running
		}
	}
	return $retval;
}

sub start_driver($$$$)
{
	my($DriverName) = shift();
	my($WhichDriver) = shift();
	my($subdir) = shift();
	my($InitScript) = shift();

	my $prompt;

	$WhichDriver .= $DRIVER_SUFFIX;
	if ( ROOT_is_set() )
	{
		return;
	}
	if ( "$DriverName" eq "" )
	{
		$prompt="$WhichDriver";
	} else {
		$prompt="$DriverName ($WhichDriver)";
	}
	if (-e "/lib/modules/$CUR_OS_VER/$subdir/$WhichDriver" )
	{
		if (IsModuleLoaded("$WhichDriver") == 1) 
		{
			print "$prompt driver already started...\n";
			if (GetYesNo("Restart $prompt driver now?", "n") == 1)
			{
				if (-e "$INIT_DIR/$InitScript" )
				{
					system "$INIT_DIR/$InitScript restart";
				} else {
					system "/sbin/rmmod $WhichDriver";
				}
			}
		} else {
			if (GetYesNo("Start $prompt driver now?", "n") == 1)
			{
				if (-e "$INIT_DIR/$InitScript" )
				{
					system "$INIT_DIR/$InitScript start";
				} else {
					system "/sbin/rmmod $WhichDriver";
				}
			}
		}
	}
}

# ============================================================================
# Device identification

# Identify speed of PCIe link for a Mellanox HCA
# This routine is from OFED, but is not yet used.  OFED only used it to
# provide a verbose message during install
sub check_pcie_link
{
	my $setpci = '/sbin/setpci';
	my $lspci = '/sbin/lspci';
    if (open (PCI, "$lspci -d 15b3: -n|")) {
        while(<PCI>) {
            my $devinfo = $_;
            $devinfo =~ /(15b3:[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])/;
            my $devid = $&;
            my $link_width = `$setpci -d $devid 72 | cut -b1`;
            chomp $link_width;

            print BLUE "Device ($devid):\n";
            print "\t" . `$lspci -d $devid`;

            if ( $link_width eq "8" ) {
                print "\tLink Width: 8x\n";
            }
            else {
                print "\tLink Width is not 8x\n";
            }
            my $link_speed = `$setpci -d $devid 72 | cut -b2`;
            chomp $link_speed;
            if ( $link_speed eq "1" ) {
                print "\tLink Speed: 2.5Gb/s\n";
            }
            elsif ( $link_speed eq "2" ) {
                print "\tLink Speed: 5Gb/s\n";
            }
            else {
                print "\tLink Speed: Unknown\n";
            }
            print "", RESET "\n";
        }
        close (PCI);
    }
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =========================================================================
# Component installation state

# constants for component state/action tracking during menus
my $State_Uninstall = 0;
my $State_Install = 1;
my $State_UpToDate = 2;
my $State_DoNotInstall = 3;
my $State_DoNotAutoInstall = 4;	# valid only in DefaultInstall, must explicitly select

sub component_start_prompts();
sub disable_components(@);
my %comp_prereq_hash;
# indicate if given state reflects a component which will be on the system
# after processing the present menu selections
# states:
# $State_Uninstall - make sure not on system (Uninstall)
# $State_Install - install on system (Install/Upgrade/Re-Install)
# $State_UpToDate - leave as is on system (Installed/Up To Date)
# $State_DoNotInstall - leave as is not on system (Do Not Install)
sub will_be_on_system($)
{
	my $state = shift();

	return ($state == $State_Install || $state == $State_UpToDate);
}

# state returned:
# $State_Uninstall - make sure not on system (Uninstall)
# $State_Install - install on system (Install/Upgrade/Re-Install)
# $State_UpToDate - leave as is on system (Installed/Up To Date)
# $State_DoNotInstall - leave as is not on system (Do Not Install)
sub setstate($$$$)
{
	my $isinstalled = shift();   
	my $available   = shift();
	my $isupgrade   = shift();
	my $defaultstate= shift();	# default if available and ! installed

	if (! $available && $isinstalled && !$isupgrade){ return $State_UpToDate; }
	if (! $available && ! $isinstalled )			{ return $State_DoNotInstall; }
	if (! $available )				                { return $State_Uninstall; }
	if ($isinstalled && !$isupgrade)				{ return $State_UpToDate; }
	if ($isinstalled)								{ return $State_Install; }
	# available and not installed
	if ($defaultstate == $State_DoNotAutoInstall)	{ return $State_DoNotInstall; }
	return $defaultstate;	# typcally State_Install
}

# state returned:
# $State_Uninstall - make sure not on system (Uninstall)
# $State_Install - install on system (Install/Upgrade/Re-Install)
# $State_UpToDate - leave as is on system (Installed/Up To Date)
# $State_DoNotInstall - leave as is not on system (Do Not Install)
sub shiftstate($$$$)
{
	my $state       = shift();
	my $isinstalled = shift();   
	my $available   = shift();
	my $isupgrade   = shift();

	if (! $available && $isinstalled && ! $isupgrade) {
		return ($state==$State_UpToDate)?$State_Uninstall:$State_UpToDate;
	}
	if (! $available && ! $isinstalled ) {
		return ($state==$State_DoNotInstall)?$State_Uninstall:$State_DoNotInstall;
	}
	if (! $available ) {
		return $State_Uninstall;
	}
	if ($isinstalled && !$isupgrade) {
		return ($state==$State_UpToDate)?$State_Install
				:($state==$State_Install)?$State_Uninstall
				:$State_UpToDate;
	}
	if ($isinstalled ) {
		return ($state==$State_Install)?$State_Uninstall:$State_Install;
	}
	# available and not installed
	return ($state==$State_Uninstall)?$State_Install
			:($state==$State_Install)?$State_DoNotInstall:$State_Uninstall;
}

sub InstallStateToStr($)
{
	my $state = shift();

	if ($state == $State_Uninstall) {
		return "Uninstall";
	} elsif ($state == $State_Install) {
		return "Install";
	} elsif ($state == $State_UpToDate) {
		return "UpToDate";
	} elsif ($state == $State_DoNotInstall) {
		return "DoNotInstall";
	} elsif ($state == $State_DoNotAutoInstall) {
		return "DoNotAutoInstall";
	} else {
		return "INVALID";
	}
}

# caller has output 24 characters, we have 55 left to play with
# (avoid using last column so don't autowrap terminal)
sub printInstallState($$$$)
{
	my $installed = shift();
	my $uninstall = shift();
	my $boldmessage = shift();
	my $message   = shift();

	if ($uninstall )
	{
		print   RED, "[  Uninstall  ] ", RESET;
	} elsif ($installed ) {
		print GREEN, "[  Installed  ] ", RESET;
	} else {
		print        "[Not Installed] ";
	}
	if ("$message" ne "" && $boldmessage) {
		print BOLD, RED "$message", RESET, "\n";
	} else {
		print "$message\n";
	}
	return;
}

# states:
# $State_Uninstall - make sure not on system (Uninstall)
# $State_Install - install on system (Install/Upgrade/Re-Install)
# $State_UpToDate - leave as is on system (Installed/Up To Date)
# $State_DoNotInstall - leave as is not on system (Do Not Install)
sub printInstallAvailableState($$$$$$)
{
	my $installed = shift();
	my $available = shift();
	my $isupgrade = shift();
	my $state     = shift();
	my $boldmessage = shift();
	my $message   = shift();

	if ( $state == $State_Uninstall )
	{
		print RED, "[  Uninstall  ]", RESET;
	} elsif ( $state == $State_Install) {
		if ($installed)
		{           
			if ( $isupgrade ) 
			{       
				print GREEN, "[   Upgrade   ]", RESET;
			} else {
				print "[ Re-Install  ]";
			}
		} else {
			print           "[   Install   ]";
		}
	} elsif ($state == $State_UpToDate) {
		print "[ Up To Date  ]";
	} elsif ($state == $State_DoNotInstall) {
		print "[Don't Install]";
	}

	if ( $available )
	{
		print "[Available] ";
	} else {
		print BOLD, RED "[Not Avail] ", RESET;
	}
	if ("$message" ne "" && $boldmessage) {
		print BOLD, RED "$message", RESET, "\n";
	} else {
		print "$message\n";
	}

	return;
}

# =======================================================================
# Component processing

# indicate which main INSTALL is being used.  This can influence error checks
# and assumptions made by individual components
my $MainInstall = "";

# function must be supplied if any components set ComponentInfo{}{HasFirmware}
sub update_hca_firmware();

# these variables must be initialized by main program to control the
# data driven component menus and functions in this section
my $Default_Install=0;	# -a option used to select default install of All
my $Default_Upgrade=0;	# -U option used to select default upgrade of installed
my $Default_Uninstall=0;	# -u option used to select default uninstall of All
my $Default_SameAutostart=0; # -n option used to default install, preserving autostart values
my $Default_CompInstall=0;	# -i option used to select default install of Default_Components
my $Default_CompUninstall=0;	# -e option used to select default uninstall of Default_Components
my %Default_Components = ();		# components selected by -i or -e
my $Skip_FirmwareUpgrade=1;	# -f option used to select skipping firmware upgrade
my $Default_Autostart=0;	# -s option used to select default autostart of All
my $Default_DisableAutostart=0; # -D option used to select default disabling of autostart for Default_DisabledComponents
my %Default_DisabledComponents = ();		# components selected by -D
my $Default_EnableAutostart=0; # -E option used to select default enabling of autostart for Default_EnabledComponents
my %Default_EnabledComponents = ();		# components selected by -E

	# Names of supported install components
	# must be listed in depdency order such that prereqs appear 1st
my @Components = ();

# Sub components for autostart processing
my @SubComponents = ();

# components/subcomponents for autostart processing
my @AutostartComponents = ();

	# an additional "special" component which is always installed when
	# we install/upgrade anything and which is only uninstalled when everything
	# else has been uninstalled.  Typically this will be the opaconfig
	# file and related files absolutely required by it (such as wrapper_version)
my $WrapperComponent = "";

# This provides more detailed information about each Component in @Components
# since hashes are not retained in the order specified, we still need
# @Components and @SubComponents to control install and menu order
# Fields are as follows:
#	Name => full name of component/subcomponent for prompts
# 	DefaultInstall => default installation (State_DoNotInstall,
# 					  State_DoNotAutoInstall or State_Install)
#					  used only when available and ! installed
#	SrcDir => directory name within install media for component
#	DriverSubdir => directory within /lib/modules/$CUR_OS_VERSION/ to
#					install driver to.  Set to "" if no drivers in component
#					set to "." if no subdir
# 	PreReq => other components which are prereqs of a given
#				component/subcomponent
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	CoReq =>  other components which are coreqs of a given component
#				Note that CoReqs can also be listed as prereqs to provide
#				install verification as each component is installed,
#				however prereqs should only refer to items earlier in the list
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	Hidden => component should not be shown in menus/prompts
#			  used for hidden PreReq.  Hidden components can't HasStart
#			  nor HasFirmware
#	Disabled =>  components/subcomponents which are disabled from installation
#	HasStart =>  components/subcomponents which have autostart capability
#	DefaultStart =>  should autostart default to Enable (1) or Disable (0)
#				Not needed/ignored unless HasStart=1
# 	StartPreReq => other components/subcomponents which must be autostarted
#				before autostarting this component/subcomponent
#				Not needed/ignored unless HasStart=1
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	StartComponents => components/subcomponents with start for this component
#				if a component has a start script 
#				list the component as a subcomponent of itself
#	HasFirmware =>  components which need HCA firmware update after installed
#
# Note both Components and SubComponents are included in the list below.
# Components require all fields be supplied
# SubComponents only require the following fields:
#	Name, PreReq (should reference only components), HasStart, StartPreReq,
#	DefaultStart
my %ComponentInfo = ();
	# translate from startup script name to component/subcomponent name
my %StartupComponent = ();
	# has component been installed since last configured autostart
my %ComponentWasInstalled = ();

# constants for autostart functions $configure argument
my $Start_Unspecified=0;
my $Start_NoStart=1;
my $Start_Start=2;

sub ShowComponents()
{
	foreach my $comp ( @Components )
	{
		if (! $ComponentInfo{$comp}{'Hidden'}) {
			print " $comp";
		}
	}
	print "\n";
}

# return 1 if $comp has a prereq of $prereq, 0 otherwise
sub comp_has_prereq_of($$)
{
	my($comp) = shift();
	my($prereq) = shift();

	if ($ComponentInfo{$comp}{'PreReq'} =~ / $prereq /) {
		return 1;
	} else {
		return 0;
	}
}

# return 1 if $comp has a coreq of $coreq, 0 otherwise
sub comp_has_coreq_of($$)
{
	my($comp) = shift();
	my($coreq) = shift();

	if ($ComponentInfo{$comp}{'CoReq'} =~ / $coreq /) {
		return 1;
	} else {
		return 0;
	}
}

# return 1 if $comp has a prereq or coreq of $req, 0 otherwise
sub comp_has_req_of($$)
{
	my($comp) = shift();
	my($req) = shift();

	return (comp_has_prereq_of($comp, $req) || comp_has_coreq_of($comp, $req));
}
# return 1 if $comp has a prereq of $prereq, 0 otherwise
sub comp_has_startprereq_of($$)
{
	my($comp) = shift();
	my($prereq) = shift();

	if ($ComponentInfo{$comp}{'StartPreReq'} =~ / $prereq /) {
		return 1;
	} else {
		return 0;
	}
}

# for comp_is_available we specially handle the case of function not found
# in which case eval returns ""
# all other component functions against install media will have called
# comp_is_available first, so they need not be protected by this test
sub comp_is_available($)
{
	my $comp = shift();
	my $rc;

	if ($ComponentInfo{$comp}{'Disabled'}) {
		return 0;
	}
	$rc = eval "available_$comp()";
	if ( "$rc" eq "" ) {
		return 0;	# $comp not loaded
	} else {
		return $rc;
	}
}

# return version string for component on install media
# only valid if comp_is_available is TRUE
sub comp_media_version($)
{
	my $comp = shift();

	my $result = eval "media_version_$comp()";
	chomp $result;
	return $result;
}

# for comp_is_installed we specially handle the case of function not found
# in which case eval returns ""
# all other component functions against system itself will have called
# comp_is_installed first, so they need not be protected by this test
sub comp_is_installed($)
{
	my $comp = shift();
	my $rc;

	$rc = eval "installed_$comp()";
	if ( "$rc" eq "" ) {
		return 0;	# $comp not loaded
	} else {
		return $rc;
	}
}

# return version string for component on system
# only valid if comp_is_installed is TRUE
sub comp_installed_version($)
{
	my $comp = shift();

	my $result = eval "installed_version_$comp()";
	chomp $result;
	return $result;
}

# return TRUE if component is installed and up to date
# return FALSE if not installed, or not same version as media
# typically only called when component is available, returns
# FALSE if component not available
sub comp_is_uptodate($)
{
	my $comp = shift();

	# safety check
	if (! comp_is_available("$comp") ) {
		return 0;
	}
	if (! comp_is_installed("$comp")) {
		return 0;
	}
	# available and installed, compare versions
	return (comp_installed_version($comp) eq comp_media_version($comp));
}

# check if all prereqs of $comp have been installed
# returns: 1 - all ok, 0 - some prereqs missing
sub check_prereqs($)
{
	my($comp) = shift();

	foreach my $c ( @Components )
	{
		if (comp_has_prereq_of($comp, $c) && ! comp_is_installed("$c") )
		{
			NormalPrint "Unable to Install $ComponentInfo{$comp}{'Name'}, prereq $ComponentInfo{$c}{'Name'} not installed\n";
			HitKeyCont;
			return 0;
		}
	}
	return 1;
}

# build processing for the given component
# returns 0 on success, 1 on failure
# only valid if comp_is_available is TRUE
sub comp_build($$$$$)
{
	my $comp = shift();
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild

	LogPrint "Building $ComponentInfo{$comp}{'Name'} for $osver using '$build_temp'\n";
	return eval "build_$comp('$osver',$debug,'$build_temp',$force)";
}

# special hook for build processing for the given component within OFED build
# returns 1 if build should be done, 0 if not
# only valid for subset of components and if comp_is_available is TRUE
sub comp_ofed_need_build($$$$)
{
	my $comp = shift();
	my $osver = shift();
	my $force = shift();	# should we force build
	my $prompt = shift();	# should we prompt user about build

	return eval "ofed_need_build_$comp('$osver',$force,$prompt)";
}

# special hook for build processing for the given component within OFED build
# returns 0 on success, >0 on failure
# only valid for subset of components and if comp_is_available is TRUE
sub comp_ofed_check_build_dependencies($$)
{
	my $comp = shift();
	my $osver = shift();

	return eval "ofed_check_build_dependencies_$comp('$osver')";
}

# special hook for build processing for the given component within OFED build
# returns 0 on success, 1 on failure
# only valid for subset of components and if comp_is_available is TRUE
sub comp_ofed_build($$$$)
{
	my $comp = shift();
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build

	LogPrint "Building $ComponentInfo{$comp}{'Name'} for $osver using '$build_temp'\n";
	return eval "ofed_build_$comp('$osver',$debug,'$build_temp')";
}

# before preinstall determine if present settings will require all
# installed components to be reinstalled
# returns "all" if need to reinstall all UpToDate components
# returns "this" if need to reinstall this component even if up to date
# returns "no" if no need to reinstall this component even if up to date
# only valid if comp_is_available is TRUE
sub comp_need_reinstall($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return eval "need_reinstall_$comp('$install_list', '$installing_list')";
}

# check presence of OS prereqs for the given component
# returns 0 on success, 1 on failure
# only valid if comp_is_available is TRUE
# for backward compatibility with old comp.pl files
# we specially handle the case of function not found
# in which case eval returns ""
sub comp_check_os_prereqs($)
{
	my $comp = shift();
	my $rc;

	DebugPrint "Checking OS Prereqs for $ComponentInfo{$comp}{'Name'}\n";
	$rc = eval "check_os_prereqs_$comp()";
	DebugPrint "Done: rc='$rc'\n";
	if ( "$rc" eq "" ) {
		return 0;	# $comp not loaded
	} else {
		return $rc;
	}
}

# preinstall processing for the given component
# returns 0 on success, 1 on failure
# only valid if comp_is_available is TRUE
sub comp_preinstall($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return eval "preinstall_$comp('$install_list', '$installing_list')";
}

# install the given component
# only valid if comp_is_available is TRUE
sub comp_install($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	# sanity check, should not get here if false
	if (! comp_is_available($comp) ) {
		return;
	}
	print_separator;
	# this will catch failures in install of prereqs
	if (! check_prereqs($comp)) {
		return;
	}

	eval "install_$comp('$install_list', '$installing_list')";
}

# postinstall processing for the given component
# only valid if comp_is_available is TRUE
sub comp_postinstall($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	eval "postinstall_$comp('$install_list', '$installing_list')";
}

# uninstall the given component
# typically only called if comp_is_available is TRUE
# or comp_is_installed is TRUE
# however could be called when not available and not installed in which
# case could be an empty function, in which case we can simply ignore
# eval's "" return
sub comp_uninstall($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_separator;
	if ($ComponentInfo{$comp}{'HasStart'}) {
		disable_components(@{ $ComponentInfo{$comp}{'StartComponents'} });
	}
	eval "uninstall_$comp('$install_list', '$uninstalling_list')";
}

# start the given component now
# only valid if comp_is_installed is TRUE
sub comp_start($)
{
	my $comp = shift();

	eval "start_$comp()";
}

# stop the given component now
# can be called even if comp_is_installed is FALSE, in which case can be a noop
sub comp_stop($)
{
	my $comp = shift();

	eval "stop_$comp()";
}

# determine if the given component is configured for Autostart at boot
sub comp_IsAutostart2($)
{
	my $comp = shift();

	return eval "IsAutostart2_$comp()";
}
# get autostart desc for the given component
sub comp_autostart_desc($)
{
	my $comp = shift();

	my $desc = eval "autostart_desc_$comp()";
	if ( "$desc" eq "" ) {
		$desc = $ComponentInfo{$comp}{'Name'};
	}
	return $desc;
}
# enable autostart for the given component
sub comp_enable_autostart2($$)
{
	my $comp = shift();
	my $quiet = shift();

	if ( ! comp_IsAutostart2($comp) == 1 )
	{
		if (! $quiet) {
			my $desc = comp_autostart_desc($comp);
			NormalPrint "Enabling autostart for $desc\n";
		}
	}
	eval "enable_autostart2_$comp()";
}
# disable autostart for the given component
sub comp_disable_autostart2($$)
{
	my $comp = shift();
	my $quiet = shift();

	if ( comp_IsAutostart2($comp) == 1 )
	{
		if (! $quiet) {
			my $desc = comp_autostart_desc($comp);
			NormalPrint "Disabling autostart for $desc\n";
		}
	}

	eval "disable_autostart2_$comp()";
}

sub DumpComponents($)
{
	my $allow_install = shift();

	if (! DebugPrintEnabled() ) {
		return;
	}
	DebugPrint("\nComponents:\n");
	foreach my $comp ( @Components ) {
		DebugPrint("   $comp: '$ComponentInfo{$comp}{'Name'}' SrcDir: $ComponentInfo{$comp}{'SrcDir'}\n");
		DebugPrint("           DefaultInstall: ".InstallStateToStr($ComponentInfo{$comp}{'DefaultInstall'})." DriverSubdir: $ComponentInfo{$comp}{'DriverSubdir'}\n");
		DebugPrint("           PreReq: $ComponentInfo{$comp}{'PreReq'} CoReq: $ComponentInfo{$comp}{'CoReq'}\n");
		DebugPrint("           Hidden: $ComponentInfo{$comp}{'Hidden'} HasStart: $ComponentInfo{$comp}{'HasStart'} HasFirmware: $ComponentInfo{$comp}{'HasFirmware'}\n");
		DebugPrint("           StartPreReq: $ComponentInfo{$comp}{'StartPreReq'} StartComponents: $ComponentInfo{$comp}{'StartComponents'}\n");
		if ($allow_install) {
			my $avail = comp_is_available($comp);
			DebugPrint("           IsAvailable: $avail");
			if ($avail) {
				DebugPrint("           MediaVersion: ".comp_media_version($comp));
			}
			DebugPrint("\n");
		}
		my $installed = comp_is_installed($comp);
		DebugPrint("           IsInstalled: $installed");
		if ($installed) {
			DebugPrint("           InstalledVersion: ".comp_installed_version($comp));
		}
		DebugPrint("\n");
	}

	DebugPrint("\nSubComponents:\n");
	foreach my $comp ( @SubComponents ) {
		DebugPrint("   $comp: '$ComponentInfo{$comp}{'Name'}'\n");
		DebugPrint("           PreReq: $ComponentInfo{$comp}{'PreReq'} CoReq: $ComponentInfo{$comp}{'CoReq'}\n");
		DebugPrint("           HasStart: $ComponentInfo{$comp}{'HasStart'}\n");
		DebugPrint("           StartPreReq: $ComponentInfo{$comp}{'StartPreReq'}\n");
	}
}

# make sure every component is stopped
sub stop_all_components()
{
	my $comp;
	my $i;

	if ( ROOT_is_set() )
	{
		return;
	}
	print_separator;
	print "Stopping loaded drivers...\n";
	# perform the stop, work backwards through list
	for ($i=scalar(@Components)-1; $i >= 0; $i--)
	{
		$comp = $Components[$i];
		if ( $ComponentInfo{$comp}{'HasStart'} )
		{
			comp_stop($comp);
		}
	}
}


# build @AutostartComponents listing all components and subcomponents which
# have autostart capability.  They are listed in prefered startup order
sub build_autostart_components_list()
{
	my $comp;
	# only need to do once
	if (scalar(@AutostartComponents) != 0 ) {
		return;
	}
	foreach $comp ( @Components )
	{
		if ( $ComponentInfo{$comp}{'HasStart'} )
		{
			# StartComponents will list Components and SubComponents which
			# have start capability
			@AutostartComponents = ( @AutostartComponents, @{ $ComponentInfo{$comp}{'StartComponents'} })
		}
	}
}

# disable autostart for a list of components and
# all components dependent on given component
sub disable_components(@)
{
	my @disabled = ( @_ );
	my %need_disable = ();
	my %dont_need_disable = ();
	my $comp;

	build_autostart_components_list;
	foreach $comp ( @disabled ) {
		$need_disable{$comp} = 1;
		DebugPrint("disable $comp explicitly\n");
	}
	my $done = 0;
	while ( ! $done) {
		$done=1;
		foreach $comp ( @disabled ) {
			# comp will be disabled, any which depend on it as a
			# startprereqs will also be disabled
			foreach my $c ( @AutostartComponents ) {
				if (comp_has_startprereq_of($c, $comp)
					&& ! $need_disable{$c} && ! $dont_need_disable{$c} ) {
					if (comp_is_installed("$c") ) {
						@disabled = ( @disabled, $c );
						$need_disable{$c}=1;
						DebugPrint("also disable $c\n");
						$done=0;
					} else {
						$dont_need_disable{$c}=1;
						DebugPrint("no need to disable $c\n");
					}
				}
			}
		}
	}
	foreach $comp ( reverse(@AutostartComponents) ) {
		foreach my $c ( @disabled ) {
			if ( "$comp" eq "$c" ) {
				DebugPrint("invoke disable $c\n");
				comp_disable_autostart2($c,0);
			}
		}
	}
}

# enable autostart for a list of components and
# all components they depend on
sub enable_components(@)
{
	my @enabled = ( @_ );
	my %need_enable = ();
	my $comp;

	build_autostart_components_list;
	foreach $comp ( @enabled ) {
		$need_enable{$comp} = 1;
		DebugPrint("enable $comp explicitly\n");
	}
	my $done = 0;
	while ( ! $done) {
		$done=1;
		foreach $comp ( @enabled ) {
			# comp will be enabled, make sure all its
			# startprereqs will also be enabled
			foreach my $c ( @AutostartComponents ) {
				if (comp_has_startprereq_of($comp, $c) && ! $need_enable{$c} ) {
					DebugPrint("also enable $c\n");
					@enabled = ( $c, @enabled );
					$need_enable{$c}=1;
					$done=0;
				}
			}
		}
	}
	foreach $comp ( @AutostartComponents ) {
		foreach my $c ( @enabled ) {
			if ( "$comp" eq "$c" ) {
				DebugPrint("invoke enable $c\n");
				comp_enable_autostart2($c,0);
			}
		}
	}
}

sub install_startup($$$)
{
	my($srcdir) = shift();
	my($WhichStartup) = shift();
	my($StartupDesc) = shift();
	my $prompt;
	my $res;

	if ( "$StartupDesc" eq "" )
	{
		$prompt="$WhichStartup";
	} else {
		$prompt="$StartupDesc ($WhichStartup)";
	}
	print "Creating $prompt system startup files...\n";
	check_dir("$INIT_DIR");
	if ( -e "$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR.$CUR_VENDOR_VER" ) {
		copy_file("$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR.$CUR_VENDOR_VER", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} elsif ( -e "$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR.$CUR_VENDOR_MAJOR_VER" ) {
		copy_file("$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR.$CUR_VENDOR_MAJOR_VER", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} elsif ( -e "$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR" )
	{
		copy_file("$srcdir/$WhichStartup.$CUR_DISTRO_VENDOR", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} elsif ( -e "$srcdir/init_$WhichStartup.$CUR_DISTRO_VENDOR" ) {
		copy_file("$srcdir/init_$WhichStartup.$CUR_DISTRO_VENDOR", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} elsif ( -e "$srcdir/$WhichStartup" )
	{
		copy_file("$srcdir/$WhichStartup", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} elsif ( -e "$srcdir/init_$WhichStartup" ) {
		copy_file("$srcdir/init_$WhichStartup", "$INIT_DIR/$WhichStartup",
					"$OWNER", "$GROUP", "ugo=rx,u=rwx");
	} else {
		NormalPrint "$prompt system startup file not found\n";
	}
	
	if ( ! $Default_SameAutostart )
	{
		disable_autostart($WhichStartup);
	} else {
		if ( IsAutostart($WhichStartup) == 1 )
		{
			enable_autostart($WhichStartup);
		} else {
			disable_autostart($WhichStartup);
		}
	}     
}

# run build for all components
sub build_all_components($$$$)
{
	my $osver = shift();	# Kernel OS Version to build for
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a full rebuild

	my $comp;
	my $ret = 0;

	foreach $comp ( @Components )
	{
		my $rc = comp_build($comp,$osver,$debug,$build_temp,$force);
		if (0 != $rc) {
			NormalPrint "Unable to Build $ComponentInfo{$comp}{'Name'}\n";
		}
		$ret |= $rc;
	}
	return $ret;
}

sub count_hidden_comps()
{
	my $i;
	my $ret=0;

	for($i=0; $i < scalar(@Components); $i++)
	{
		my $comp = $Components[$i];
		if ($ComponentInfo{$comp}{'Hidden'}) {
			$ret++;
		}
	}
	return $ret;
}

# convert a screen selection into a Components subscript, accounting for Hidden
sub get_comp_subscript($$$)
{
	my $firstline=shift();
	my $maxlines=shift();
	my $selection=shift();
	my $index=0;
	my $i;

	for ($i=0; $i < scalar(@Components); $i++)
	{
		my $comp = $Components[$i];
		if ($index >= $firstline && $index < $firstline+$maxlines) {
			if (! $ComponentInfo{$comp}{'Hidden'}) {
				if ($index - $firstline == $selection) {
					return $i;
				}
				$index++;
			}
		} else {
			if (! $ComponentInfo{$comp}{'Hidden'}) {
				$index++;
			}
		}
	}
	return $i	# invalid entry return 1 past number of Components
}

sub show_install_menu($)
{
	my $showversion = shift();	# should per comp versions be shown

	my $inp;
	my %available = ();
	my %installed = ();
	my %installed_version = ();
	my %media_version = ();
	my %isupgrade = ();
	my %installState = ();
	my %statusMessage = ();
	my %boldMessage = ();
	my $comp;
	my $i;
	my $newstate = $State_Uninstall;	# most recent state change for a comp
	my $firstline = 0;
	my $maxlines=14;
	my $num_hidden_comps = count_hidden_comps();

	print "Determining what is installed on system...\n";
	DumpComponents(1);
	foreach $comp ( @Components )
	{
		$available{$comp} = comp_is_available("$comp");
		$installed{$comp} = comp_is_installed("$comp");
		if ( $available{$comp} ) {
			$media_version{$comp} = comp_media_version($comp);
		} else {
			$media_version{$comp} = "";
		}
		if ( $installed{$comp} ) {
			$installed_version{$comp} = comp_installed_version($comp);
			$isupgrade{$comp}= ($installed_version{$comp} ne $media_version{$comp});
		} else {
			$installed_version{$comp} = "";
			$isupgrade{$comp}=1;
		}
		$installState{$comp}= setstate($installed{$comp}, $available{$comp},
							$isupgrade{$comp}, $ComponentInfo{$comp}{'DefaultInstall'});
	}
	# to avoid a subtle effect, mark as not available any items whose
	# coreqs are not available.  Such packagings should not
	# occur, but better to be safe
	foreach $comp ( @Components )
	{
		if (! $available{$comp}) {
			foreach my $c ( @Components )
			{
				if (comp_has_coreq_of($c, $comp) && $available{$c}) {
					$available{$c}=0;
				}
			}
		}
	}

DO_INS:
	if ( $Default_Install) {	
		# setstate set UnInstall or DoNotInstall for those not available
		# force install for all available even if UpToDate
		# or ComponentInfo{comp}{'DefaultInstall'} is DoNotInstall
		foreach $comp ( @Components )
		{
			if ($available{$comp}
				&& ($installState{$comp} != $State_DoNotInstall
					|| $ComponentInfo{$comp}{'DefaultInstall'} != $State_DoNotAutoInstall)) {
				$installState{$comp} = $State_Install;
			}
		}
		$newstate = $State_Install;
		$inp='P';
	} elsif ( $Default_Upgrade) {	
		foreach $comp ( @Components )
		{
			if ( $installed{$comp} )
			{
				if ( $available{$comp} )
				{
					$installState{$comp} = $State_Install;
				} elsif ( ! $isupgrade{$comp} ) {
					$installState{$comp} = $State_UpToDate;
				} else {
					$installState{$comp} = $State_Uninstall; # we must uninstall
				}
			} else {
				$installState{$comp} = $State_DoNotInstall;
			}
		}
		$newstate = $State_Install;
		$inp='P';
	} elsif ( $Default_CompInstall) {
		foreach $comp ( @Components )
		{
			if ( $Default_Components{$comp} )
			{
				if ( $available{$comp} )
				{
					$installState{$comp} = $State_Install;
				} else {
					NormalPrint "Unable to install $ComponentInfo{$comp}{'Name'}, Not Available\n";
					# setstate provided a reasonable default action
				}
			} else {
				# setstate defaulted to install all available and not installed
				# for version updates re-install to be safe
				if ( $installState{$comp} == $State_Install 
					&& ( ! $installed{$comp} || ! $isupgrade{$comp} ) )
				{
					# Do Not Install
					$installState{$comp} = $State_DoNotInstall;
				}
			}
		}
		$newstate = $State_Install;
		$inp='P';
	} else {
		system "clear";        
		printf ("$BRAND OPA Install ($VERSION $DBG_FREE) Menu\n\n");
		my $screens = int((scalar(@Components) - $num_hidden_comps + $maxlines-1)/$maxlines);
		if ($screens > 1 ) {
			printf ("Please Select Install Action (screen %d of $screens):\n",
						$firstline/$maxlines+1);
		} else {
			printf ("Please Select Install Action:\n");
		}
		my $index=0;
		for ($i=0; $i < scalar(@Components); $i++)
		{
			$comp = $Components[$i];
			if ($index >= $firstline && $index < $firstline+$maxlines) {
				if ($showversion && "$statusMessage{$comp}" eq "") {
					if ($available{$comp}) {
						$statusMessage{$comp} = $media_version{$comp};
						$boldMessage{$comp} = 0;
					} elsif($installed{$comp}) {
						$statusMessage{$comp} = $installed_version{$comp};
						$boldMessage{$comp} = 0;
					}
				}
				if (! $ComponentInfo{$comp}{'Hidden'}) {
					printf ("%x) %-20s", $index-$firstline, $ComponentInfo{$comp}{'Name'});
					printInstallAvailableState($installed{$comp},
									$available{$comp},
									$isupgrade{$comp},
 									$installState{$comp},
									$boldMessage{$comp}, $statusMessage{$comp});
					$index++;
				}
			} elsif (! $ComponentInfo{$comp}{'Hidden'}) {
				$index++;
			}
		}
		
		printf ("\n");
		if ($screens > 1 ) {
			printf ("N) Next Screen\n");
		}
		printf (  "P) Perform the selected actions       I) Install All\n");
		printf (  "R) Re-Install All                     U) Uninstall All\n");
		printf (  "X) Return to Previous Menu (or ESC)\n");	

		$inp = getch();                
	        
		if ($inp =~ /[qQ]/ || $inp =~ /[xX]/ || ord($inp) == $KEY_ESC ) 
		{
			return;
		}

		# do not clear status messages when jump between screens
		if ($inp !~ /[nN]/ ) {
			%statusMessage = ();
			%boldMessage = ();
		}

	}

	if ($inp =~ /[nN]/ )
	{
		if (scalar(@Components) > $maxlines) {
			$firstline += $maxlines;
			if ($firstline >= scalar(@Components)) {
				$firstline=0;
			}
		}
	} elsif ($inp =~ /[rR]/ )
	{
		foreach $comp ( @Components )
		{
			if ( $installed{$comp} && $available{$comp}) {
				$installState{$comp} = $State_Install;
			}
		}
	} elsif ($inp =~ /[iI]/ )
	{
		foreach $comp ( @Components )
		{
			if ( $available{$comp} ) {
				$installState{$comp} = $State_Install;
			}
		}
		$newstate = $State_Install;
	} elsif ($inp =~ /[uU]/ )
	{
		foreach $comp ( @Components )
		{
			$installState{$comp} = $State_Uninstall;
		}
		$newstate = $State_Uninstall;
	} elsif ($inp =~ /[0123456789abcdefABCDEF]/) {
		my $value = hex($inp);
		my $index = get_comp_subscript($firstline, $maxlines, $value);
		if ( $value < $maxlines && $index < scalar(@Components)) {
			my $selected = $Components[$index];
			$installState{$selected} = shiftstate($installState{$selected},$installed{$selected},$available{$selected},$isupgrade{$selected});
			$newstate = $installState{$selected};
		}
	}

	if (! will_be_on_system($newstate)) {
		# something is being uninstalled or not installed
		# loop through a few times to catch all coreqs, prereqs
		# and coreqs of prereqs
		my $done = 0;	# we are done if we loop through with no changes
		while (! $done) {
			$done=1;
			foreach $comp ( @Components )
			{
				if (! will_be_on_system($installState{$comp})) {
					# comp will not be on system, make sure all its
					# pre/coreqs will also not be on system
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($c, $comp)
							&& will_be_on_system($installState{$c})) {
							$statusMessage{$c}="requires $ComponentInfo{$comp}{'Name'}";
							$boldMessage{$c}=1;
							$installState{$c}=$installed{$c}?$State_Uninstall:$State_DoNotInstall;
							$done=0;
						}
					}
				}
				if ($ComponentInfo{$comp}{'Hidden'}) {
					# if no longer needed, also remove it
					my $needed = 0;	# is $comp needed
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($c, $comp)
							&& will_be_on_system($installState{$c})) {
							$needed=1;
						}
					}
					if (! $needed && will_be_on_system($installState{$comp})) {
						$installState{$comp}=$installed{$comp}?$State_Uninstall:$State_DoNotInstall;
						$done=0;
					}
				}
			}
		}
	} elsif (will_be_on_system($newstate)) {
		# something is being installed or left on system
		# loop through a few times to catch all coreqs, prereqs
		# and coreqs of prereqs
		my $done = 0;	# we are done if we loop through with no changes
		my $forcedone = 0;	# used to break infinite loop in subtle issue below
		while (! $forcedone && ! $done) {
			$done=1;
			foreach $comp ( @Components )
			{
				if (will_be_on_system($installState{$comp})) {
					# comp will be on system, make sure all its
					# pre/coreqs will also be on system
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($comp, $c)
							&& ! will_be_on_system($installState{$c})) {
							if (! $available{$c} ) {
								# pre/coreq $c not available, can't install comp
								$statusMessage{$comp}="requires $ComponentInfo{$c}{'Name'}";
								$boldMessage{$comp}=1;
								$installState{$comp}=$installed{$comp}?$State_Uninstall:$State_DoNotInstall;
								# this should not occur for coreqs
								# however there are subtle effects here.
								# If we install an item which has a prereq
								# whose prereq is not available we could get
								# stuck with an invalid combination since we
								# will have marked the 1st prereq installed,
								# found the 2nd prereq problem
								# unmarked the 1st prereq but still have
								# left the original item to be installed
								# bail to avoid infinite loop
								$forcedone=1;
								last;
							} else {
								# also install $c
								$statusMessage{$c}="needed by $ComponentInfo{$comp}{'Name'}";
								$boldMessage{$c}=1;
								$installState{$c}=$State_Install;
							}
							$done=0;
						}
					}
				}
				if ($ComponentInfo{$comp}{'Hidden'} && $available{$comp}
					&& will_be_on_system($installState{$comp})) {
					# if all prereqs being reinstalled also reinstall it
					my $reinstall = 1;	# no already installed dependents
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($c, $comp)
							&& will_be_on_system($installState{$c})
							&& $installState{$c} != $State_Install) {
							$reinstall=0;
						}
					}
					if ($reinstall) {
						$installState{$comp}=$State_Install;
						# no need to force another loop, didn't change
						# will_be_on_system($comp)
					}
				}
			}
		}
	}

	if ($inp =~ /[pP]/) {
		# perform the install
		my $updateFirmware=0;

		# build a list of what will be installed after installation completes
		# use a space separate string so easier to pass and can be "grep'ed"
		my $install_list = "";
		my $installing_list = "";
		my $uninstalling_list = "";
		my $have_some_uptodate = 0;
		foreach $comp ( @Components )
		{
			if ($installState{$comp} == $State_UpToDate) {
				$have_some_uptodate = 1;
			}
			if ($installState{$comp} == $State_Install
				|| $installState{$comp} == $State_UpToDate) {
				$install_list .= " $comp ";
			}
			if ($installState{$comp} == $State_Install) {
				$installing_list .= " $comp ";
			}
			if ($installState{$comp} == $State_Uninstall) {
				$uninstalling_list .= " $comp ";
			}
		}

		# first uninstall what will be removed, do this in reverse order
		# so dependency issues are avoided
		foreach $comp ( reverse(@Components) ) {
			if ($installState{$comp} == $State_Uninstall) {
				comp_uninstall($comp, $install_list, $uninstalling_list);
				$installed{$comp} = 0;
			}
		}
		if ( "$WrapperComponent" ne "" && "$installing_list" eq "" && "$install_list" eq "" ) {
			comp_uninstall($WrapperComponent, $install_list, $uninstalling_list);
		}

		if ($have_some_uptodate ) {
			# determine if some up to date components need to be reinstalled
			# for example due to a change in install prefix, install options ...
			# to determine this run need_reinstall for all components which
			# will be installed or are up to date.  Net result is we may change
			# some or all components in State_UpToDate to State_Install

			my $need_reinstall_all = 0;
			my $need_reinstall_some = 0;
			foreach $comp ( @Components )
			{
				if (($installState{$comp} == $State_Install
						|| $installState{$comp} == $State_UpToDate)
					&& $available{$comp} ) {
					my $reins = comp_need_reinstall($comp,$install_list,$installing_list);
					if ("$reins" eq "all") {
						VerbosePrint("$comp needs reinstall all\n");
						$need_reinstall_all = 1;
						last;
					} elsif ("$reins" eq "this") {
						if ($installState{$comp} == $State_UpToDate
							&& $available{$comp} ) {
							VerbosePrint("$comp needs reinstall\n");
							$installState{$comp} = $State_Install;
							$need_reinstall_some = 1;
						}
					}
				}
			}
			if ($need_reinstall_all || $need_reinstall_some) {
				if ($need_reinstall_all) {
					NormalPrint "INSTALL options require Reinstall of all UpToDate Components\n";
				} else {
					NormalPrint "Reinstall of some UpToDate Components is Required\n";
				}
				$installing_list  = "";	# recompute
				foreach $comp ( @Components )
				{
					if ($need_reinstall_all
						&& $installState{$comp} == $State_UpToDate
						&& $available{$comp} ) {
						$installState{$comp} = $State_Install;
					}
					if ($installState{$comp} == $State_Install) {
						$installing_list .= " $comp ";
					}
				}
			}
		}
		# check OS pre-reqs for all components which will be installed
		my $have_all_os_prereqs=1;
		foreach $comp ( @Components )
		{
			if ($installState{$comp} == $State_Install) {
				if (0 != comp_check_os_prereqs($comp)) {
					$have_all_os_prereqs=0;
					NormalPrint "Lacking OS Prereqs for $ComponentInfo{$comp}{'Name'}\n";
				}
			}
		}
		if (! $have_all_os_prereqs) {
			HitKeyCont;
			goto DONE;
		}

		# run pre-install for all components which will be installed
		# Reverse the order to avoid dependency issues
		foreach $comp ( reverse(@Components) )
		{
			if ($installState{$comp} == $State_Install) {
				if (0 != comp_preinstall($comp,$install_list,$installing_list)) {
					NormalPrint "Unable to Prepare $ComponentInfo{$comp}{'Name'} for Install\n";
					HitKeyCont;
					goto DONE;
				}
			}
		}

		# Now install components
		if ( "$WrapperComponent" ne "" && "$installing_list" ne "" ) {
			comp_install($WrapperComponent, $install_list, $installing_list);
		}
		foreach $comp ( @Components )
		{
			if ($installState{$comp} == $State_Install) {
				comp_install($comp, $install_list, $installing_list);
				if ( $ComponentInfo{$comp}{'HasFirmware'} ) {
					$updateFirmware=1;
				}
			}
		}

		# run post-install for all components which were installed
		foreach $comp ( @Components )
		{
			if ($installState{$comp} == $State_Install) {
				comp_postinstall($comp, $install_list, $installing_list);
			}
		}

		%installed = ();
		if ( $Default_Prompt ) {
			foreach $comp ( @Components )
			{
				$installed{$comp} = 0;
			}
			# limit autostart to newly installed components with a
			# default start.  Also include their start prereqs.
			# Note start prereqs are all inclusive, so we don't need to
			# find prereqs of prereqs
			foreach $comp ( @Components )
			{
				if ($installState{$comp} == $State_Install
					&& $ComponentInfo{$comp}{'HasStart'}
					&& ($Default_SameAutostart
						|| $ComponentInfo{$comp}{'DefaultStart'}) ) {
					$installed{$comp} = 1;
					foreach my $c ( @Components ) {
						if (comp_has_startprereq_of($comp, $c)) {
							$installed{$c} = 1;
						}
					}
				}
			}
		} else {
			foreach $comp ( @Components )
			{
				if ($installState{$comp} == $State_Install
					|| $installState{$comp} == $State_UpToDate) {
					$installed{$comp} = 1;
				} else {
					$installed{$comp} = 0;
				}
			}
		}
		show_autostart_menu(0, %installed);

#		if ( $updateFirmware && ! $Skip_FirmwareUpgrade ) {
#			update_hca_firmware;
#		}

		# show_autostart_menu unconditionally requested user hit return,
		# update_hca_firmware will also as needed, so only request return below
		# if one of these functions does something.
		# component_start_prompts if it does anything will also request a return
		my $need_ret = 0;
		$need_ret |= check_depmod;
		$need_ret |= check_ldconfig;
		if (component_start_prompts) {
			$need_ret=0;
		}
		$need_ret |= check_need_reboot;
		if ($need_ret) {
			HitKeyCont;
		}
		return;
	}

	# we had an error above
DONE:
	if ( ! $Default_Prompt ) {
		goto DO_INS;
	}
	$exit_code = 1;
}

sub show_installed($)
{
	my $showversion = shift();	# should per comp versions be shown

	my %installed = ();
	my %statusMessage = ();
	my $comp;
	my $i;

	system "clear";
	printf ("$BRAND OPA Installed Software ($VERSION)\n\n");
	my $index=0;
	for ($i=0; $i < scalar(@Components); $i++)
	{
		if ($index > 0 && ($index % 20 == 0) ) {
			HitKeyCont;
		}
		$comp = $Components[$i];
		$installed{$comp} = comp_is_installed("$comp");
		if ( $showversion && $installed{$comp} ) {
			$statusMessage{$comp} = comp_installed_version($comp);
		}
		if (! $ComponentInfo{$comp}{'Hidden'}) {
			printf ("   %-20s ", $ComponentInfo{$comp}{'Name'});
			printInstallState($installed{$comp}, 0, 0, "$statusMessage{$comp}");
			$index++;
		}
	}
	HitKeyCont;
}

sub show_uninstall_menu($)
{
	my $showversion = shift();	# should per comp versions be shown

	my %installed = ();
	my %installed_version = ();
	my %installState = ();
	my %statusMessage = ();
	my %boldMessage = ();
	my $inp;
	my $comp;
	my $i;
	my $newstate;	# most recent state change for a comp
	my $firstline = 0;
	my $maxlines=14;
	my $num_hidden_comps = count_hidden_comps();

	print "Determining what is installed on system...\n";
	DumpComponents(0);
	foreach $comp ( @Components )
	{
		$installed{$comp} = comp_is_installed("$comp");
		if ($installed{$comp}) {
			$installed_version{$comp} = comp_installed_version("$comp");
		}
		$installState{$comp}= setstate($installed{$comp},0,0,$State_DoNotInstall);
	}
DO_UNINS:
	if ( $Default_Uninstall) {
		foreach $comp ( @Components )
		{
			$installState{$comp} = $State_Uninstall;
		}
		$newstate = $State_Uninstall;
		$inp="P";
	} elsif ( $Default_CompUninstall) {
		foreach $comp ( @Components )
		{
			if ( $Default_Components{$comp} )
			{
				$installState{$comp} = $State_Uninstall;
			}
		}
		$newstate = $State_Uninstall;
		$inp="P";
	} else {
		system "clear";
		printf ("$BRAND OPA Uninstall Menu ($VERSION)\n\n");
		my $screens = int((scalar(@Components)-$num_hidden_comps + $maxlines-1)/$maxlines);
		if ($screens > 1 ) {
			printf ("Please Select Uninstall Action (screen %d of $screens):\n",
						$firstline/$maxlines+1);
		} else {
			printf ("Please Select Uninstall Action:\n");
		}
		my $index=0;
		for($i=0; $i < scalar(@Components); $i++)
		{
			$comp = $Components[$i];
			if ($index >= $firstline && $index < $firstline+$maxlines) {
				if ($showversion && "$statusMessage{$comp}" eq ""
					&& $installed{$comp}) {
					$statusMessage{$comp} = $installed_version{$comp};
					$boldMessage{$comp} = 0;
				}
				if (! $ComponentInfo{$comp}{'Hidden'}) {
					printf ("%x) %-20s ", $index-$firstline, $ComponentInfo{$comp}{'Name'});
					printInstallState($installed{$comp}, ($installState{$comp} == $State_Uninstall),
						$boldMessage{$comp}, $statusMessage{$comp});
					$index++;
				}
			} elsif (! $ComponentInfo{$comp}{'Hidden'}) {
				$index++;
			}
		}

		printf ("\n");
		if ($screens > 1 ) {
			printf ("N) Next Screen\n");
		}
		printf (  "P) Perform the selected actions\n");
		printf (  "U) Uninstall All\n");
		printf (  "X) Return to Previous Menu (or ESC)\n");
			

		$inp = getch();
	
		if ($inp =~ /[qQ]/ || $inp =~ /[xX]/ || ord($inp) == $KEY_ESC)
		{
			return;
		}

		# do not clear status messages when jump between screens
		if ($inp !~ /[nN]/ )
		{
			%statusMessage = ();
			%boldMessage = ();
		}
	}

	if ($inp =~ /[nN]/ )
	{
		if (scalar(@Components) > $maxlines) {
			$firstline += $maxlines;
			if ($firstline >= scalar(@Components)) {
				$firstline=0;
			}
		}
	} elsif ($inp =~ /[uU]/ )
	{
		foreach $comp ( @Components )
		{
			$installState{$comp} = $State_Uninstall;
		}
		$newstate = $State_Uninstall;
	}
	elsif ($inp =~ /[0123456789abcdefABCDEF]/)
	{
		my $value = hex($inp);
		my $index = get_comp_subscript($firstline, $maxlines, $value);
		if ( $value < $maxlines && $index < scalar(@Components)) {
			my $selected = $Components[$index];
			$installState{$selected} = shiftstate($installState{$selected},$installed{$selected},0,0);
			$newstate = $installState{$selected};
		}
	}

	if (! will_be_on_system($newstate)) {
		my $done = 0;	# we are done if we loop through with no changes
		# something is being uninstalled or not installed
		# loop through a few times to catch all coreqs, prereqs
		# and coreqs of prereqs
		while (! $done) {
			$done=1;
			foreach $comp ( @Components )
			{
				if (! will_be_on_system($installState{$comp})) {
					# comp will not be on system, make sure all its
					# pre/coreqs will also not be on system
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($c, $comp)
							&& will_be_on_system($installState{$c})) {
							$statusMessage{$c}="requires $ComponentInfo{$comp}{'Name'}";
							$boldMessage{$c}=1;
							$installState{$c}=$installed{$c}?$State_Uninstall:$State_DoNotInstall;
							$done=0;
						}
					}
				}
				if ($ComponentInfo{$comp}{'Hidden'}) {
					# if no longer needed, also remove it
					my $needed = 0;	# is $comp needed
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($c, $comp)
							&& will_be_on_system($installState{$c})) {
							$needed=1;
						}
					}
					if (! $needed && will_be_on_system($installState{$comp})) {
						$installState{$comp}=$installed{$comp}?$State_Uninstall:$State_DoNotInstall;
						$done=0;
					}
				}
			}
		}
	} elsif (will_be_on_system($newstate)) {
		# something is being left on system
		# loop through a few times to catch all coreqs, prereqs
		# and coreqs of prereqs
		my $done = 0;	# we are done if we loop through with no changes
		my $forcedone = 0;	# used to force infinite loop in subtle issue below
		while (! $forcedone && ! $done) {
			$done=1;
			foreach $comp ( @Components )
			{
				if (will_be_on_system($installState{$comp})) {
					# comp will be on system, make sure all its
					# pre/coreqs will also be on system
					foreach my $c ( @Components )
					{
						if (comp_has_req_of($comp, $c)
							&& ! will_be_on_system($installState{$c})) {
							if (! $installed{$c} ) {
								# pre/coreq $c not installed, can't keep comp
								# this is not expected to occur, but is
								# a safety net for corrupted systems
								$statusMessage{$comp}="requires $ComponentInfo{$c}{'Name'}";
								$boldMessage{$comp}=1;
								$installState{$comp}=$installed{$comp}?$State_Uninstall:$State_DoNotInstall;
								# bail to avoid infinite loop, especially
								# for prereq chains and missing coreqs
								# see install_menu discussion for a similar
								# related issue
								$forcedone=1;
								last;
							} else {
								# also install $c
								$statusMessage{$c}="needed by $ComponentInfo{$comp}{'Name'}";
								$boldMessage{$c}=1;
								$installState{$c}=$State_Install;
							}
							$done=0;
						}
					}
				}
			}
		}
	}

	if ($inp =~ /[pP]/)
	{
		# build a list of what will be installed after installation completes
		# use a space separate string so easier to pass and can be "grep'ed"
		my $install_list = "";
		my $uninstalling_list = "";
		foreach $comp ( @Components )
		{
			if ($installState{$comp} == $State_Install
				|| $installState{$comp} == $State_UpToDate) {
				$install_list .= " $comp ";
			}
			if ($installState{$comp} == $State_Uninstall) {
				$uninstalling_list .= " $comp ";
			}
		}

		# perform the uninstall, work backwards through list
		foreach $comp ( reverse(@Components) )
		{
			if ($installState{$comp} == $State_Uninstall)
			{
				comp_uninstall($comp, $install_list, $uninstalling_list);
				$installed{$comp} = 0;
			}
		}
		if ( "$WrapperComponent" ne "" && "$install_list" eq "" ) {
			comp_uninstall($WrapperComponent, $install_list, $uninstalling_list);
		}
		# since we did an uninstall should request a return
		my $need_ret = 1;
		$need_ret |= check_depmod;
		$need_ret |= check_ldconfig;
		$need_ret |= check_need_reboot;
		if ($need_ret) {
			HitKeyCont;
		}
		return;
	}

	if ( ! $Default_Prompt ) {
		goto DO_UNINS;
	}
}

sub reconfig_autostart()
{
	my %installed = ();
	my $comp;

	build_autostart_components_list;
	foreach $comp ( @Components ) {
		$installed{$comp} = comp_is_installed("$comp");
		DebugPrint("installed($comp)=$installed{$comp}\n");
		# fill in subcomponents to simplify tests for Default_*Components below
		# if show_autostart_menu is called, it will ignore these extra entries
		foreach my $c ( @{ $ComponentInfo{$comp}{'StartComponents'} }) {
			$installed{$c} = $installed{$comp};
		}
	}
	if (! $Default_Autostart) {
		# interactive menu, use previous value as default
		show_autostart_menu(1, %installed);
	} else {
		if ( $Default_DisableAutostart) {
			# build list of components/subcomponents to disable
			my @disabled = ();
			foreach $comp ( @AutostartComponents ) {
				if ( $installed{$comp} ) {
					if ($Default_DisabledComponents{$comp}) {
						@disabled = ( @disabled, $comp );
					}
				}
			}
			disable_components(@disabled);
		}
		if ( $Default_EnableAutostart) {
			# build list of components/subcomponents to enable
			my @enabled = ();
			foreach $comp ( @AutostartComponents ) {
				if ( $installed{$comp} ) {
					if ($Default_EnabledComponents{$comp}) {
						@enabled = ( @enabled, $comp );
					}
				} else {
				}
			}
			enable_components(@enabled);
		}
		if (! $Default_DisableAutostart && ! $Default_EnableAutostart) {
			# use component specific default as value
			show_autostart_menu(0, %installed);
		}
	}
}

sub component_start_prompts()
{
	my $comp;
	my $start = 0;

	foreach $comp ( @Components ) {
		$start ||= ($ComponentWasInstalled{$comp} && $ComponentInfo{$comp}{'HasStart'});;
	}
	# TBD disabled for now, restart of iba causes problems if other
	# drivers are running above it
	if (0 && $start && GetYesNo("Start drivers now?", "n") == 1)
	{
		foreach $comp ( @Components )
		{
			# if not already loaded, start prereqs
			# prehaps prompt for all then do the work?
			if ($ComponentWasInstalled{$comp} && $ComponentInfo{$comp}{'HasStart'})
			{
				comp_start($comp);
				$ComponentWasInstalled{$comp}=0;
			}
		}
		HitKeyCont;
		return 1;
	}
	return 0;
} 

# states:
# $Start_Start - Enable Autostart
# $Start_NoStart - Disable Autostart
sub printStartState($$$)
{
	my $enabled     = shift();
	my $boldmessage = shift();
	my $message   = shift();

	if ( $enabled )
	{
		print GREEN, "[Enable ]", RESET;
	} else {
		print RED, "[Disable]", RESET;
	}

	if ("$message" ne "" && $boldmessage) {
		print BOLD, RED "$message", RESET, "\n";
	} else {
		print "$message\n";
	}

	return;
}

# convert a screen selection into a Autostart subscript
sub get_subscript($$$@)
{
	my $firstline=shift();
	my $maxlines=shift();
	my $selection=shift();
	my @list = ( @_ );
	my $index=0;
	my $i;

	for ($i=0; $i < scalar(@list); $i++)
	{
		my $comp = $list[$i];
		if ($index >= $firstline && $index < $firstline+$maxlines) {
			if ($index - $firstline == $selection) {
				return $i;
			}
			$index++;
		} else {
			$index++;
		}
	}
	return $i	# invalid entry return 1 past number of Components
}
sub show_autostart_menu($%)
{
	my $usePrevious = shift(); # should previous setting be used as default
	my %selections = ( @_ );	# components to show

	my $inp;
	my @PromptAutostart = ();
	my %enabled = ();
	my %statusMessage = ();
	my %boldMessage = ();
	my $comp;
	my $i;
	my $newenabled = 0;	# most recent state change for a comp
	my $firstline = 0;
	my $maxlines=14;

	# figure out which to prompt for
	# while selections may include SubComponents, we only look
	# at components and include all their subcomponents in the prompts
	foreach $comp ( @Components )
	{
		if ( comp_is_installed("$comp") && $ComponentInfo{$comp}{'HasStart'} )
		{
			# StartComponents will list Components and SubComponents which
			# have start capability
			@PromptAutostart = ( @PromptAutostart, @{ $ComponentInfo{$comp}{'StartComponents'} })
		}
	}
	if ( $Default_SameAutostart ) {
		foreach $comp ( @PromptAutostart )
		{
			my $state;
			# we recreate startup files to ensure they are in the
			# startup order of the new release
			if ( comp_IsAutostart2($comp) == 1 )
			{
				comp_enable_autostart2($comp,1);
				$state = "enabled";
			} else {
				comp_disable_autostart2($comp,1);
				$state = "disabled";
			}
			my $desc = comp_autostart_desc($comp);
			NormalPrint "Leaving autostart for $desc at its previous value: $state\n";
		}
		return;
	}

	foreach $comp ( @PromptAutostart )
	{
		DebugPrint("prompt for $comp\n");
		if ($usePrevious) {
			$enabled{$comp} = comp_IsAutostart2($comp);
		} else {
			$enabled{$comp} = $ComponentInfo{$comp}{'DefaultStart'};
		}
	}
DO_AUTOSTART:
	if ( $Default_Prompt) {
		$inp='P';
	} else {
		system "clear";        
		printf ("$BRAND OPA Autostart ($VERSION $DBG_FREE) Menu\n\n");
		my $screens = int((scalar(@PromptAutostart) + $maxlines-1)/$maxlines);
		if ($screens > 1 ) {
			printf ("Please Select Autostart Option (screen %d of $screens):\n",
						$firstline/$maxlines+1);
		} else {
			printf ("Please Select Autostart Option:\n");
		}
		my $index=0;
		for ($i=0; $i < scalar(@PromptAutostart); $i++)
		{
			$comp = $PromptAutostart[$i];
			if ($index >= $firstline && $index < $firstline+$maxlines) {
				printf ("%x) %-34s", $index-$firstline, comp_autostart_desc($comp));
				printStartState($enabled{$comp},
								$boldMessage{$comp}, $statusMessage{$comp});
				$index++;
			} else {
				$index++;
			}
		}
		
		printf ("\n");
		if ($screens > 1 ) {
			printf ("N) Next Screen\n");
		}
		printf (  "P) Perform the autostart changes\n");
		printf (  "S) Autostart All                     R) Autostart None\n");
		printf (  "X) Return to Previous Menu (or ESC)\n");	

		$inp = getch();                
	        
		if ($inp =~ /[qQ]/ || $inp =~ /[xX]/ || ord($inp) == $KEY_ESC ) 
		{
			return;
		}

		# do not clear status messages when jump between screens
		if ($inp !~ /[nN]/ ) {
			%statusMessage = ();
			%boldMessage = ();
		}

	}

	if ($inp =~ /[nN]/ )
	{
		if (scalar(@PromptAutostart) > $maxlines) {
			$firstline += $maxlines;
			if ($firstline >= scalar(@PromptAutostart)) {
				$firstline=0;
			}
		}
	} elsif ($inp =~ /[sS]/ )
	{
		foreach $comp ( @PromptAutostart )
		{
			$enabled{$comp} = 1;
		}
		$newenabled = 1;
	} elsif ($inp =~ /[rR]/ )
	{
		foreach $comp ( @PromptAutostart )
		{
			$enabled{$comp} = 0;
		}
		$newenabled = 0;
	} elsif ($inp =~ /[0123456789abcdefABCDEF]/) {
		my $value = hex($inp);
		my $index = get_subscript($firstline, $maxlines, $value, @PromptAutostart);
		if ( $value < $maxlines && $index < scalar(@PromptAutostart)) {
			my $selected = $PromptAutostart[$index];
			$enabled{$selected} = ! $enabled{$selected};
			$newenabled = $enabled{$selected};
		}
	}

	if (! $newenabled) {
		# something is being disabled
		# loop through a few times to catch all prereqs
		# and prereqs of prereqs
		my $done = 0;	# we are done if we loop through with no changes
		while (! $done) {
			$done=1;
			foreach $comp ( @PromptAutostart )
			{
				if (! $enabled{$comp}) {
					# comp will be disabled, make sure all its
					# startprereqs will also be disabled
					foreach my $c ( @PromptAutostart )
					{
						if (comp_has_startprereq_of($c, $comp) && $enabled{$c}) {
							$statusMessage{$c}="requires $ComponentInfo{$comp}{'Name'}";
							$boldMessage{$c}=1;
							$enabled{$c}=0;
							$done=0;
						}
					}
				}
			}
		}
	} else {
		# something is being disabled
		# loop through a few times to catch all prereqs
		my $done = 0;	# we are done if we loop through with no changes
		while (! $done) {
			$done=1;
			foreach $comp ( @PromptAutostart )
			{
				if ($enabled{$comp}) {
					# comp will be enabled, make sure all its
					# startprereqs will also be enabled
					foreach my $c ( @PromptAutostart )
					{
						if (comp_has_startprereq_of($comp, $c) && ! $enabled{$c}) {
							# also enable $c
							$statusMessage{$c}="needed by $ComponentInfo{$comp}{'Name'}";
							$boldMessage{$c}=1;
							$enabled{$c}=1;
							$done=0;
						}
					}
				}
			}
		}
	}

	if ($inp =~ /[pP]/) {
		# perform the changes

		# first disable, do this in reverse order
		# so dependency issues are avoided
		foreach $comp ( reverse(@PromptAutostart) ) {
			if (! $enabled{$comp}) {
				comp_disable_autostart2($comp,0);
			}
		}
		# now enable
		foreach $comp ( @PromptAutostart ) {
			if ($enabled{$comp}) {
				comp_enable_autostart2($comp,0);
			}
		}
		HitKeyCont;
		return;
	}

	if ( ! $Default_Prompt ) {
		goto DO_AUTOSTART;
	}
	$exit_code = 1;	# unexpected
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =============================================================================
# The functions and constants below assist in editing hotplug and blacklists
# to prevent autoloading of drivers prior to startup scripts

my $HOTPLUG_HARDWARE_DIR = "/etc/sysconfig/hardware";

# if not existing file on OS, use this location and create empty file
# code in add_blacklist depends on pre-existance of file
my $HOTPLUG_BLACKLIST_FILE = "/etc/modprobe.d/opa-blacklist.conf";
my $HOTPLUG_BLACKLIST_PREFIX = "blacklist";
my $HOTPLUG_BLACKLIST_SPACE = " ";
my $HOTPLUG_BLACKLIST_SPACE_WILDCARD = "[ 	]*";

# check if the module is blacklisted
sub is_blacklisted($)
{
	my $module = shift();

	my $file = "${ROOT}${HOTPLUG_BLACKLIST_FILE}";
	my $found;

	if (! -f "$file")
	{
		return 0;
	}

	return ! system("grep -q $module $file");
}

# add to list to prevent automatic hotplug of driver
sub add_blacklist($)
{
	my $module = shift();

	my $file = "${ROOT}${HOTPLUG_BLACKLIST_FILE}";
	my $found;

	if (! -e "$file")
	{
		system("touch $file"); # Blacklist file missing, let's create it.
	} elsif (! -f "$file") {
		return; # Blacklist file exists but is not regular file, abort.
	}
	open (INPUT, "$file");
	open (OUTPUT, ">>$TMP_CONF");

	select (OUTPUT);
	while (($_=<INPUT>))
	{
		if (/^${HOTPLUG_BLACKLIST_PREFIX}${HOTPLUG_BLACKLIST_SPACE_WILDCARD}$module[ 	]*$/)
		{
			$found++;
		} 
		print $_;
	}
	if (!defined($found))
	{
		print "${HOTPLUG_BLACKLIST_PREFIX}${HOTPLUG_BLACKLIST_SPACE}$module\n";
	}
	select(STDOUT);

	close (INPUT);
	close (OUTPUT);
	system "mv $TMP_CONF $file";

	# also remove any hotplug config files which load the driver
	open hwconfig, "ls $ROOT/$HOTPLUG_HARDWARE_DIR/hwcfg* 2>/dev/null |"
			|| Abort "Unable to open pipe\n";
	while (<hwconfig>) {
		chop;
		if ( ! system("grep -q \"MODULE.*'$module'\" $_ 2>/dev/null") ) {
			system "rm -f $_"
		}
	}
	close hwconfig;
}

sub remove_blacklist($)
{
	my($module) = shift();

	my($file) = "${ROOT}${HOTPLUG_BLACKLIST_FILE}";
	if (! -f "$file")
	{
		return;
	}
	open (INPUT, "$file");
	open (OUTPUT, ">>$TMP_CONF");

	select (OUTPUT);
	while (($_=<INPUT>))
	{
		if (/^${HOTPLUG_BLACKLIST_PREFIX}${HOTPLUG_BLACKLIST_SPACE_WILDCARD}$module[ 	]*$/)
		{
			next;
		} else {
			print $_;
		}
	}
	select(STDOUT);

	close (INPUT);
	close (OUTPUT);
	system "mv $TMP_CONF $file";
	if ( -z "$file" ) {
	   system("rm -f $file"); # blacklist file is empty, remove it.
	}
}

#!/usr/bin/perl
## BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]

#

use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# IP address configuration
# used for IPoIB at present but generalized so could support VNIC or
# iPathEther also

my $MAX_HFI_PORTS=20;	# maximum valid ports

# Validate the passed in IP address (or netmask).
# Verify there are enough dots '.' and same number of
# decimal numbers. This is not comprehensive.
#
# inputs:
#	IP address in dot notation.  eg:
#	'a.b.c.d' or 'a.b.c' or 'a.b'
#
# outputs:
#	0 == failure(not a valid IP address)
#	1 == Success.

sub Validate_IP_Addr($)
{
	$_ = shift();		# setup for translate & other cmds

	my($count)= 0;

	# verify there are 3 and only 3 dots, 'a.b.c.d'.
	# translate '.' to self, side-effect is the count.

	$count=(tr/\.//);
	if ( $count < 1 || $count > 3 )
	{
		return 0;
	}

	# accept only decimal digits separated by dots.
	if ( /[0-9\.]/ ) 
	{
		# because we checked dots above, any of the three below is ok
		if ( /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/ ) 
		{
			return 1;	# Success
		}
		if ( /([0-9]+)\.([0-9]+)\.([0-9]+)/ ) 
		{
			return 1;	# Success
		}
		if ( /([0-9]+)\.([0-9]+)/ ) 
		{
			return 1;	# Success
		}
	}
	return 0;	# failure.
}


# Retrieve an IPV4 address in standard 'dot' notation from stdin.
# Perform simple IP address format validation.
#
# returns:
#	IP address string.
#

sub Get_IP_Addr($$)
{
	my($interface) = shift();
	my($default_ip) = shift();

	my($ip,$idx);

	# acquire a valid IP address.
	# sadly last & redo caused runtime errors?

	do 
	{
		if ("$default_ip" ne "")
		{
			print "Enter IPV4 address in dot notation (or dhcp) for $interface [$default_ip]: ";
		} else {
			print "Enter IPV4 address in dot notation (or dhcp) for $interface: ";
		}
		chomp($ip = <STDIN>);
		$ip=remove_whitespace($ip);

		if ( length($ip) == 0 && "$default_ip" ne "" ) 
		{
			$ip = $default_ip;
			$_ = "y";
		}
		else 
		{
			# verify there are enough chars for a valid IP address
			if ( "$ip" ne "dhcp" && Validate_IP_Addr($ip) == 0 ) 
			{
				print("Bad IPV4 address '$ip'\n");
				$_ = "n";
			}
			else 
			{
				do
				{
					# require a response
					print("Is IPV4 address '$ip' correct? (y/n): ");
					chomp($_ = <STDIN>);
					$_=remove_whitespace($_);
				} until (/[YyNn]/);
			}
		}
	} until (/[Yy]/);
	LogPrint "Enter IPV4 address in dot notation for $interface: -> $ip\n";

	return $ip;
}

# Retrieve an IPV4 netmask in standard 'dot' notation from stdin.
# Perform simple IP address format validation.
#
# returns:
#	IP address string.
#

sub Get_IP_Addr_Netmask($$)
{
	my($interface) = shift();
	my($ipaddr) = shift();

	my($idx,$default_netmask,$dot_count);
	my $netmask;

	if ( "$ipaddr" eq "dhcp" ) {
		return "";
	}
	$default_netmask = `/usr/lib/opa/tools/opaipcalc --netmask $ipaddr`;
	$default_netmask =~ s/NETMASK=//;
	$default_netmask =~ s/\n//;
	$_ = $ipaddr;		# setup for translate & other cmds
	$dot_count=(tr/\.//);
	do 
	{
		print "Enter IPV4 netmask in dot notation for $interface $ipaddr [$default_netmask]: ";
		chomp($netmask = <STDIN>);
		$netmask=remove_whitespace($netmask);
		$_=$netmask;

		if ( length($netmask) == 0 ) 
		{
			$netmask = $default_netmask;
			print("Is IPV4 netmask '$netmask' correct? (y/n): ");
			chomp($_ = <STDIN>);
			$_=remove_whitespace($_);
		}
		else 
		{
			# verify there are enough chars for a valid IP address
			if ( Validate_IP_Addr($netmask) == 0 ) 
			{
				print("Bad IPV4 netmask: '$netmask'\n");
				$_ = "n";
			}
			elsif ($dot_count != (tr/\.//))
			{
				print("Inappropriate IPV4 netmask for $ipaddr: '$netmask'\n");
				$_ = "n";
			}
			else 
			{
				print("Is IPV4 netmask '$netmask' correct? (y/n): ");
				chomp($_ = <STDIN>);
				$_=remove_whitespace($_);
			}
		}
	} until (/[Yy]/);
	LogPrint "Enter IPV4 netmask in dot notation for $interface $ipaddr [$default_netmask]: -> $netmask\n";
	return $netmask;
}

# return the next sequential IPV4 address. Last numeric field is incremented.
#
# Assumes a valid dot notation IP address (e.g., 7.7.7.240)
# Increment the 'host' number ('240' in the example) by 1.
#  7.7.7.240 --> 7.7.7.241
#
# input:
#	base IP address in 'dot' notation.
# output:
#	next IP address

sub NextIPaddr($)
{
	my($base) = shift();

	my($next,$hostnum,$idx,$len);

	if ( "$base" eq "dhcp" ) {
		return "$base";
	}
	# locate right-most '.'
	$idx = rindex($base, ".");
	Abort "NextIPaddr: Bad IPV4 address ".$base
		if ($idx == -1);

	$idx += 1;	# move past the dot to the last numeric field portion of
				# the IP address.

	# extract the host number
	$len = length($base);
	$hostnum = substr($base, ($idx), ($len - $idx));

	$hostnum += 1;	# next host number

	# replace the last numeric field with the incremented host number
	$next = $base;
	substr($next,$idx,length($hostnum)) = $hostnum;

	DebugPrint("Next IP '$next'\n");

	return $next
}

# return the next sequential interface name. Last numeric field is incremented.
# if the final field is not numeric, returns ""
sub NextInterface($)
{
	my($base) = shift();

	my($next,$hostnum,$idx,$len);
	my $number;
	my $prefix;

	$_ = $base;
	if ( ! /.*([0-9]+)$/ ) 
	{
		# non numeric name, can't auto-increment
		return "";
	}
	$prefix = $base;
	$prefix =~ s/(.*)([0-9]+)$/$1/;
	$number = $base;
	$number =~ s/(.*)([0-9]+)$/$2/;

	$number += 1;	# next intf number

	return "$prefix$number";
}

# build the ifcfg file for a network device
sub Build_ifcfg($$$)
{
	my($device) = shift();		# device name
	my($ipaddr) = shift();		# ip address for device or "dhcp"
	my($netmask) = shift();		# ip address netmask for device

	my($target, $SysCmd);
	my ($temp);

	$target = "$ROOT$NETWORK_CONF_DIR/ifcfg-$device";
	print("Creating ifcfg-$device for $ipaddr mask $netmask\n\n");

	if ( "$CUR_DISTRO_VENDOR" eq "UnitedLinux" || "$CUR_DISTRO_VENDOR" eq "SuSE") {
		if ( "$ipaddr" eq "dhcp" ) {
			# append boot protocol type
			$SysCmd = "echo \"BOOTPROTO=\'dhcp\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;
		} else {
			# append boot protocol type
			$SysCmd = "echo \"BOOTPROTO=\'static\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the device instance internet protocol address
			$SysCmd = "echo \"IPADDR=\'$ipaddr\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the netmask
			$SysCmd = "echo \"NETMASK=\'$netmask\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the network
			$temp = `/usr/lib/opa/tools/opaipcalc --network $ipaddr $netmask`;
			chomp($temp);
			$temp =~ s/NETWORK=//;
			$SysCmd = "echo \"NETWORK=\'$temp\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the broadcast
			$temp = `/usr/lib/opa/tools/opaipcalc --broadcast $ipaddr $netmask`;
			chomp($temp);
			$temp =~ s/BROADCAST=//;
			$SysCmd = "echo \"BROADCAST=\'$temp\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			$SysCmd = "echo \"REMOTE_IPADDR=\'\'\" >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;
		}

		$SysCmd = "echo \"STARTMODE=\'hotplug\'\" >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;

		$SysCmd = "echo \"WIRELESS='no'\" >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;

		# SLES11 and newer have IPOIB_MODE option in ifcfg
		$SysCmd = "echo \"IPOIB_MODE='connected'\" >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;
		$SysCmd = "echo \"MTU=65520\" >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;
	} else {
		# Append the device instance name
		$SysCmd = "echo DEVICE=$device > $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;

		$SysCmd = "echo \"TYPE=\'InfiniBand\'\" >> $target";
                DebugPrint("cmd '$SysCmd'\n");
                system $SysCmd;

		if ( "$ipaddr" eq "dhcp" ) {
			$SysCmd = "echo BOOTPROTO=dhcp >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			$SysCmd = "echo DHCPCLASS= >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;
		} else {

			$SysCmd = "echo BOOTPROTO=static >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# Append the device instance Internet Protocol address
			$SysCmd = "echo IPADDR=$ipaddr >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the network,broadcast
			$SysCmd = "/usr/lib/opa/tools/opaipcalc --network --broadcast $ipaddr $netmask >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;

			# append the netmask
			$SysCmd = "echo NETMASK=$netmask >> $target";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;
		}

		$SysCmd = "echo ONBOOT=yes >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;

		$SysCmd = "echo CONNECTED_MODE=yes >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;
		$SysCmd = "echo MTU=65520 >> $target";
		DebugPrint("cmd '$SysCmd'\n");
		system $SysCmd;
	}

	system "chown $OWNER $target";
	system "chgrp $GROUP $target";
	system "chmod ugo=r,u=rw $target";
}

sub Config_IP_Manually($$)
{
	my($compname) = shift();
	my($sampledev) = shift();

	print "\n$compname requires an ifcfg file for each $compname device instance.\n";
	print ("Manually create files such as '$ROOT$NETWORK_CONF_DIR/ifcfg-$sampledev'\n");
}


sub Exist_ifcfg($)
{
	my($prefix) = shift();

	my $ifcfg_wildcard="$NETWORK_CONF_DIR/ifcfg-$prefix"."[0-9]*";
	return ( `ls $ROOT$ifcfg_wildcard 2>/dev/null` ne "" );
}

#
# Generate the network interface config files for IP over IB
#	/etc/sysconfig/network-scripts/ifcfg-ibl1
#
# Assign IP (Internet Protocol) addresses in standard 'dot' notation to
# IP over IB device instances. Create IP over IB 'ifup ibX' configuration files
# located in '/etc/sysconfig/network-scripts' for each IP over IB port.
#
# **** Currently - ONLY static IP address assignment is supported.
#
# inputs:
#	[0] == are we reconfiguring, if 1, allows editing of existing ifcfg files
#
# outputs:
#	none.
#
sub Config_ifcfg($$$$$)
{
	my($reconfig) = shift();
	my($compname) = shift();
	my($prefix) = shift();
	my($firstdev) = shift();
	my($showoptions) = shift();

	my($max_ports,$port,$a,$inp,$seq,$intf_seq,$default_intf);
	my($netmask);
	my($ipaddr) = "";
	my($interface) = "";
	my(%interfaces) = ();
	my $config_dir;

	$max_ports = 0;
			
	# Check if ifcfg files are present
	my $ifcfg_wildcard="$NETWORK_CONF_DIR/ifcfg-$prefix"."[0-9]*";
	if ( `ls $ROOT$ifcfg_wildcard 2>/dev/null` ne "" )
	{
		if ($reconfig)
		{
			# always prompt regardless of previous check_keep_config answer
			clear_keep_config("$ifcfg_wildcard");
		}
		if (! $reconfig 
			|| check_keep_config("$ifcfg_wildcard", "$compname ifcfg files", "y"))
		{
			print "Leaving $ROOT$ifcfg_wildcard unchanged...\n";
			return;
		} 
		print "removing $ROOT$ifcfg_wildcard\n";
		system "rm -f $ROOT$ifcfg_wildcard";
	}
	if (GetYesNo("Configure $compname IPV4 addresses now?", "n") == 0)
	{
		# If user answered 'no', then reluctantly bail.
		Config_IP_Manually("$compname","$prefix$firstdev");
		return;
	}

	if ( $showoptions != 0 )
	{
		printf ("\nYou may configure an $compname interface for each HFI port\n");
		printf ("Or you may select to have $compname only run on some HFI ports\n");
		printf ("Or you may select to configure redundant HFI ports with a\n");
		printf ("pair of HFI ports running a single $compname interface\n");
	}
	do
	{
		printf ("How many $compname interfaces would you like to configure? [1]: ");

		$inp = <STDIN>;
		$inp=remove_whitespace($inp);

		if ( length($inp) == 0 ) 
		{
			$max_ports=1;
		} elsif ($inp < 0 || $inp > $MAX_HFI_PORTS)
		{
			printf ("You must specify a number between 0 and $MAX_HFI_PORTS\n");
		} elsif ($inp == 0) {
			LogPrint "How many $compname interfaces would you like to configure? -> $inp\n";
			if (GetYesNo("You specified 0, would you like to skip IP address configuration?", "n") == 1)
			{
				# If user answered to skip, then reluctantly bail.
				Config_IP_Manually("$compname","$prefix$firstdev");
				return;
			}
		} else {
			$max_ports=$inp;
			LogPrint "How many $compname interfaces would you like to configure? -> $inp\n";
		}
	} while ($max_ports == 0);

	print "\nAbout to create $compname ifcfg files in $NETWORK_CONF_DIR\n";

	# Does the user want sequential IP address assignment starting at a base
	# IP address or specify an IP address for each HFI port (a.k.a. IPoIB device
	# instance). 

	if ( $max_ports > 1 ) {
		$intf_seq = GetYesNo("Configure interface names sequentially starting with $prefix$firstdev?", "y");
		$seq = GetYesNo("Assign Internet Addresses sequentially from a base IP address?", "y");
	} else {
		$intf_seq = GetYesNo("Use interface name $prefix$firstdev?", "y");
		$seq = 1;	# doesn't matter
	}

	# Allocate IP addresses and create the network config files '$prefix[firstdev...n]'.

	for($a=$firstdev; $a < $max_ports+$firstdev; $a++)
	{
		if ($intf_seq)
		{
			$interface="$prefix$a";
		} else {
			$default_intf = $interface;
			$interface = "";
			do {
				if ($default_intf eq "" )
				{
					print "Enter $compname interface name: ";
				} else {
					print "Enter $compname interface name [$default_intf]: ";
				}

				chomp($inp = <STDIN>);
				$inp=remove_whitespace($inp);
				if ( length($inp) == 0 )
				{
					$inp=$default_intf;
				}
				if ("$inp" eq "" )
				{
					printf "You must enter an interface name, such as $prefix$firstdev\n";
				} else {
					if (exists $interfaces{$inp})
					{
						print "You have already used $interface, specify a different name\n";
					} else {
						$interface=$inp;
						$interfaces{$interface} = 1;
					}
				}
			} while ("$interface" eq "");
		}
		LogPrint "Enter $compname interface name [$default_intf]: -> $interface\n";
		if ( $seq == 0 || $a == $firstdev) 
		{
			# not sequential assignment, get each IP addr.
			$ipaddr = Get_IP_Addr($interface, $ipaddr);
			$netmask = Get_IP_Addr_Netmask($interface, $ipaddr);
		}

		Build_ifcfg($interface, $ipaddr, $netmask);
		# make sure future prompts start fresh and don't auto remove
		clear_keep_config("$ifcfg_wildcard");

		# generate the next sequential IP address
		$ipaddr = NextIPaddr($ipaddr);
		$interface = NextInterface($interface);
	}
}

sub net_interface_down($)
{
	my($dev) = shift();	# base device name

	my($a);				# device instance number
	my($IF);			# interface name
	my($SysCmd);

	if ( ROOT_is_set() )
	{
		return;
	}
	# make sure the specified network interfaces are not running
	for($a=0; $a < $MAX_HFI_PORTS; $a++)
	{
		$IF = "$NETWORK_CONF_DIR/ifcfg-".$dev."$a";
		if ( -r $IF )
		{
			$SysCmd = "/sbin/ifdown $dev"."$a";
			DebugPrint("cmd '$SysCmd'\n");
			system $SysCmd;
		}
	}
}


# Remove ifcfg files.
# driver should have already been unloaded.
#
sub Remove_ifcfg($$$)
{
	my($WhichDriver) = shift();	# driver name
	my($compname) = shift();
	my($prefix) = shift();

	if (IsModuleLoaded("$WhichDriver") == 1) 
	{
		print "Warning: '$WhichDriver' module still loaded? continuing...\n";
	}

	# This could be an 'update' where we might not want to clobber the
	# IPoIB config files.

	my $ifcfg_wildcard="$NETWORK_CONF_DIR/ifcfg-$prefix"."[0-9]*";
	if ( `ls $ROOT$ifcfg_wildcard 2>/dev/null` ne "" )
	{
		if (check_keep_config("$ifcfg_wildcard", "$compname ifcfg files", "y"))
		{
			print "Keeping $compname ifcfg files ...\n";
		} else {
			print "removing $ROOT$ifcfg_wildcard\n";
			system "rm -f $ROOT$ifcfg_wildcard";
		}
	}
}

sub check_network_config()
{
	my $nm=read_simple_config_param("$ROOT/etc/sysconfig/network/config", "NETWORKMANAGER");
	if ( "$nm" eq "yes" ) {
		print RED "Please set NETWORKMANAGER=no in $ROOT/etc/sysconfig/network/config", RESET "\n";
		HitKeyCont;
	}
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =============================================================================
# The functions and constants below assist in editing modules.conf or
# modprobe.conf to add IB specific entries

my $MODULE_CONF_FILE = "/etc/modules.conf";
my $MODULE_CONF_DIST_FILE;
my $DRACUT_EXE_FILE = "/usr/bin/dracut";
if (substr($CUR_OS_VER,0,3) eq "2.6")
{
	$MODULE_CONF_FILE = "/etc/modprobe.conf";
	$MODULE_CONF_DIST_FILE = "/etc/modprobe.conf.dist";
	$DRACUT_EXE_FILE = "/sbin/dracut";
}
if (-f "$(MODULE_CONF_FILE).local")
{
	$MODULE_CONF_FILE = "$(MODULE_CONF_FILE).local";
}
my $OPA_CONF="modules.conf";	## additions to modules.conf

# marker strings used in MODULES_CONF_FILE
# for entries added by installation
my $START_DRIVER_MARKER="OPA Drivers Start here";
my $END_DRIVER_MARKER="OPA Drivers End here";

# Keep track of whether we already did edits to avoid repeated edits
my $DidConfig=0;

sub	edit_modconf($)
{
	my($srcdir) = shift();	# directory containing $OPA_CONF file

	if ($DidConfig == 1)
	{
		return;
	}
	edit_conf_file("$srcdir/$OPA_CONF.$CUR_DISTRO_VENDOR", "$MODULE_CONF_FILE",
		"module dependencies", "$START_DRIVER_MARKER",  "$END_DRIVER_MARKER");
	$DidConfig = 1;
}

# remove iba entries from modules.conf
sub remove_modules_conf()
{
	$DidConfig = 0;
	if (check_keep_config($MODULE_CONF_FILE, "", "y"))
	{
		print "Keeping $ROOT/$MODULE_CONF_FILE changes ...\n";
	} else {
		print "Modifying $ROOT$MODULE_CONF_FILE ...\n";
		del_marks ("$START_DRIVER_MARKER", "$END_DRIVER_MARKER", 0, "$ROOT$MODULE_CONF_FILE");
	}
}

# This code is from OFED, it removes lines related to IB from
# modprobe.conf.  Used to prevent distro specific effects on OFED.
sub disable_distro_ofed()
{
	if ( "$MODULE_CONF_DIST_FILE" ne "" && -f "$ROOT$MODULE_CONF_DIST_FILE" ) {
		my $res;

		$res = open(MDIST, "$ROOT$MODULE_CONF_DIST_FILE");
		if ( ! $res ) {
			NormalPrint("Can't open $ROOT$MODULE_CONF_DIST_FILE for input: $!");
			return;
		}
		my @mdist_lines;
		while (<MDIST>) {
			push @mdist_lines, $_;
		}
		close(MDIST);

		$res = open(MDIST, ">$ROOT$MODULE_CONF_DIST_FILE");
		if ( ! $res ) {
			NormalPrint("Can't open $ROOT$MODULE_CONF_DIST_FILE for output: $!");
			return;
		}
		foreach my $line (@mdist_lines) {
			chomp $line;
			if ($line =~ /^\s*install ib_core|^\s*alias ib|^\s*alias net-pf-26 ib_sdp/) {
				print MDIST "# $line\n";
			} else {
				print MDIST "$line\n";
			}
		}
		close(MDIST);
	}
}

# Start rdma on run level 235 on RHEL67
sub run_rdma_on_startup()
{
	if (-e "/etc/redhat-release") {
		if (6.7 ==  `cat \"/etc/redhat-release\" | grep -o [0-9]\.[0-9]`) {
			system ("chkconfig --level 235 rdma on");
		}
	}
}

# =============================================================================
# The functions and constants below assist in editing limits.conf
# to add IB specific entries related to memory locking

my $LIMITS_CONF_FILE = "/etc/security/limits.conf";
my $LIMITS_CONF="limits.conf";	## additions to limits.conf

# marker strings used in LIMITS_CONF_FILE
# for entries added by installation
my $START_LIMITS_MARKER="OPA Settings Start here";
my $END_LIMITS_MARKER="OPA Settings End here";

# Keep track of whether we already did edits to avoid repeated edits
my $DidLimits=0;

# Path to opasystemconfig
my $OPA_SYSTEMCFG_FILE = "/sbin/opasystemconfig";

# remove iba entries from modules.conf
sub remove_limits_conf()
{
	$DidLimits = 0;
	if ( -e "$ROOT$LIMITS_CONF_FILE") {
		if (check_keep_config($LIMITS_CONF_FILE, "", "y"))
		{
			print "Keeping $ROOT/$LIMITS_CONF_FILE changes ...\n";
		} else {
			print "Modifying $ROOT$LIMITS_CONF_FILE ...\n";
			if ( -e "$ROOT$OPA_SYSTEMCFG_FILE" ) {
			     system("$ROOT$OPA_SYSTEMCFG_FILE --disable Memory_Limit");
			}
		}
	}
}

#
# Override the system's standard udev configuration to allow
# different access rights to some of the infiniband device files.
#
my $UDEV_RULES_DIR ="/etc/udev/rules.d";
my $UDEV_RULES_FILE = "05-opa.rules";
my $Default_UserQueries = 0;

my $udev_perm_string = "Allow non-root users to access the UMAD interface?";

AddAnswerHelp("UserQueries", "$udev_perm_string");

sub install_udev_permissions($)
{
	my ($srcdir) = shift(); # source directory.
	my $SourceFile;
	my $Context;
	my $Cnt;

	if ($Default_UserQueries == 0) {
		$Default_UserQueries = GetYesNoWithMemory("UserQueries",0,"$udev_perm_string", "y");
	}

	if ($Default_UserQueries > 0) {
                # Installation of udev will be taken care during RPM installation, we just have to set
                setup_env("OPA_UDEV_RULES", 1);
	} elsif ( -e "$UDEV_RULES_DIR/$UDEV_RULES_FILE" ) {
                #update environment variable accordingly
                setup_env("OPA_UDEV_RULES", 0);
	}
}

sub remove_udev_permissions()
{
	remove_file("$UDEV_RULES_DIR/$UDEV_RULES_FILE");
}

#
# Ensures OPA drivers are incorporated in the initial ram disk.
#
my $CallDracut = 0;
my $DracutOutputLogFile = "";

sub rebuild_ramdisk()
{
	# Save current logfile path
	$DracutOutputLogFile = $LogFile;
	$CallDracut++;

	# Capture INT/TERM to make sure end call is made
	$SIG{INT} = sub {die "$!"};
	$SIG{TERM} = sub {die "$!"};

# Call dracut once only at the end of INSTALL
END {
	if ($CallDracut && -d '/boot') {
		my $cmd = $DRACUT_EXE_FILE;
		my $kver = `uname -r | xargs echo -n`;
		my $tmpfile = "/tmp/initramfs-$kver.img";

		# Reopen logfile
		open_log($DracutOutputLogFile);
		if ( -e $cmd ) {
			NormalPrint("Rebuilding boot image with \"$cmd -f\"...");
			# Try to build a temporary image first as a dry-run to make sure
			# a failed run will not destroy an existing image.
			if (system("$cmd -f $tmpfile") == 0) {
				system("mv -f $tmpfile /boot/");
				NormalPrint("done.\n");
			} else {
				NormalPrint("failed.\n");
			}
		} else {
			NormalPrint("$cmd not found, cannot update initial ram disk.");
		}
		close_log();
	}
}
		
}

my $OPA_MODPROBE_DIR = "/etc/modprobe.d";

sub enable_mod_force_load_file($$)
{
	my ($module) = shift(); # module name
	my ($conf_file) = shift(); # modprobe configuration file
	my ($retval);

	# Create the configuration file if not existing
	if (! -e "$conf_file" ) {
		system ("touch $conf_file");
		system ("echo 'install $module modprobe -i -f $module \$CMDLINE_OPTS' > $conf_file");
		return;
	}
	# Check if we have an entry for this module in the config file
	$retval=`grep -e "install $module" -e "modprobe -i $module" $conf_file  2>/dev/null | grep -v "#"`;
	if ("$retval" eq "") {
		system ("echo 'install $module modprobe -i -f $module \$CMDLINE_OPTS' >> $conf_file");
	} else {
		system("sed -i 's/modprobe -i $module/modprobe -i -f $module/g' $conf_file");
	}
}

sub enable_mod_force_load($)
{
	my ($module) = shift(); # module name
	my ($file);
	my ($retval);
	my ($found) = 0;
	my (@conf_files) = ( `ls $OPA_MODPROBE_DIR` );

	# Check if there is any config file that contains install entry for the module
	# if yes, update it; otherwise, create a new conf file.
	chomp(@conf_files);
	foreach $file (@conf_files) {
		$retval=`grep "install $module" $OPA_MODPROBE_DIR/$file 2>/dev/null | grep -v "#"`;
		if ("$retval" ne "") {
			$found = 1;
			$retval=`echo "$retval" | grep "modprobe -i $module"`;
			if ("$retval" ne "") {
				enable_mod_force_load_file($module, "$OPA_MODPROBE_DIR/$file");
			}
		}
	}

	if (!$found) {
		enable_mod_force_load_file($module, 
			"$OPA_MODPROBE_DIR/$module.conf");
	}
}

my $OPA_IRQBALANCE_FILE = "/etc/sysconfig/irqbalance";
my $OPA_IRQBALANCE_BAK = "/etc/sysconfig/irqbalance.bak";
sub set_opairqbalance()
{
	print "Updating $ROOT$OPA_IRQBALANCE_FILE\n";

	# Look up the current arguments. Note that this may be an empty string.
	my ($original_line) = `egrep -e '^IRQBALANCE_ARGS=' $ROOT$OPA_IRQBALANCE_FILE`;
	chomp($original_line);

	if ($original_line =~ /--hintpolicy=exact/ || $original_line =~ /-h exact/) {
		# Already set to exact. No action is needed.
	} else {
		# Make a backup.
		copy_data_file("$ROOT$OPA_IRQBALANCE_FILE", "$ROOT/$OPA_IRQBALANCE_BAK");

		# Replace the existing hint policy with the new one.
		my ($original_args) = $original_line;
		$original_args =~ s/IRQBALANCE_ARGS=//;
		$original_args =~ s/["']//g;
		my ($new_args) = $original_args;
		$new_args =~ s/--hintpolicy=[a-z]*//;
		$new_args =~ s/-h [a-z]*//;

		# In RHEL6.7 systems, irqbalance throws error if IRQBALANCE_ARGS
		# starts with a space character.
		# Swap the args to avoid leading space character when ${new_args} is empty
		if (-e "/etc/redhat-release" &&
			6 ==  `cat \"/etc/redhat-release\" | grep -o [0-9]\.[0-9] | cut -d\. -f1`) {
			$new_args = "--hintpolicy=exact ${new_args}";
		}
		else {
			$new_args = "$new_args --hintpolicy=exact";
		}

		if ($original_line eq "") {
			# If there were no arguments in the existing file, just append.
			open (OUTPUT, ">>$ROOT$OPA_IRQBALANCE_FILE");
			select (OUTPUT);
			print "IRQBALANCE_ARGS=$new_args\n";
			select(STDOUT);
			close(OUTPUT);
		} else {
			# Otherwise, rewrite the existing line.
			open (INPUT, "$ROOT$OPA_IRQBALANCE_BAK");
			open (OUTPUT, ">$ROOT$OPA_IRQBALANCE_FILE");
			select (OUTPUT);

			while (($_=<INPUT>)) {
				if (/^$original_line/) {
					print "# $_";
					print "IRQBALANCE_ARGS=$new_args\n";
				} else {
					print $_;
				}
			}
			select(STDOUT);

			close (INPUT);
			close (OUTPUT);
			unlink("$ROOT$OPA_IRQBALANCE_BAK");
		}
	}

	# Make sure irqbalance is enabled and started.
	if (substr($CUR_OS_VER,0,3) eq "2.6") {
                `/sbin/chkconfig irqbalance on; service irqbalance restart`
        }
        else {
                `systemctl enable irqbalance; systemctl restart irqbalance`
        }

}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ===========================================================================
# Host Tools

# capture host information for problem report
sub capture_report($)
{
	my($req_compname) = shift();

	my $result;
	my $inp;
	my $detail;

	if ( ! -e "$BIN_DIR/opacapture" ) {
		printf("$req_compname not installed on this system\n");
		printf("Unable to Generate Supporting Information\n");
		HitKeyCont;
		return;
	}

GET_FILENAME:
	printf ("\n\nEnter Filename to Generate [q to quit] : ");
	$inp = <STDIN>;
	$inp=remove_whitespace($inp);
	chomp $inp;
	$_ = $inp;
		
	if (/^[Qq]$/) {
		return;
	}

	if ( length($inp) == 0 ) {
		goto GET_FILENAME;
	}

	LogPrint "Capturing $INT_VERSION Report to $inp\n";
	$detail=GetNumericValue("Capture detail level (1-Normal 2-Fabric 3-Fabric+FDB 4-Analysis):", 1, 1, 4);
	close_log;
	$result = system "$BIN_DIR/opacapture -d $detail $inp";
	if ( $result != 0 ) {
		printf("\nError generating $inp\n");
		goto GET_FILENAME;
	}
	open_log;
	HitKeyCont;
}

# invoke FastFabric TUI
my $FabricSetupScpFromDir=".";

sub run_fastfabric($)
{
	my($req_compname) = shift();

	if ( ! -e "$BIN_DIR/opafastfabric" ) {
		printf("$req_compname not installed on this system\n");
		printf("Unable to perform FastFabric (Host/Chassis/Switch Setup/Admin)\n");
		HitKeyCont;
		return;
	}
	system("$BIN_DIR/opafastfabric -r '$ROOT' --fromdir $FabricSetupScpFromDir");
	return;
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =============================================================================
# The functions and constants below assist in using RPM files

# on platforms without 32 bit app on 64 bit OS support, these are ''
# _glob is a glob pattern version which can be used to match rpm names
# when building rpms the simple _cpu32 values should be used
my $suffix_64bit = "";	# suffix for rpm name for 64 bit rpms

my $rpm_check_dependencies = 1;	# can be set to 0 to disable rpm_check_os_prereqs
my $skip_kernel = 0; # can be set to 1 by --user-space argument

sub rpm_query_param($);
# TBD or
# my $RPM_ARCH = rpm_query_param('_target_cpu');
# chomp $RPM_ARCH;
my $RPM_ARCH=my_tolower("$ARCH");
if ( "$RPM_ARCH" eq "ia32" ) {
	$RPM_ARCH = rpm_query_param('_target_cpu');
	#$RPM_ARCH=`uname -m`; # or i386
	chomp $RPM_ARCH;
}
my $RPM_KERNEL_ARCH = `uname -m`; # typically matches $RPM_ARCH
chomp $RPM_KERNEL_ARCH;

my $RPM_DIST=`rpm -qf /etc/issue 2>/dev/null|head -1`;
chomp $RPM_DIST;
if ( "$RPM_DIST" eq "" ) {
	$RPM_DIST="unsupported";
} else {
	# This effectively gets rid of any CPU architecture suffix in RPM_DIST
	$RPM_DIST=`rpm -q --queryformat "[%{NAME}]-[%{VERSION}]-[%{RELEASE}]" $RPM_DIST 2>/dev/null`;
	chomp $RPM_DIST;
	if ( "$RPM_DIST" eq "" ) {
		$RPM_DIST="unsupported";
	}
}
sub rpm_query_release_pkg($);
my $RPM_DIST_REL = rpm_query_release_pkg($RPM_DIST);

# version string for kernel used in RPM filenames uses _ instead of -
sub rpm_tr_os_version($)
{
	my($osver) = shift();	# uname -r style output
	$osver =~ s/-/_/g;
	return "$osver";
}

# query a parameter of RPM tools themselves
sub	rpm_query_param($)
{
	my($param) = shift();	# parameter name: such as _mandir, _sysconfdir, _target_cpu
	my $ret = `chroot /$ROOT $RPM --eval "%{$param}"`;
	chomp $ret;
	return $ret;
}

# query an attribute of the RPM file
sub	rpm_query_attr($$)
{
	my($rpmfile) = shift();	# .rpm file
	my($attr) = shift();	# attribute name: such as NAME or VERSION

	if ( ! -f "$rpmfile" ) {
		return "";
	}
	return `$RPM --queryformat "[%{$attr}]" -qp $rpmfile 2>/dev/null`;
}

# query an attribute of the installed RPM package
sub	rpm_query_attr_pkg($$)
{
	my($package) = shift();	# installed package
	my($attr) = shift();	# attribute name: such as NAME or VERSION

	return `chroot /$ROOT $RPM --queryformat "[%{$attr}]" -q $package 2>/dev/null`;
}

# determine if rpm parameters will allow srpms to build debuginfo rpms
sub rpm_will_build_debuginfo()
{
	# If debug_package is set to nil in .rpmmacros, srpms will not generate
	# -debuginfo rpms, so they will not be available to install
	return (rpm_query_param('debug_package') ne "");
}

# get NAME of RPM file
sub rpm_query_name($)
{
	my($rpmfile) = shift();	# .rpm file

	return rpm_query_attr($rpmfile, "NAME");
}

# get RELEASE of installed RPM package
sub rpm_query_release_pkg($)
{
	my($package) = shift();	# installed package

	return rpm_query_attr_pkg($package, "RELEASE");
}

sub rpm_query_version_release($)
{
	my($rpmfile) = shift();	# .rpm file

	my $ver = rpm_query_attr($rpmfile, "VERSION");
	my $rel = rpm_query_attr($rpmfile, "RELEASE");
	return "${ver}-${rel}";
}

# get VERSION-RELEASE of installed RPM package
sub rpm_query_version_release_pkg($)
{
	my($package) = shift();	# installed package

	my $ver = rpm_query_attr_pkg($package, "VERSION");
	my $rel = rpm_query_attr_pkg($package, "RELEASE");
	return "${ver}-${rel}";
}

# return NAME-VERSION-RELEASE.ARCH
sub rpm_query_full_name($)
{
	my($rpmfile) = shift();	# .rpm file

	if ( ! -f "$rpmfile" ) {
		return "";
	}
	return `$RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}]' -qp $rpmfile 2>/dev/null`;
}

# beware, this could return more than 1 name
#sub rpm_query_full_name_pkg($)
#{
#	my($package) = shift();	# installed package
#	return `chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}]' -q $package 2>/dev/null`;
#}

sub rpm_adjust_mode_cpu($$)
{
	my($package) = shift();	# package name
	my $mode = shift();	# "user" or "kernel rev"
						# "any"- checks if any variation of package is installed

	if ("$mode" eq "user" || "$mode" eq "any") {
			return ($mode, $RPM_ARCH);
		} else {
			return ($mode, $RPM_KERNEL_ARCH);
		}
	}

my $last_checked;	# last checked for in rpm_is_installed
sub rpm_is_installed($$)
{
	my($package) = shift();	# package name
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my $rc;
	my $cpu;

	if ($skip_kernel && "$mode" ne "user" && "$mode" ne "any") {
               return 1;
	}

	( $mode, $cpu ) = rpm_adjust_mode_cpu($package, $mode);
	if ("$mode" eq "any" ) {
		# any variation is ok
		DebugPrint("$RPM -q $package > /dev/null 2>&1\n");
		$rc = system("chroot /$ROOT $RPM -q $package > /dev/null 2>&1");
		$last_checked = "any variation";
	} elsif ("$mode" eq "user") {
		# verify $cpu version or noarch is installed
		DebugPrint "chroot /$ROOT $RPM --queryformat '[%{ARCH}\\n]' -q $package 2>/dev/null|egrep '^$cpu\$|^noarch\$' >/dev/null 2>&1\n";
		$rc = system "chroot /$ROOT $RPM --queryformat '[%{ARCH}\\n]' -q $package 2>/dev/null|egrep '^$cpu\$|^noarch\$' >/dev/null 2>&1";
		$last_checked = "for $cpu or noarch";
	} else {
		# $mode is kernel rev, verify proper kernel version is installed
		# for kernel packages, RELEASE is kernel rev
		my $release = rpm_tr_os_version($mode);
		DebugPrint "chroot /$ROOT $RPM --queryformat '[%{VERSION}\\n]' -q $package 2>/dev/null|egrep '$release' >/dev/null 2>&1\n";
		$rc = system "chroot /$ROOT $RPM --queryformat '[%{VERSION}\\n]' -q $package 2>/dev/null|egrep '$release' >/dev/null 2>&1";
		$last_checked = "for kernel $release";
	}
	DebugPrint("Checked if $package $mode is installed: ".(($rc==0)?"yes":"no")."\n");
	return 0 == $rc;
}

sub rpm_is_installed_list($@)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- verifies any variation of package is installed
	my(@package_list) = @_;	# package names

	foreach my $package ( @package_list )
	{
		if ( !  rpm_is_installed($package, $mode) ) {
			return 0;
		}
	}
	return 1;
}

# return 0 on success, number of errors otherwise
sub rpm_check_os_prereqs_internal($$@)
{
	my $mode = shift();	# default mode
	my $message = shift();
	my(@package_list) = @_;	# package names
	my $err=0;
	
	if ( ! $rpm_check_dependencies ) {
		return 0;
	}
	# Check installation requirements
	DebugPrint "Checking prereqs $message: @package_list\n";
	for my $package_info ( @package_list )
	{
		# expand any alias in package_info
		my $full_package_info="";
		my @alternatives = (split ('\|',$package_info));
		for my $altpackage_info ( @alternatives )
		{
			my ($package, $details) = (split (' ',$altpackage_info,2));
			if ($details ne "") {
				$details=" $details";
			}
			if ( "$full_package_info" ne "" ) {
				$full_package_info = "$full_package_info|";
			}

			# expand "g77" alias for various fortran compilers
			# and "libgfortran" alias for various fortran library
			if ("$package" eq "g77" ) {
				# on RHEL4u5-6: gcc4-gfortran, gcc-g77
				# on RHEL5.1: gcc-gfortran, compat-gcc-34-g77
				# on RHEL5.2: gcc-gfortran
				# on RHEL5.3: gcc43-gfortran
				# on sles10sp1-2: gcc-fortran
				# on sles11: gcc-fortran
				$full_package_info = "${full_package_info}gcc4-gfortran$details|gcc-g77$details|gcc-gfortran$details|compat-gcc-34-g77$details|gcc43-gfortran$details|gcc42-gfortran$details|gcc-fortran$details|gcc42-fortran$details|gcc43-fortran$details"

			} elsif ("$package" eq "libgfortran") {
				# on RHEL4u5-6: libgfortran
				# on RHEL5.1: libgfortran
				# on RHEL5.2: libgfortran
				# on RHEL5.3: libgfortran43
				# on sles10sp1-2: libgfortran
				# on sles11sp0-1: libgfortran43
				# on sles11sp2: libgfortran46
				# TBD - openSUSE11.2 has libgfortran44
                                # sles12sp0: libgfortran3-4
				$full_package_info = "${full_package_info}libgfortran$details|libgfortran42$details|libgfortran43$details|libgfortran46$details|compat-gcc-34-g77$details|libgfortran3$details";
			} else {
				$full_package_info = "${full_package_info}$altpackage_info";
			}
		}

		# now process the expanded list of alternatives
		DebugPrint "Checking prereq: $full_package_info\n";
		my $errmessage="";
		@alternatives = (split ('\|',$full_package_info));
		for my $altpackage_info ( @alternatives )
		{
			DebugPrint "Checking prereq: $altpackage_info\n";
			my ($package, $version, $pkgmode) = (split (' ',$altpackage_info));
			if ("$pkgmode" eq "") {
				$pkgmode = $mode;
			}

			# keep things simple for callers, handle distro specific namings
			
			# distro specific naming of libstdc++
			if ("$package" eq "libstdc++" && "$CUR_DISTRO_VENDOR" eq 'SuSE'
					&& "$CUR_VENDOR_VER" eq 'ES11') {
				# hack because CUR_VENDOR_VER doesn't actually contain the minor 
				# version any more...
				my $CUR_VENDOR_MINOR_VER = `grep PATCHLEVEL /etc/SuSE-release | cut -d' ' -f 3`;
				chop($CUR_VENDOR_MINOR_VER);
				if ($CUR_VENDOR_MINOR_VER eq '0' || $CUR_VENDOR_MINOR_VER eq '1') { $package="libstdc++43"; }
				if ($CUR_VENDOR_MINOR_VER eq '2' ) { $package="libstdc++46"; }
				if ($CUR_VENDOR_MINOR_VER eq '3' ) { $package="libstdc++6"; }
				# SLES11 SP3 has renamed libstdc++47 as libstdc++6
				# TBD - openSUSE has libstdc++42
				# TBD - openSUSE11.2 has libstdc++44
			} elsif ("$package" eq "libstdc++" && "$CUR_DISTRO_VENDOR" eq 'SuSE'
					&& ("$CUR_VENDOR_VER" eq 'ES12' || "$CUR_VENDOR_VER" eq 'ES121' || "$CUR_VENDOR_VER" eq 'ES122')) {
				$package="libstdc++6";
		 	} elsif ("$package" eq "libstdc++-devel" && "$CUR_DISTRO_VENDOR" eq 'SuSE'
					&& "$CUR_VENDOR_VER" eq 'ES11') {
				# hack because CUR_VENDOR_VER doesn't actually contain the minor 
				# version any more...
				my $CUR_VENDOR_MINOR_VER = `grep PATCHLEVEL /etc/SuSE-release | cut -d' ' -f 3`;
				chop($CUR_VENDOR_MINOR_VER);
				if ($CUR_VENDOR_MINOR_VER eq '0' || $CUR_VENDOR_MINOR_VER eq '1') { $package="libstdc++43-devel"; }
				if ($CUR_VENDOR_MINOR_VER eq '2' ) { $package="libstdc++46-devel"; }
				if ($CUR_VENDOR_MINOR_VER eq '3') { $package="libstdc++47-devel"; }
				# TBD - openSUSE has libstdc++42-devel
				# TBD - openSUSE11.2 has libstdc++44-devel
			}

			# distro specific naming of sysfsutils
			if ("$package" eq "sysfsutils" ) {
				if ("$CUR_DISTRO_VENDOR" ne 'SuSE' && "$CUR_DISTRO_VENDOR" ne 'redhat'
			    	&& "$CUR_DISTRO_VENDOR" ne 'fedora' && "$CUR_DISTRO_VENDOR" ne 'rocks') {
					$package="libsysfs";
				} elsif (($CUR_DISTRO_VENDOR eq "redhat" and $CUR_VENDOR_VER eq "ES6")) {
        			$package = "libsysfs";
				}
			}

			# distro specific naming of sysfsutils-devel
			# RHEL4 used sysfsutils-devel
			# RHEL6 uses libsysfs
			# SuSE uses sysfsutils
			# others use libsysfs-devel
			if ("$package" eq "sysfsutils-devel" ) {
				if (($CUR_DISTRO_VENDOR eq "SuSE")
					or ($CUR_DISTRO_VENDOR eq "redhat" and $CUR_VENDOR_VER eq "ES5")
	) {
        			$package = "sysfsutils";
				} elsif (($CUR_DISTRO_VENDOR eq "redhat" and $CUR_VENDOR_VER eq "ES6")) {
        			$package = "libsysfs";
    			} elsif (($CUR_DISTRO_VENDOR eq "rocks") or
        			($CUR_DISTRO_VENDOR eq "fedora") or
        			($CUR_DISTRO_VENDOR eq "redhat")) {
        				$package = "sysfsutils-devel";
    			} else {
        			$package = "libsysfs-devel";
    			}

			}

			if ("$pkgmode" eq "user") {
				# SLES10 and 11 -64bit rpms report ppc as ARCH
				$package="$package$suffix_64bit";
				if ( "$suffix_64bit" ne "" ) {
					$pkgmode="any";
				}
			}
			if (! rpm_is_installed($package, $pkgmode)) {
				if ( $errmessage ne "") {
					$errmessage="$errmessage\n OR ";
				}
				$errmessage = "$errmessage$package ($last_checked)";
			#} elsif ("$version" ne "" && "$version" ne "any") {
			#	# TBD - could be multiple versions of package installed
			#	# in which case this returns merged strings, not good
			#	my $ver = rpm_query_attr_pkg($package, "VERSION");
			#	TBD - string compare not the same as proper numeric compare
			#	if ($ver lt $version) {
			#		if ( $errmessage ne "") {
			#			$errmessage="$errmessage\n OR ";
			#		}
			#		$errmessage = "$errmessage$package version $version ($last_checked)";
			#	}
			} else {
				$errmessage="";
				last;
			}
		}
		if ( $errmessage ne "" ) {
			if (scalar(@alternatives) > 1) {
				$errmessage="$errmessage\n";
			}
			NormalPrint("$errmessage is required$message\n");
			$err++;
		}
	}
	return $err;
}

sub rpm_check_os_prereqs($$)
{
        no strict 'refs';
        my $comp = shift();
        my $mode = shift();
        my $list_name;
        my $array_ref;
        my @rpm_list = {};
        my $prereq_check = 0;

        if ( ! $rpm_check_dependencies ) {
                return 0;
        }

        $list_name=$comp."_prereq";
        $array_ref = $comp_prereq_hash{$list_name};
	#checking if prereq array exists
	#it assumed that it has no prereqs it array does not exist
        if ( $array_ref ) {
                @rpm_list = @{ $array_ref };
        }
        else{
                return 0;
        }

	#checking whether each entry in rpm_list is installed
        DebugPrint "Checking prereqs for $comp\n";
        foreach (@rpm_list){
                DebugPrint "Checking installation of $_\n";
		#Don't check dependencies for kernel RPMS if their installation is skipped
		if($skip_kernel == 1){
                	if( "$_" =~ /kernel/ || "$_" =~ /kmod/ || "$_" eq "pciutils" ) {
				DebugPrint("Skipping check for $_ \n");
				next;
			}
		}
                if(!rpm_is_installed($_, $mode)){
                        NormalPrint("--> $comp requires $_ \n");
                        $prereq_check = 1;
                }
        }

        return $prereq_check;
}


sub rpm_check_build_os_prereqs($$@)
{
	my $mode = shift();
	my $build_info = shift();
	my(@package_list) = @_;	# package names
	return rpm_check_os_prereqs_internal($mode, " to build $build_info", @package_list);
}

# get list of package rpms installed
# the list could include multiple versions and/or multiple architectures
# and/or multiple kernel releases
# all entries in returned list are complete package names in the form:
#	NAME-VERSION-RELEASE.ARCH
sub rpms_installed_pkg($$)
{
	my $package=shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed

	my @lines=();
	my $cpu;

	( $mode, $cpu ) = rpm_adjust_mode_cpu($package, $mode);
	if ( "$mode" eq "any" ) {
		DebugPrint("chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null\n");
		open(rpms, "chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null|");
	} elsif ("$mode" eq "user" ) {
		DebugPrint("chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null|egrep '\.$cpu\$|\.noarch\$' 2>/dev/null\n");
		open(rpms, "chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null|egrep '\.$cpu\$|\.noarch\$' 2>/dev/null|");
	} else {
		# $mode is kernel rev, verify proper kernel version is installed
		# for kernel packages, RELEASE is kernel rev
		my $release = rpm_tr_os_version($mode);
		DebugPrint("chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null|egrep '-$release\.$cpu\$' 2>/dev/null\n");
		open(rpms, "chroot /$ROOT $RPM --queryformat '[%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n]' -q $package 2>/dev/null|egrep '-$release\.$cpu\$' 2>/dev/null|");
	}
	@lines=<rpms>;
	close(rpms);
	if ( $? != 0) {
		# query command failed, package must not be installed
		@lines=();
	}
	chomp(@lines);
	DebugPrint("package $package $mode: installed: @lines\n");
	return @lines;
}

# identify all possible variations of the package
sub rpm_variations($$)
{
	my $package=shift();
	my $mode = shift();	# "user", kernel rev or "any"
						# "any" checks if any variation of package is installed
	my @variations = ( $package );

	if ( ("$mode" eq "any" || "$mode" eq "user") && $suffix_64bit ne "") {
		@variations = (@variations, "$package$suffix_64bit");
	}
	return @variations;
}

# get list of package rpms installed
# the list could include multiple versions and/or multiple architectures
# and/or multiple kernel releases
# all entries in returned list are complete package names in the form:
#	NAME-VERSION-RELEASE.ARCH
sub rpms_variations_installed_pkg($$)
{
	my $package=shift();
	my $mode = shift();	

	my @result=();

	foreach my $p ( rpm_variations($package, $mode) ) {
		@result = ( @result, rpms_installed_pkg($p, $mode) );
	}
	return @result;
}

# determine if given rpm contains the given file
sub rpm_has_file($$)
{
	my($rpmfile) = shift();	# .rpm file
	my($file) = shift();		# file to look for in rpm

	if ( ! -f "$rpmfile" ) {
		return 0;
	}
	return (! system("$RPM -qlp $rpmfile 2>/dev/null | grep '/${file}\$' > /dev/null 2>&1"));
}

# return names of all installed RPMs matching the given partial name and filter
sub rpm_query_all($$)
{
	my $package = shift();
	my $filter = shift();

	my $res=`chroot /$ROOT $RPM -qa 2>/dev/null|grep -i '$package'|grep '$filter'`;
	$res=~s/\n/ /g;
	return $res;
}

# uninstall all packages which match package partial name and filter
# returns 0 on sucess (or package not installed), != 0 on failure
sub rpm_uninstall_matches($$$;$)
{
	my $name = shift();	# for use only in log messages
	my $package = shift();	# part of package name
	my $filter = shift();	# any additional grep filter
	my $options = shift();	# additional rpm command options
	my $rpms = rpm_query_all("$package", "$filter");

	if ( "$rpms" ne "" ) {
		LogPrint "uninstalling $name: $RPM -e $rpms\n";
		my $out =`chroot /$ROOT $RPM -e $options $rpms 2>&1`;
		my $rc=$?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
		return $rc;
	} else {
		return 0;
	}
}

sub rpm_run_install($$$)
{
	my($rpmfile) = shift();	# .rpm file
	my $mode = shift();	# "user" or kernel rev
						# "any"- will install any variation found
	my($options) = shift();	# additional rpm command options
						# if " -U " is part of these options, -U will be
						# unconditionally used, even if the rpm is not
						# already installed.  Otherwise -U will only be
						# used if the rpm is installed.  Note that some OFED
						# rpms do not properly handle -U for actual upgrades.
						# Hence for OFED we tend to uninstall the old rpms first
						# and the rpm -i is used to install here.

	my $chrootcmd="";
	my $Uoption= 0;

	if ($skip_kernel && "$mode" ne "user" && "$mode" ne "any") {
		return;
	} elsif ($skip_kernel && $rpmfile =~ /\/hfi1-firmware/) {
		return;
	}

	# We require whitespace around -U so its not mistaken for filenames or other
	# multi-letter options
	if ($options =~ / -U /) {
		$Uoption=1;
		$options =~ s/ -U //;
	}
	
	if ( ! -e $rpmfile ) {
		NormalPrint "Not Found: $rpmfile $mode\n";
		return;
	}

	if (ROOT_is_set()) {
		LogPrint "  cp $rpmfile $ROOT/var/tmp/rpminstall.tmp.rpm\n";
		if (0 != system("cp $rpmfile $ROOT/var/tmp/rpminstall.tmp.rpm")) {
			LogPrint "Unable to copy $rpmfile $ROOT/var/tmp/rpminstall.tmp.rpm\n";
			return;
		}
		# just to new ROOT relative name for use in commands below
		$rpmfile = "/var/tmp/rpminstall.tmp.rpm";
		$chrootcmd="chroot $ROOT ";
	}

	my $package = rpm_query_name($rpmfile);
	my $fullname = rpm_query_full_name($rpmfile);
	my $out;

	NormalPrint "installing ${fullname}...\n";

	my $upgrade=rpm_is_installed($package, $mode);
	if ( ! $upgrade ) {
		my @obsoletes = split /[[:space:]]+/, `$RPM --queryformat '[%{OBSOLETES}\\n]' -qp $rpmfile 2>/dev/null`;
		for my $p ( @obsoletes ) {
			next if ( "$p" eq "(none)" );	
			$upgrade |= rpm_is_installed($p, $mode);
			if ($upgrade) {
				last;
			}
		}
	}

	if( $Uoption || $upgrade ) {	
		# -U option will only update this exact package and architecture
		# when multiple architectures are installed, other architecture rpms
		# are not affected by -U, however --force is needed in that case
		# also need --force for reinstall case
		LogPrint "  $chrootcmd$RPM -U --force $options $rpmfile\n";
		$out=`$chrootcmd$RPM -U --force $options $rpmfile 2>&1`;
		if ( $? == 0 ) {
			NormalPrint("$out");
		} else {
			NormalPrint("ERROR - Failed to install $rpmfile\n");
			NormalPrint("$out");
			$exit_code = 1;
			HitKeyCont;
		}

	} else {
		# initial install of rpm
		# force not required, even if other architectures already installed
		if ("$ARCH" eq 'PPC64') {
			# PPC64 SLES10 needs --force
			$options='--force '."$options";
		}
		LogPrint "  $chrootcmd$RPM -i $options $rpmfile\n";
		$out=`$chrootcmd$RPM -i $options $rpmfile 2>&1`;
		if ( $? == 0 ) {
			NormalPrint("$out");
		} else {
			NormalPrint("ERROR - Failed to install $rpmfile\n");
			NormalPrint("$out");
			$exit_code = 1;
			HitKeyCont;
		}
	}
	if (ROOT_is_set()) {
		system("rm -f $ROOT/var/tmp/rpminstall.tmp.rpm");
	}
}

# returns 0 on sucess (or package not installed), != 0 on failure
# uninstalls all variations of given package
sub rpm_uninstall($$$$)
{
	my($package) = shift();	# package name
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my($options) = shift();	# additional rpm command options
	my($verbosity) = shift();	# verbose or silent
	my @fullnames = rpms_variations_installed_pkg($package, $mode); # already adjusts mode
	my $rc = 0;
	foreach my $fullname (@fullnames) {
		if ( "$verbosity" ne "silent" ) {
			print "uninstalling ${fullname}...\n";
		}
		LogPrint "chroot /$ROOT $RPM -e $options $fullname\n";
		my $out=`chroot /$ROOT $RPM -e $options $fullname 2>&1`;
		$rc |= $?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
	}
	return $rc;
}

# resolve rpm package filename within $rpmdir for $mode
sub rpm_resolve($$$)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- any variation found
	my $package = shift();	# package name
	my $rpmfile;
	my $cpu;

	( $mode, $cpu ) = rpm_adjust_mode_cpu($package, $mode);
	if ("$mode" eq "user" ) {
		# we expect 0-1 match, ignore all other filenames returned
		DebugPrint("Checking for User Rpm: $rpmdir/${package}-[0-9]*.${cpu}.rpm\n");
		$rpmfile = file_glob("$rpmdir/${package}-[0-9]*.${cpu}.rpm");
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for User Rpm: $rpmdir/${package}-r[0-9]*.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-r[0-9]*.${cpu}.rpm");
		}
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for User Rpm: $rpmdir/${package}-trunk-[0-9]*.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-trunk-[0-9]*.${cpu}.rpm");
		}
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			# we expect 0-1 match, ignore all other filenames returned
			DebugPrint("Checking for User Rpm: $rpmdir/${package}-[0-9]*.noarch.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-[0-9]*.noarch.rpm");
			if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
				DebugPrint("Checking for User Rpm: $rpmdir/${package}-r[0-9]*.noarch.rpm\n");
				$rpmfile = file_glob("$rpmdir/${package}-r[0-9]*.noarch.rpm");
			}
			if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
				DebugPrint("Checking for User Rpm: $rpmdir/${package}-trunk-[0-9]*.noarch.rpm\n");
				$rpmfile = file_glob("$rpmdir/${package}-trunk-[0-9]*.noarch.rpm");
			}
		}
	} elsif ("$mode" eq "any" ) {
		# we expect 0-1 match, ignore all other filenames returned
		DebugPrint("Checking for User Rpm: $rpmdir/${package}-[0-9]*.*.rpm\n");
		$rpmfile = file_glob("$rpmdir/${package}-[0-9]*.*.rpm");
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for User Rpm: $rpmdir/${package}-r[0-9]*.*.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-r[0-9]*.*.rpm");
		}
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for User Rpm: $rpmdir/${package}-trunk-[0-9]*.*.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-trunk-[0-9]*.*.rpm");
		}
	} else {
		my $osver = rpm_tr_os_version("$mode");	# OS version
		# we expect 1 match, ignore all other filenames returned
		if ( "$CUR_VENDOR_VER" eq 'ES122' ) {
			DebugPrint("Checking for Kernel Rpm: $rpmdir/${package}-${osver}_k*.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-${osver}_k*.${cpu}.rpm");
		} else {
			DebugPrint("Checking for Kernel Rpm: $rpmdir/${package}-[0-9]*.[0-9][0-9].${osver}-[0-9]*.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-[0-9]*.[0-9][0-9].${osver}-[0-9]*.${cpu}.rpm");
		}
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for Kernel Rpm: $rpmdir/${package}-${osver}-[0-9]*.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-${osver}-[0-9]*.${cpu}.rpm");
		}
		if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
			DebugPrint("Checking for Kernel Rpm: $rpmdir/${package}-trunk-[0-9]*-${osver}.${cpu}.rpm\n");
			$rpmfile = file_glob("$rpmdir/${package}-trunk-[0-9]*-${osver}.${cpu}.rpm");
		}
	}
	VerbosePrint("Resolved $package $mode: $rpmfile\n");
	return $rpmfile;
}

sub rpm_exists($$$)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- any variation found
	my $package = shift();	# package name
	my $rpmfile;

	$rpmfile = rpm_resolve($rpmdir, $mode, $package);
	return ("$rpmfile" ne "" && -e "$rpmfile");
}

sub rpm_install($$$)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- will install any variation found
	my $package = shift();	# package name
	my $rpmfile;

	# use a different directory for BUILD_ROOT to limit conflict with OFED
	my $build_temp = "/var/tmp/IntelOPA-DELTA";
	my $BUILD_ROOT="$build_temp/build";
	my $RPM_DIR="$build_temp/DELTARPMS";
	my $RPMS_SUBDIR = "RPMS";
	my $prefix=$OFED_prefix;

	if ($skip_kernel && "$mode" ne "user" && "$mode" ne "any") {
		return;
	} elsif ($skip_kernel && $rpmfile =~ /\/hfi1-firmware/) {
		return;
	}

RPM_RES:

	$rpmfile = rpm_resolve($rpmdir, $mode, $package);
	if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
		NormalPrint "Not Found: $package $mode\n";
		if ( "$mode" ne "user" && "$mode" ne "any" ) # kernel mode
		{
			NormalPrint "Rebuilding $package SRPM $mode\n";
			if (0 == build_srpm($package, $RPM_DIR, $BUILD_ROOT, $prefix, "append")) {
				delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmdir");
				goto RPM_RES;
			}
		}
	} else {
		if ("$mode" eq "user" || "$mode" eq "any" ) {
			rpm_run_install($rpmfile, $mode, "");
		} else {
			# kernel install
			if ("$CUR_DISTRO_VENDOR" eq 'SuSE') {
				# ofed1.3 only uses --nodeps on SuSE to workaround ksym
				# dependencies.
				rpm_run_install($rpmfile, $mode, "--nodeps");
			} else {
				rpm_run_install($rpmfile, $mode, "");
			}
		}
	}
}

sub rpm_install_with_options($$$$)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- will install any variation found
	my $package = shift();	# package name
	my($options) = shift();	# additional rpm command options
	my $rpmfile;

	# use a different directory for BUILD_ROOT to limit conflict with OFED
	my $build_temp = "/var/tmp/IntelOPA-DELTA";
	my $BUILD_ROOT="$build_temp/build";
	my $RPM_DIR="$build_temp/DELTARPMS";
	my $RPMS_SUBDIR = "RPMS";
	my $prefix=$OFED_prefix;

	if ($skip_kernel && "$mode" ne "user" && "$mode" ne "any") {
		return;
	} elsif ($skip_kernel && $rpmfile =~ /\/hfi1-firmware/) {
		return;
	}

RPM_RES:

	$rpmfile = rpm_resolve($rpmdir, $mode, $package);
	if ( "$rpmfile" eq "" || ! -e "$rpmfile" ) {
		NormalPrint "Not Found: $package $mode\n";
		if ( "$mode" ne "user" && "$mode" ne "any" ) # kernel mode
		{
			NormalPrint "Rebuilding $package SRPM $mode\n";
			if (0 == build_srpm($package, $RPM_DIR, $BUILD_ROOT, $prefix, "append")) {
				delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmdir");
				goto RPM_RES;
			}
		}
	} else {
		if ("$mode" eq "user" || "$mode" eq "any" ) {
			rpm_run_install($rpmfile, $mode, $options);
		} else {
			# kernel install
			if ("$CUR_DISTRO_VENDOR" eq 'SuSE' && 
			    $options !~ / --nodeps /) {
				# ofed1.3 only uses --nodeps on SuSE to workaround ksym
				# dependencies.
				rpm_run_install($rpmfile, $mode, "--nodeps $options");
			} else {
				rpm_run_install($rpmfile, $mode, $options);
			}
		}
	}
}

# verify the rpmfiles exist for all the RPMs listed
sub rpm_exists_list($$@)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- any variation found
	my(@package_list) = @_;	# package names

	foreach my $package ( @package_list )
	{
		if (! rpm_exists($rpmdir, $mode, $package) ) {
			return 0;
		}
	}
	return 1;
}

sub rpm_install_list($$@)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- will install any variation found
	my(@package_list) = @_;	# package names

	foreach my $package ( @package_list )
	{
		rpm_install($rpmdir, $mode, $package);
	}
}

sub rpm_install_list_with_options($$$@)
{
	my $rpmdir = shift();
	my $mode = shift();	# "user" or kernel rev
						# "any"- will install any variation found
	my($options) = shift();	# additional rpm command options
	my(@package_list) = @_;	# package names

	foreach my $package ( @package_list )
	{
		rpm_install_with_options($rpmdir, $mode, $package, $options);
	}
}

# returns 0 on success (or rpms not installed), != 0 on failure
sub rpm_uninstall_list2($$$@)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my($options) = shift();	# additional rpm command options
	my($verbosity) = shift();	# verbose or silent
	my(@package_list) = @_;	# package names
	my $package;
	my $ret = 0;	# assume success

	foreach $package ( reverse(@package_list) )
	{
		$ret |= rpm_uninstall($package, $mode, $options, $verbosity);
	}
	return $ret;
}

# returns 0 on success (or rpms not installed), != 0 on failure
sub rpm_uninstall_list($$@)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my($verbosity) = shift();	# verbose or silent
	my(@package_list) = @_;	# package names

	return rpm_uninstall_list2($mode, "", $verbosity, (@package_list));
}


# uninstall all rpms which match any of the supplied package names
# and based on mode and distro/cpu.
# uninstall is done in a single command so dependency issues handled
# returns 0 on success (or rpms not installed), != 0 on failure
sub rpm_uninstall_all_list($$@)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my($verbosity) = shift();	# verbose or silent
	my(@package_list) = @_;	# package names
	my @uninstall = ();
	my $options = "";

	if ("$mode" eq "any") {
		$options = "--allmatches";
	}
	foreach my $package ( @package_list )
	{
		foreach my $p ( rpm_variations($package, $mode) )
		{
			if (rpm_is_installed($p, $mode)) {
				if ("$mode" eq "any") {
					@uninstall = (@uninstall, $p);
				} else {
					@uninstall = (@uninstall, rpms_installed_pkg($p, $mode));
				}
			}
		}
	}
	
	if (scalar(@uninstall) != 0) {
		LogPrint "chroot /$ROOT $RPM -e $options @uninstall\n";
		my $out=`chroot /$ROOT $RPM -e $options @uninstall 2>&1`;
		my $rc=$?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
		return $rc;
	} else {
		LogPrint "None Found\n";
		return 0;	# nothing to do
	}
}

# uninstall all rpms which match any of the supplied package names
# and based on mode and distro/cpu, 
# uninstall is done in a single command
# returns 0 on success (or rpms not installed), != 0 on failure
# Force to uninstall without any concern for dependency.
sub rpm_uninstall_all_list_with_options($$$@)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my($options) = shift();	# additional rpm command options
	my($verbosity) = shift();	# verbose or silent
	my(@package_list) = @_;	# package names
	my @uninstall = ();

	if ("$mode" eq "any") {
		$options .= "--allmatches";
	}
	foreach my $package ( @package_list )
	{
		foreach my $p ( rpm_variations($package, $mode) )
		{
			if (rpm_is_installed($p, $mode)) {
				if ("$mode" eq "any") {
					@uninstall = (@uninstall, $p);
				} else {
					@uninstall = (@uninstall, rpms_installed_pkg($p, $mode));
				}
			}
		}
	}
	
	if (scalar(@uninstall) != 0) {
		LogPrint "chroot /$ROOT $RPM -e $options @uninstall\n";
		my $out=`chroot /$ROOT $RPM -e $options @uninstall 2>&1`;
		my $rc=$?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
		return $rc;
	} else {
		LogPrint "None Found\n";
		return 0;	# nothing to do
	}
}

# see if prereqs for building kernel modules are installed
# return 0 on success, 1 if missing dependencies
sub check_kbuild_dependencies($$)
{
	my $osver = shift();	# kernel rev
	my $srpm = shift();	# what trying to build
	my $dir = "/lib/modules/$osver/build";

	if ( ! $rpm_check_dependencies ) {
		return 0;
	}
	if ( ! -d "$dir/scripts" ) {
		NormalPrint "Unable to build $srpm: $dir/scripts: not found\n";
		NormalPrint "kernel-source or kernel-devel is required to build $srpm\n";
		return 1;	# failure
	}
	return 0;
}

# see if basic prereqs for building RPMs are installed
# return 0 on success, or number of missing dependencies
sub check_rpmbuild_dependencies($)
{
	my $srpm = shift();	# what trying to build
	my $err = 0;

	if ("$CUR_DISTRO_VENDOR" eq 'redhat') {
		if (! rpm_is_installed("rpm-build", "any") ) {
			NormalPrint("rpm-build ($last_checked) is required to build $srpm\n");
			$err++;
		}
	}
	if ( "$CUR_DISTRO_VENDOR" ne "SuSE" && rpm_will_build_debuginfo()) {
		if (! rpm_is_installed("redhat-rpm-config", "any")) {
			NormalPrint("redhat-rpm-config ($last_checked) is required to build $srpm\n");
			$err++;
		}
	}
	return $err;
}

# see if basic prereqs for building are installed
# return 0 on success, or number of missing dependencies
sub check_build_dependencies($)
{
	my $build_info = shift();	# what trying to build
	my $err = 0;

	$err = rpm_check_build_os_prereqs('user', $build_info, ('glibc-devel'));
	return $err;
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =============================================================================
# The functions and constants below assist in doing builds such as via rpmbuild

# The functions below assume a hash of build options.  A sample is shown below
#my %ofed_kernel_ib_options = (
#	# build option		# arch & kernels supported on
#	"--with-core-mod" => "",	# supported on all
#	"--with-ehca-mod" => "PPC 2\.6\.1[6-9].* 2\.6\.20.* 2\.6\.9-55\.
#							PPC64 2\.6\.1[6-9].* 2\.6\.20.* 2\.6\.9-55\.",
#	"--with-iser-mod" => "ALL 2\.6\.16\..*-.*-.* 2\.6\..*\.el5 2\.6\.9-[3-5].*\.EL.*",
#		# all kernels except 2.6.5*  note .* wildcard need as 2nd kernelpat
#	"--with-rds-mod" => "ALL !2\.6\.5.* .*",
#	"--without-ipoibconf" => "NONE",	# essentially a comment
#			# DAPL not supported for PPC64
#	"--with-dapl" => "!PPC64",	# any kernel for !PPC64
#);

# The arch & kernels specification is quite flexible.
#
# special formats:
# 		"" -> always use option (any arch, any kernels)
# 		"NONE" -> never use option, no remaining lines are processed
#
# typical format is one line per arch, separated by newline (inside string):
# 		"arch1 kernelpat1 kernelpat2
#			arch2 kernelpat3"
# leading spaces and tabs ignored before arch
#
# arch format:
#	exact ARCH value (IA32, PPC, X86_64, etc)
#	ALL - remainder of line applies to all architectures
#			if no matches for kernel are found on this line, continues to later
#			lines
#	!arch - remainder of line applies to all architectures except arch
#			if no matches for kernel are found on this line, continues to later
#			lines.  If no kernels listed, applies to any kernel.
#	if for a given arch line, no kernels are specified, it matches any kernels
#
# kernelpat format:
#	"" -> (eg. no kernelpat specified for arch), option applies to any kernel
#			for given arch
#	 - all patterns are regex style
#		beware: . is a wildcard unless \. used
#	- !kernelpat means not on kernel, unlike !arch this indicates option is
#		not appliable to this specific kernel, but does not affect other kernels

# process osver and $ARCH against the list of allowed kernel/arch for
# a given build option to decide if option allowed for given kernel/arch
sub arch_kernel_is_allowed($$)
{
	my $osver = shift();
	my $archs = shift();

	if ( "$archs" eq "" ) {
		# option applicable to all archs all kernels
		DebugPrint "yes\n";
		return 1;
	} else {
		# newlines separate details of each arch
		my @arch_list = split /\n/, $archs;
		foreach my $archdetails ( @arch_list ) {
			# spaces separate arch and each kernelpattern
			# ignore leading and trailing tabs/spaces
			$archdetails =~ s/^[ 	]*//;	# remove leading
			$archdetails =~ s/[ 	]*$//;	# remove trailing
			# all other whitespace is just separators
			my @archkernels = split /[[:space:]]+/,$archdetails;
			# arch is 1st, rest are kernelpatterns
			my $arch = $archkernels[0];
			shift @archkernels;
			if ( "$arch" eq "NONE" ) {
				DebugPrint "no\n";
				return 0;
			} elsif ( "$ARCH" eq "$arch" || "ALL" eq "$arch"
				|| (substr($arch,0,1) eq "!" && "$ARCH" ne substr($arch,1)) ) {
				if (scalar(@archkernels) == 0) {
					# option applicable to all kernels for arch
					DebugPrint "yes\n";;
					return 1;
				} else {
					# list of kernel patterns specified
					foreach my $kernelpattern ( @archkernels ) {
#print "check $kernelpattern\n";
						if (substr($kernelpattern,0,1) eq "!") {
							$kernelpattern = substr($kernelpattern, 1);
							if ( $osver =~ /^$kernelpattern$/ ) {
								# option not available on this kernel
								DebugPrint "no\n";
								return 0;
							}
						} elsif ( $osver =~ /^$kernelpattern$/ ) {
							# option applicable to this kernel for arch
							DebugPrint "yes\n";
							return 1;
						}
					}
				}
			}
		}
	}
	DebugPrint "no\n";
	return 0;	# not specified
}

# given a build option and a kernel, decide if applicable to ARCH and kernel
# based on lookup in build_options hash
sub build_option_is_allowed($$@)
{
	my $osver = shift();
	my $build_option = shift();
	my(%build_options) = @_;	# list of options and when valid

	return arch_kernel_is_allowed($osver, $build_options{$build_option});
}

# based on $osver and $ARCH decide what build options to use
sub get_build_options($@)
{
	my $osver = shift();
	my(@build_options) = @_;	# list of options and when valid

	my $ret = "";
	my $i;
	for($i=0; $i < scalar(@build_options); $i += 2) {
		my $option = $build_options[$i];
		my $archs = $build_options[$i+1];
		if (arch_kernel_is_allowed($osver, $archs)) {
			DebugPrint "Check $option - yes\n";
			$ret="$ret $option";
		} else {
			DebugPrint "Check $option - no\n";
		}
	}
	return "$ret";
}

# execute build_cmd within srcdir
# note builds are done on local image not in $ROOT
# return 0 on success, != 0 on failure
sub run_build($$$$)
{
	my $message= shift();	# message for building output
	my $srcdir= shift();
	my $build_cmd= shift();
	my $resfileop= shift();	# "append" or "replace"

	my $rc;
	my $shfileop;
	
	if ( "$resfileop" eq "append" ) {
		$shfileop = ">>";
	} else {
		$shfileop = ">";
	}

	NormalPrint "Building $message...";

	LogPrint "\n  cd $srcdir; $build_cmd $shfileop build.res 2>&1\n";
	$rc=system "cd $srcdir; $build_cmd $shfileop build.res 2>&1";
	if ( $rc != 0 ) {
		NormalPrint "\nERROR - FAILED to build $message, see $srcdir/build.res\n";
		# TBD system("cat $srcdir/build.res >> $LogFile");
	} else {
		NormalPrint " done\n";
	}
	return $rc;
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;

my $Default_FirmwareUpgradeMode="";	# --fwupdate option
#  "" - normal operation for upgrade
#  "asneeded" - force update to this rev unless already on HCA
#  "always" - force update to this rev

sub update_hca_firmware()
{
	print("Firmware Update unnecessary\n");
    HitKeyCont;
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

#[ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
use File::Basename;

#############################################################################
##
##    MPI installation generic functions

# these functions can be used by the MPI specific install functions

# installs PSM based MPI component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_generic_mpi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];
    my $mpiname = $_[2];
    my $compiler = $_[3];
    my $mpifullname = "$mpiname"."_$compiler"."_hfi";
    my $srcdir = $ComponentInfo{$mpifullname}{'SrcDir'};
    my $version = eval "media_version_$mpifullname()";
    
    printf ("Installing $ComponentInfo{$mpifullname}{'Name'} $version...\n");
    LogPrint ("Installing $ComponentInfo{$mpifullname}{'Name'} $version for $CUR_OS_VER\n");
    # make sure any old potentially custom built versions of mpi are uninstalled
    my @list = ( "$mpifullname", "mpitests_$mpifullname" );
    rpm_uninstall_list2("any", "--nodeps", 'silent', @list);
    
    my $rpmfile = rpm_resolve("$srcdir", "any", "$mpifullname");
    if ( "$rpmfile" ne "" && -e "$rpmfile" ) {
	my $mpich_prefix= "/usr/mpi/$compiler/$mpiname-"
	    . rpm_query_attr($rpmfile, "VERSION") . "-hfi";
	if ( -d "$mpich_prefix" ) {
	    if (GetYesNo ("Remove $mpich_prefix directory?", "y")) {
		LogPrint "rm -rf $mpich_prefix\n";
		system("rm -rf $mpich_prefix");
	    }
	}
    }
    # enable this code if mpitests is missing for some compilers or MPIs
    #my $mpitests_rpmfile = rpm_resolve("$srcdir/OtherMPIs", "any", "mpitests_$mpifullname");
    #if ( "$mpitests_rpmfile" ne "" && -e "$mpitests_rpmfile" ) {
        rpm_install_list_with_options ("$srcdir", "user", " -U --nodeps ", @list);
    #} else {
    #    rpm_install("$srcdir/OtherMPIs", "user", "$mpifullname");
    #}
    check_dir ("/opt/iba");
    copy_systool_file ("$srcdir/comp.pl", "/usr/lib/opa/.comp_$mpifullname.pl");
    
    $ComponentWasInstalled{$mpifullname} = 1;
}

sub installed_generic_mpi
{
    my $mpiname = $_[0];
    my $compiler = $_[1];
    my $mpifullname = "$mpiname"."_$compiler"."_hfi";

    return ( -e "$ROOT/usr/lib/opa/.comp_$mpifullname.pl"
		   	|| rpm_is_installed ($mpifullname, "user") );
}

sub uninstall_generic_mpi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];
    my $mpiname = $_[2];
    my $compiler = $_[3];
    my $mpifullname = "$mpiname"."_$compiler"."_hfi";
    my $rc;
    my $top;
    
    NormalPrint ("Uninstalling $ComponentInfo{$mpifullname}{'Name'}...\n");
    if (lc($CUR_DISTRO_VENDOR) eq "redhat" &&
	($CUR_VENDOR_VER eq "ES6" || $CUR_VENDOR_VER eq "ES6.1")) {
	$top = rpm_query_attr_pkg("$mpifullname", "INSTPREFIXES");
    } else {
	$top = rpm_query_attr_pkg("$mpifullname", "INSTALLPREFIX");
    }
    if ($top eq "" || $top =~ /is not installed/) {
	$top = undef;
    } else {
	$top = `dirname $top`;
	chomp $top;
    }
    
    # uninstall tests in case built by do_build
    $rc = rpm_uninstall ("mpitests_$mpifullname", "user", "", "verbose");
    $rc = rpm_uninstall ($mpifullname, "user", "", "verbose");

    if ( -d $top ) {
	my @files = glob("$top/*");
	my $num = scalar (@files);
	if ( $num == 0 ) {
	    system ("rm -rf $top");
	}
    }
    
    system ("rm -rf $ROOT/usr/lib/opa/.comp_$mpifullname.pl");
    system ("rmdir $ROOT/usr/lib/opa 2>/dev/null"); # remove only if empty
    $ComponentWasInstalled{$mpifullname} = 0;
}

#############################################################################
##
##    OpenMPI GCC

# immediately stops or starts given component, only
# called if HasStart
sub start_openmpi_gcc_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_openmpi_gcc_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_openmpi_gcc_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_gcc_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "openmpi_gcc_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_openmpi_gcc_hfi
{
    return  installed_generic_mpi("openmpi", "gcc");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_openmpi_gcc_hfi
{
    return rpm_query_version_release_pkg ("openmpi_gcc_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_openmpi_gcc_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_gcc_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "openmpi_gcc_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_openmpi_gcc_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_openmpi_gcc_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_openmpi_gcc_hfi
{
	return rpm_check_os_prereqs("openmpi_gcc_hfi", "user");
}

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_openmpi_gcc_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_openmpi_gcc_hfi
{
    install_generic_mpi("$_[0]", "$_[1]", "openmpi", "gcc");
}

# called after all components are installed.
sub postinstall_openmpi_gcc_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_openmpi_gcc_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "openmpi", "gcc");
}

#############################################################################
##
##    OpenMPI Intel

# immediately stops or starts given component, only
# called if HasStart
sub start_openmpi_intel_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_openmpi_intel_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_openmpi_intel_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_intel_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "openmpi_intel_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_openmpi_intel_hfi
{
    return  installed_generic_mpi("openmpi", "intel");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_openmpi_intel_hfi
{
    return rpm_query_version_release_pkg ("openmpi_intel_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_openmpi_intel_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_intel_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "openmpi_intel_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_openmpi_intel_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_openmpi_intel_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_openmpi_intel_hfi
{
	return rpm_check_os_prereqs("openmpi_intel_hfi", "user");
}

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_openmpi_intel_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_openmpi_intel_hfi
{
    install_generic_mpi("$_[0]", "$_[1]", "openmpi", "intel");
}

# called after all components are installed.
sub postinstall_openmpi_intel_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_openmpi_intel_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "openmpi", "intel");
}

#############################################################################
##
##    OpenMPI PGI

# immediately stops or starts given component, only
# called if HasStart
sub start_openmpi_pgi_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_openmpi_pgi_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_openmpi_pgi_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_pgi_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "openmpi_pgi_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_openmpi_pgi_hfi
{
    return  installed_generic_mpi("openmpi", "pgi");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_openmpi_pgi_hfi
{
    return rpm_query_version_release_pkg ("openmpi_pgi_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_openmpi_pgi_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_pgi_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "openmpi_pgi_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_openmpi_pgi_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_openmpi_pgi_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_openmpi_pgi_hfi
{
	return rpm_check_os_prereqs("openmpi_pgi_hfi", "user");
}

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_openmpi_pgi_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_openmpi_pgi_hfi
{
	install_generic_mpi("$_[0]", "$_[1]", "openmpi", "pgi");
}

# called after all components are installed.
sub postinstall_openmpi_pgi_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_openmpi_pgi_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "openmpi", "pgi");
}

#############################################################################
##
##    MVAPICH2 GCC

# immediately stops or starts given component, only
# called if HasStart
sub start_mvapich2_gcc_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_mvapich2_gcc_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_mvapich2_gcc_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_gcc_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "mvapich2_gcc_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_mvapich2_gcc_hfi
{
    return  installed_generic_mpi("mvapich2", "gcc");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_mvapich2_gcc_hfi
{
    return rpm_query_version_release_pkg ("mvapich2_gcc_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_mvapich2_gcc_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_gcc_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "mvapich2_gcc_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_mvapich2_gcc_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_mvapich2_gcc_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_mvapich2_gcc_hfi
{
	return rpm_check_os_prereqs("mvapich2_gcc_hfi", "user");
}                              

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_mvapich2_gcc_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_mvapich2_gcc_hfi
{
	install_generic_mpi("$_[0]", "$_[1]", "mvapich2", "gcc");
}

# called after all components are installed.
sub postinstall_mvapich2_gcc_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_mvapich2_gcc_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "mvapich2", "gcc");
}

#############################################################################
##
##    MVAPICH2 Intel

# immediately stops or starts given component, only
# called if HasStart
sub start_mvapich2_intel_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_mvapich2_intel_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_mvapich2_intel_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_intel_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "mvapich2_intel_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_mvapich2_intel_hfi
{
    return  installed_generic_mpi("mvapich2", "intel");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_mvapich2_intel_hfi
{
    return rpm_query_version_release_pkg ("mvapich2_intel_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_mvapich2_intel_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_intel_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "mvapich2_intel_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_mvapich2_intel_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_mvapich2_intel_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_mvapich2_intel_hfi
{
	# we allow this to install even if intel compiler runtime not available
	return rpm_check_os_prereqs("mvapich2_intel_hfi", "user");
}                              

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_mvapich2_intel_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_mvapich2_intel_hfi
{
	install_generic_mpi("$_[0]", "$_[1]", "mvapich2", "intel");
}

# called after all components are installed.
sub postinstall_mvapich2_intel_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_mvapich2_intel_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "mvapich2", "intel");
}

#############################################################################
##
##    MVAPICH2 PGI

# immediately stops or starts given component, only
# called if HasStart
sub start_mvapich2_pgi_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_mvapich2_pgi_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_mvapich2_pgi_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_pgi_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "mvapich2_pgi_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_mvapich2_pgi_hfi
{
    return  installed_generic_mpi("mvapich2", "pgi");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_mvapich2_pgi_hfi
{
    return rpm_query_version_release_pkg ("mvapich2_pgi_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_mvapich2_pgi_hfi
{
    my $srcdir = $ComponentInfo{'mvapich2_pgi_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "mvapich2_pgi_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_mvapich2_pgi_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_mvapich2_pgi_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_mvapich2_pgi_hfi
{
	# we allow this to install even if pgi compiler runtime not available
	return rpm_check_os_prereqs("mvapich2_pgi_hfi", "user");
}                              

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_mvapich2_pgi_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_mvapich2_pgi_hfi
{
	install_generic_mpi("$_[0]", "$_[1]", "mvapich2", "pgi");
}

# called after all components are installed.
sub postinstall_mvapich2_pgi_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_mvapich2_pgi_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "mvapich2", "pgi");
}



#############################################################################
###
#+##    OpenMPI GCC CUDA
#
# immediately stops or starts given component, only
# called if HasStart
sub start_openmpi_gcc_cuda_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub stop_openmpi_gcc_cuda_hfi
{
}

# is component X available on the install media (use of this
# allows for optional components in packaging or limited availability if a
# component isn't available on some OS/CPU combos)
sub available_openmpi_gcc_cuda_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_gcc_cuda_hfi'}{'SrcDir'};
    return rpm_exists ("$srcdir", "user", "openmpi_gcc_cuda_hfi");
}

# is component X presently installed on the system.  This is
# a quick check, not a "verify"
sub installed_openmpi_gcc_cuda_hfi
{
    return  installed_generic_mpi("openmpi", "gcc_cuda");
}

# what is the version installed on system.  Only
# called if installed_X is true.  versions are short strings displayed and
# logged, no operations are done (eg. only compare for equality)
sub installed_version_openmpi_gcc_cuda_hfi
{
    return rpm_query_version_release_pkg ("openmpi_gcc_cuda_hfi");
}

# only called if available_X.  Indicates version on
# media.  Will be compared with installed_version_X to determine if
# present installation is up to date.  Should return exact same format for
# version string so comparison of equality is possible.
sub media_version_openmpi_gcc_cuda_hfi
{
    my $srcdir = $ComponentInfo{'openmpi_gcc_cuda_hfi'}{'SrcDir'};
    my $rpm = rpm_resolve ("$srcdir", "user", "openmpi_gcc_cuda_hfi");
    return rpm_query_version_release ($rpm);
}

# used to build/rebuild component on local system (if
# supported).  We support this for many items in comp_ofed.pl
# Other components (like SM) are
# not available in source and hence do not support this and simply
# implement a noop.
sub build_openmpi_gcc_cuda_hfi
{
    my $osver = $_[0];
    my $debug = $_[1];
    my $build_temp = $_[2];
    my $force = $_[3];

    return 0;
}

# does this need to be reinstalled.  Mainly used for
# ofed due to subtle changes such as install prefix or kernel options
# which may force a reinstall.  You'll find this is a noop in most others.
sub need_reinstall_openmpi_gcc_cuda_hfi
{
    my $install_list = shift ();
    my $installing_list = shift ();

    return "no";
}

# called for all components before they are installed.  Use to verify OS
# has proper dependent rpms installed.
sub check_os_prereqs_openmpi_gcc_cuda_hfi
{
       return rpm_check_os_prereqs("openmpi_gcc_cuda_hfi", "user");
}

# called for all components before they are installed.  Use
# to build things if needed, etc.
sub preinstall_openmpi_gcc_cuda_hfi
{
    my $install_list = $_[0];
    my $installing_list = $_[1];

    my $full = "";
    my $rc;

    return 0;
}

# installs component.  also handles reinstall on top of
# existing installation and upgrade.
sub install_openmpi_gcc_cuda_hfi
{
    install_generic_mpi("$_[0]", "$_[1]", "openmpi", "gcc_cuda");
}

# called after all components are installed.
sub postinstall_openmpi_gcc_cuda_hfi
{
    my $install_list = $_[0];     # total that will be installed when done
    my $installing_list = $_[1];  # what items are being installed/reinstalled
}

# uninstalls component.  May be called even if component is
# partially or not installed at all in which case should do its best to
# get rid or what might remain of component from a previously aborted
# uninstall or failed install
sub uninstall_openmpi_gcc_cuda_hfi
{
    uninstall_generic_mpi("$_[0]", "$_[1]", "openmpi", "gcc_cuda");
}

#!/usr/bin/perl
## BEGIN_ICS_COPYRIGHT8 ****************************************
## 
## Copyright (c) 2015, Intel Corporation
## 
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
## 
##     * Redistributions of source code must retain the above copyright notice,
##       this list of conditions and the following disclaimer.
##     * Redistributions in binary form must reproduce the above copyright
##       notice, this list of conditions and the following disclaimer in the
##       documentation and/or other materials provided with the distribution.
##     * Neither the name of Intel Corporation nor the names of its contributors
##       may be used to endorse or promote products derived from this software
##       without specific prior written permission.
## 
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 
## END_ICS_COPYRIGHT8   ****************************************
#
## [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
#use strict;
##use Term::ANSIColor;
##use Term::ANSIColor qw(:constants);
##use File::Basename;
##use Math::BigInt;
#
## ==========================================================================
#
#Installation Prequisites array for fast fabric
#and of tools component
my @oftools_prereq = (
			"glibc",
			"libgcc",
			"libibumad",
			"libibverbs",
			"libstdc++",
);
$comp_prereq_hash{'oftools_prereq'} = \@oftools_prereq;

my @fastfabric_prereq = (
			"atlas",
			"bash",
			"bc",
			"expat",
			"expect",
			"glibc",
			"libgcc",
			"libibumad",
			"libibverbs",
			"libstdc++",
			"ncurses-libs",
			"openssl-libs",
			"perl",
			"perl-Getopt-Long",
			"perl-Socket",
			"rdma",
			"tcl",
			"zlib",
			"qperf",
			"perftest",
);
$comp_prereq_hash{'fastfabric_prereq'} = \@fastfabric_prereq;

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# Fast Fabric Support tools for OFED (oftools) installation

# autostart functions are per subcomponent
sub start_oftools
{
}

sub stop_oftools
{
}

sub available_oftools
{
	my $srcdir=$ComponentInfo{'oftools'}{'SrcDir'};
	return (rpm_resolve("$srcdir/RPMS/*/", "any", "opa-basic-tools") ne "" );
}

sub installed_oftools
{
	return(system("rpm -q --quiet opa-basic-tools") == 0)
}

# only called if installed_oftools is true
sub installed_version_oftools
{
	my $version = rpm_query_version_release_pkg("opa-basic-tools");
	return dot_version("$version");
}

# only called if available_oftools is true
sub media_version_oftools
{
	my $srcdir=$ComponentInfo{'oftools'}{'SrcDir'};
	return `cat "$srcdir/version"`;
}

sub build_oftools
{
	my $osver = $_[0];
	my $debug = $_[1];	# enable extra debug of build itself
	my $build_temp = $_[2];	# temp area for use by build
	my $force = $_[3];	# force a rebuild
	return 0;	# success
}

sub need_reinstall_oftools($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return "no";
}

sub preinstall_oftools
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	return 0;	# success
}

sub install_oftools
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'oftools'}{'SrcDir'};

	my $version=media_version_oftools();
	chomp $version;
	printf("Installing $ComponentInfo{'oftools'}{'Name'} $version $DBG_FREE...\n");
	#LogPrint "Installing $ComponentInfo{'oftools'}{'Name'} $version $DBG_FREE for $CUR_OS_VER\n";
	LogPrint "Installing $ComponentInfo{'oftools'}{'Name'} $version $DBG_FREE for $CUR_DISTRO_VENDOR $CUR_VENDOR_VER\n";

	# Check $BASE_DIR directory ...exist 
	check_config_dirs();

	check_dir("/usr/lib/opa/tools");
	check_dir("/usr/share/opa/samples");

	my $rpmfile = rpm_resolve("$srcdir/RPMS/*/", "any", "opa-basic-tools");
	rpm_run_install($rpmfile, "any", " -U ");

	$rpmfile = rpm_resolve("$srcdir/RPMS/*/", "any", "opa-address-resolution");
	rpm_run_install($rpmfile, "any", " -U ");
	check_rpm_config_file("/etc/rdma/dsap.conf");

	## Install OPA_SA_DB library, headers.
	check_dir("/usr/include/infiniband");
	copy_shlib("$srcdir/bin/$ARCH/$CUR_DISTRO_VENDOR.$CUR_VENDOR_VER/lib/$DBG_FREE/libopasadb", "$LIB_DIR/libopasadb", "1.0.0");

	$ComponentWasInstalled{'oftools'}=1;
}

sub postinstall_oftools
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
}

sub uninstall_oftools
{
	my $install_list = $_[0];	# total that will be left installed when done
	my $uninstalling_list = $_[1];	# what items are being uninstalled

	NormalPrint("Uninstalling $ComponentInfo{'oftools'}{'Name'}...\n");

	rpm_uninstall_list("any", "verbose", ("opa-basic-tools", "opa-address-resolution") );

	# remove LSF and Moab related files
	system("rm -rf $ROOT/usr/lib/opa/LSF_scripts");
	system("rm -rf $ROOT/usr/lib/opa/Moab_scripts");

	# may be created by opaverifyhosts
	system("rm -rf $ROOT/usr/lib/opa/tools/nodescript.sh");
	system("rm -rf $ROOT/usr/lib/opa/tools/nodeverify.sh");

	system "rmdir $ROOT/usr/lib/opa/tools 2>/dev/null";	# remove only if empty

	# oftools is a prereq of fastfabric can cleanup shared files here
	system("rm -rf $ROOT$BASE_DIR/version_ff");
	system "rmdir $ROOT$BASE_DIR 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$OPA_CONFIG_DIR 2>/dev/null";	# remove only if empty
	system("rm -rf $ROOT/usr/lib/opa/.comp_oftools.pl");
	system "rmdir $ROOT/usr/lib/opa 2>/dev/null";	# remove only if empty
	$ComponentWasInstalled{'oftools'}=0;
}

sub check_os_prereqs_oftools
{
	return rpm_check_os_prereqs("oftools", "user");
}
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# Fast Fabric installation

my $FF_CONF_FILE = "/usr/lib/opa/tools/opafastfabric.conf";
my $FF_TLS_CONF_FILE = "/etc/opa/opaff.xml";
sub available_fastfabric
{
	my $srcdir=$ComponentInfo{'fastfabric'}{'SrcDir'};
	return ((rpm_resolve("$srcdir/RPMS/*/", "any", "opa-basic-tools") ne "") &&
			(rpm_resolve("$srcdir/RPMS/*/", "any", "opa-fastfabric") ne ""));
}

sub installed_fastfabric
{
	return(system("rpm -q --quiet opa-fastfabric") == 0)
}

# only called if installed_fastfabric is true
sub installed_version_fastfabric
{
	my $version = rpm_query_version_release_pkg("opa-fastfabric");
	return dot_version("$version");
}

# only called if available_fastfabric is true
sub media_version_fastfabric
{
	my $srcdir=$ComponentInfo{'fastfabric'}{'SrcDir'};
	return `cat "$srcdir/version"`;
}

sub build_fastfabric
{
	my $osver = $_[0];
	my $debug = $_[1];	# enable extra debug of build itself
	my $build_temp = $_[2];	# temp area for use by build
	my $force = $_[3];	# force a rebuild
	return 0;	# success
}

sub need_reinstall_fastfabric($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return "no";
}

sub check_os_prereqs_fastfabric
{	
	return rpm_check_os_prereqs("fastfabric", "user");
}

sub preinstall_fastfabric
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	return 0;	# success
}

sub install_fastfabric
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'fastfabric'}{'SrcDir'};
	my $depricated_dir = "/etc/sysconfig/opa";

	my $version=media_version_fastfabric();
	chomp $version;
	printf("Installing $ComponentInfo{'fastfabric'}{'Name'} $version $DBG_FREE...\n");
		LogPrint "Installing $ComponentInfo{'fastfabric'}{'Name'} $version $DBG_FREE for $CUR_DISTRO_VENDOR $CUR_VENDOR_VER\n";
	check_config_dirs();

	my $rpmfile = rpm_resolve("$srcdir/RPMS/*/", "any", "opa-fastfabric");
	rpm_run_install($rpmfile, "any", " -U ");

	check_dir("/usr/lib/opa/tools");
	check_dir("/usr/share/opa/samples");
	system "chmod ug+x $ROOT/usr/share/opa/samples/hostverify.sh";
	system "rm -f $ROOT/usr/share/opa/samples/nodeverify.sh";

	check_rpm_config_file("$FF_TLS_CONF_FILE");
	printf("Default opaff.xml can be found in '/usr/share/opa/samples/opaff.xml-sample'\n");
	check_rpm_config_file("$CONFIG_DIR/opa/opamon.conf", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/opafastfabric.conf", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/allhosts", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/chassis", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/hosts", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/ports", $depricated_dir);
	check_rpm_config_file("$CONFIG_DIR/opa/switches", $depricated_dir);
	check_rpm_config_file("/usr/lib/opa/tools/osid_wrapper");

	#install_conf_file("$ComponentInfo{'fastfabric'}{'Name'}", "$FF_TLS_CONF_FILE", "$srcdir/fastfabric/tools/tls");
	#remove_conf_file("$ComponentInfo{'fastfabric'}{'Name'}", "$OPA_CONFIG_DIR/iba_stat.conf");
	system("rm -rf $ROOT$OPA_CONFIG_DIR/iba_stat.conf");	# old config

	$rpmfile = rpm_resolve("$srcdir/RPMS/*/", "any", "opa-mpi-apps");
	rpm_run_install($rpmfile, "any", " -U ");



	$ComponentWasInstalled{'fastfabric'}=1;
}

sub postinstall_fastfabric
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
}

sub uninstall_fastfabric
{
	my $install_list = $_[0];	# total that will be left installed when done
	my $uninstalling_list = $_[1];	# what items are being uninstalled


	rpm_uninstall_list("any", "verbose", ("opa-mpi-apps", "opa-fastfabric") );

	NormalPrint("Uninstalling $ComponentInfo{'fastfabric'}{'Name'}...\n");
	remove_conf_file("$ComponentInfo{'fastfabric'}{'Name'}", "$FF_CONF_FILE");
	remove_conf_file("$ComponentInfo{'fastfabric'}{'Name'}", "$OPA_CONFIG_DIR/iba_stat.conf");
	remove_conf_file("$ComponentInfo{'fastfabric'}{'Name'}", "$FF_TLS_CONF_FILE");
	
	# remove samples we installed (or user compiled), however do not remove
	# any logs or other files the user may have created
	remove_installed_files "/usr/share/opa/samples";
	system "rmdir $ROOT/usr/share/opa/samples 2>/dev/null";	# remove only if empty

	system("rm -rf $ROOT/usr/lib/opa/.comp_fastfabric.pl");
	system "rmdir $ROOT/usr/lib/opa 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$BASE_DIR 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$OPA_CONFIG_DIR 2>/dev/null";	# remove only if empty
	$ComponentWasInstalled{'fastfabric'}=0;
}

#############################################################################
##
##    OPAMGT SDK

sub available_opamgt_sdk
{
	my $srcdir = $ComponentInfo{'opamgt_sdk'}{'SrcDir'};
	return ( rpm_exists("$srcdir/RPMS/*/", "any", "opa-libopamgt-devel") &&
		     rpm_exists("$srcdir/RPMS/*/", "any", "opa-libopamgt"));
}

sub installed_opamgt_sdk
{
	return ( rpm_is_installed("opa-libopamgt-devel", "any") &&
		     rpm_is_installed("opa-libopamgt", "any"));
}

sub installed_version_opamgt_sdk
{
	return rpm_query_version_release_pkg("opa-libopamgt-devel");
}

sub media_version_opamgt_sdk
{
	my $srcdir = $ComponentInfo{'opamgt_sdk'}{'SrcDir'};
	my $rpm = rpm_resolve("$srcdir/RPMS/*/", "any", "opa-libopamgt-devel");
	return rpm_query_version_release($rpm);
}

sub build_opamgt_sdk
{
	return 0;
}

sub need_reinstall_opamgt_sdk
{
	return "no";
}

sub check_os_prereqs_opamgt_sdk
{
	rpm_check_os_prereqs("opa-libopamgt", "any");
}

sub preinstall_opamgt_sdk
{
	return 0;
}

sub install_opamgt_sdk
{
	my $install_list = $_[0];       # total that will be installed when done
	my $installing_list = $_[1];    # what items are being installed/reinstalled

	my $srcdir = $ComponentInfo{'opamgt_sdk'}{'SrcDir'};
	my $version=media_version_opamgt_sdk();
	chomp $version;
	printf("Installing $ComponentInfo{'opamgt_sdk'}{'Name'} $version $DBG_FREE...\n");
	LogPrint "Installing $ComponentInfo{'opamgt_sdk'}{'Name'} $version $DBG_FREE for $CUR_DISTRO_VENDOR $CUR_VENDOR_VER\n";

	rpm_install("$srcdir/RPMS/*/", "any", "opa-libopamgt");
	rpm_install("$srcdir/RPMS/*/", "any", "opa-libopamgt-devel");

	$ComponentWasInstalled{'opamgt_sdk'}=1;
}

sub postinstall_opamgt_sdk
{

}

sub uninstall_opamgt_sdk
{
	rpm_uninstall_all_list("any", "verbose", ("opa-libopamgt-devel", "opa-libopamgt") );
	$ComponentWasInstalled{'opamgt_sdk'}=0;
}
#!/usr/bin/perl
## BEGIN_ICS_COPYRIGHT8 ****************************************
## 
## Copyright (c) 2015, Intel Corporation
## 
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
## 
##     * Redistributions of source code must retain the above copyright notice,
##       this list of conditions and the following disclaimer.
##     * Redistributions in binary form must reproduce the above copyright
##       notice, this list of conditions and the following disclaimer in the
##       documentation and/or other materials provided with the distribution.
##     * Neither the name of Intel Corporation nor the names of its contributors
##       may be used to endorse or promote products derived from this software
##       without specific prior written permission.
## 
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 
## END_ICS_COPYRIGHT8   ****************************************
#
## [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
#use strict;
##use Term::ANSIColor;
##use Term::ANSIColor qw(:constants);
##use File::Basename;
##use Math::BigInt;
#
## ==========================================================================
#
#Installation Prequisites array for opafm
my @opafm_prereq = (
			"bash",
			"expat",
			"glibc",
			"libibumad",
			"libibverbs",
			"openssl-libs",
			"rdma",
			"systemd",
			"zlib",
);
$comp_prereq_hash{'opafm_prereq'} = \@opafm_prereq;
#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# OPA FM for OFED installation

# autostart functions are per subcomponent
# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_opafm()
{
	return IsAutostart("opafm");
}
sub autostart_desc_opafm()
{
	return "$ComponentInfo{'opafm'}{'Name'} (opafm)";
}
# enable autostart for the given capability
sub enable_autostart2_opafm()
{
	enable_autostart("opafm");
}
# disable autostart for the given capability
sub disable_autostart2_opafm()
{
	disable_autostart("opafm");
}

sub start_opafm
{
	start_utility($ComponentInfo{'opafm'}{'Name'}, "/usr/lib/opa-fm/runtime", "sm", "opafm");
}

sub stop_opafm
{
	stop_utility($ComponentInfo{'opafm'}{'Name'}, "sm", "opafm");
}

sub available_opafm
{
	my $srcdir=$ComponentInfo{'opafm'}{'SrcDir'};
	my $rpmfile = file_glob("$srcdir/RPMS/*/opa-fm-*.rpm");
	return ( -d "$srcdir" && -e "$rpmfile" );
}

sub installed_opafm
{
	my $driver_subdir=$ComponentInfo{'opafm'}{'DriverSubdir'};
	return rpm_is_installed("opa-fm", "any");
}

# only called if installed_opafm is true
sub installed_version_opafm
{
	my $fm_version = rpm_query_version_release_pkg("opa-fm");

	return dot_version("$fm_version");
}

# only called if available_opafm is true
sub media_version_opafm
{
	my $srcdir=$ComponentInfo{'opafm'}{'SrcDir'};
	my $fm_rpmfile = file_glob("$srcdir/RPMS/*/opa-fm-*.rpm");
	my $fm_version= rpm_query_version_release("$fm_rpmfile");
	# assume media properly built with matching versions
	return dot_version("$fm_version");
}

sub build_opafm
{
	my $osver = $_[0];
	my $debug = $_[1];	# enable extra debug of build itself
	my $build_temp = $_[2];	# temp area for use by build
	my $force = $_[3];	# force a rebuild
	my $srcdir=$ComponentInfo{'opafm'}{'SrcDir'};

	return 0;	# success
}

sub need_reinstall_opafm($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return "no";
}

sub preinstall_opafm
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
	my $srcdir=$ComponentInfo{'opafm'}{'SrcDir'};

	return 0;	# success
}

sub install_opafm
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'opafm'}{'SrcDir'};
	my $driver_subdir=$ComponentInfo{'opafm'}{'DriverSubdir'};
	my $rc;
	my $keep;
	my $diff_src_dest;

	my $version=media_version_opafm();
	chomp $version;

	printf("Installing $ComponentInfo{'opafm'}{'Name'} $version $DBG_FREE...\n");
	LogPrint "Installing $ComponentInfo{'opafm'}{'Name'} $version $DBG_FREE for $CUR_OS_VER\n";

	# because RPM will change autostart settings of opafm we need to save
	# and restore the settings
	my $fm_start = IsAutostart2_opafm();

	# Install the rpm
	my $rpmfile = rpm_resolve("$srcdir/RPMS/*/", "user", "opa-fm");
	rpm_run_install($rpmfile, "user", "-U");
	$rpmfile = rpm_resolve("$srcdir/RPMS/*/", "user", "opa-fm-debuginfo");
	if ($rpmfile) {
		rpm_run_install($rpmfile, "user", " -U ");
	}

	check_rpm_config_file("$CONFIG_DIR/opa-fm/opafm.xml", "/etc/sysconfig");
	check_dir("/usr/lib/opa");

	if ($fm_start) {
		enable_autostart("opafm");
	} else {
		disable_autostart("opafm");
	}

	$ComponentWasInstalled{'opafm'}=1;
}

sub postinstall_opafm
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
}

sub uninstall_opafm
{
	my $install_list = $_[0];	# total that will be left installed when done
	my $uninstalling_list = $_[1];	# what items are being uninstalled

	my $driver_subdir=$ComponentInfo{'opafm'}{'DriverSubdir'};
	NormalPrint("Uninstalling $ComponentInfo{'opafm'}{'Name'}...\n");

	rpm_uninstall_list("any", "verbose", ( "opa-fm", "opa-fm-debuginfo") );
	system("rm -rf $ROOT/usr/lib/opa/.comp_opafm.pl");
	system("rmdir -p $ROOT/opt/iba/fm_tools 2>/dev/null");  # remove only if empty
	system("rm -rf $ROOT/usr/lib/opa-fm");
	$ComponentWasInstalled{'opafm'}=0;
}

sub check_os_prereqs_opafm
{
	return rpm_check_os_prereqs("opafm", "user");
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# Fabric Viewer for OFED installation

sub available_qlgc_fv
{
	#my $srcdir=$ComponentInfo{'qlgc_fv'}{'SrcDir'};
	#my $binfile = file_glob("$srcdir/*FV*install.bin");
	#return ( -d "$srcdir" && -e "$binfile" );
	return 0;	# not yet working
}

sub installed_qlgc_fv
{
	my $driver_subdir=$ComponentInfo{'qlgc_fv'}{'DriverSubdir'};
	return 0;	# TBD
}

# only called if installed_qlgc_fv is true
sub installed_version_qlgc_fv
{
	# TBD - can we determine this in another way?
	if ( -e "$ROOT$BASE_DIR/version_qlgc_fv" ) {
		return `cat $ROOT$BASE_DIR/version_qlgc_fv`;
	} else {
		return "";
	}
}

# only called if available_qlgc_fv is true
sub media_version_qlgc_fv
{
	my $srcdir=$ComponentInfo{'qlgc_fv'}{'SrcDir'};
	return `cat "$srcdir/Version"`;
}

sub build_qlgc_fv
{
	my $osver = $_[0];
	my $debug = $_[1];	# enable extra debug of build itself
	my $build_temp = $_[2];	# temp area for use by build
	my $force = $_[3];	# force a rebuild
	my $srcdir=$ComponentInfo{'qlgc_fv'}{'SrcDir'};

	return 0;	# success
}

sub need_reinstall_qlgc_fv($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return "no";
}

sub preinstall_qlgc_fv
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
	my $srcdir=$ComponentInfo{'qlgc_fv'}{'SrcDir'};

	return 0;	# success
}

sub install_qlgc_fv
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'qlgc_fv'}{'SrcDir'};
	my $driver_subdir=$ComponentInfo{'qlgc_fv'}{'DriverSubdir'};
	my $rc;

	my $version=media_version_qlgc_fv();
	chomp $version;
	printf("Installing $ComponentInfo{'qlgc_fv'}{'Name'} $version $DBG_FREE...\n");
	LogPrint "Installing $ComponentInfo{'qlgc_fv'}{'Name'} $version $DBG_FREE for $CUR_OS_VER\n";

	# TBD - how to run $srcdir/*FV*install.bin
	# TBD - do we need this or can we figure out in installed_version above
	#check_dir("/opt/iba");
	#copy_systool_file("$srcdir/comp.pl", "/opt/iba/.comp_qlgc_fv.pl");
	#check_dir("$BASE_DIR");
	#copy_data_file("$srcdir/Version", "$BASE_DIR/version_qlgc_fv");

	$ComponentWasInstalled{'qlgc_fv'}=1;
}

sub postinstall_qlgc_fv
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled
}

sub uninstall_qlgc_fv
{
	my $install_list = $_[0];	# total that will be left installed when done
	my $uninstalling_list = $_[1];	# what items are being uninstalled

	my $driver_subdir=$ComponentInfo{'qlgc_fv'}{'DriverSubdir'};
	NormalPrint("Uninstalling $ComponentInfo{'qlgc_fv'}{'Name'}...\n");

	#TBD how to run unininstall
	system("rm -rf $ROOT$BASE_DIR/version_qlgc_fv");
	system "rmdir $ROOT$BASE_DIR 2>/dev/null";  # remove only if empty
	system("rm -rf $ROOT/opt/iba/.comp_qlgc_fv.pl");
	system "rmdir $ROOT/opt/iba 2>/dev/null";  # remove only if empty
	$ComponentWasInstalled{'qlgc_fv'}=0;
}

#!/usr/bin/perl
## BEGIN_ICS_COPYRIGHT8 ****************************************
## 
## Copyright (c) 2015, Intel Corporation
## 
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
## 
##     * Redistributions of source code must retain the above copyright notice,
##       this list of conditions and the following disclaimer.
##     * Redistributions in binary form must reproduce the above copyright
##       notice, this list of conditions and the following disclaimer in the
##       documentation and/or other materials provided with the distribution.
##     * Neither the name of Intel Corporation nor the names of its contributors
##       may be used to endorse or promote products derived from this software
##       without specific prior written permission.
## 
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 
## END_ICS_COPYRIGHT8   ****************************************
#
## [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
#use strict;
##use Term::ANSIColor;
##use Term::ANSIColor qw(:constants);
##use File::Basename;
##use Math::BigInt;
#
## ==========================================================================
#
#Installation Prequisites array for delta components
my @opa_stack_prereq = (
		"bash",
		"kernel",
		"kmod",
		"rdma",
		"systemd",
		"glibc",
		"libibumad",
		"libibumad-devel",
		"libibverbs",
		"pciutils",
		"opensm-libs",
		"libibcm",
);
$comp_prereq_hash{'opa_stack_prereq'} = \@opa_stack_prereq;

my @ibacm_prereq = (
		"bash",
		"chkconfig",
		"glibc",
		"libibumad",
		"libibverbs",
);
$comp_prereq_hash{'ibacm_prereq'} = \@ibacm_prereq;

my @mpi_selector_prereq = (
		"bash",
		"coreutils",
		"perl",
		"perl-Getopt-Long",
		"tcsh",
);
$comp_prereq_hash{'mpi_selector_prereq'} = \@mpi_selector_prereq;

my @intel_hfi_prereq = (
		"bash",
		"glibc",
		"libgcc",
		"libibverbs",
		"libuuid",
		"libuuid-devel",
		"python",
		"systemd",
		"irqbalance",
);
$comp_prereq_hash{'intel_hfi_prereq'} = \@intel_hfi_prereq;

my @mvapich2_prereq = (
		"bash",
		"libibverbs",
		"librdmacm",
		"glibc",
		"zlib",
		"sysfsutils",
);
$comp_prereq_hash{'mvapich2_prereq'} = \@mvapich2_prereq;

my @openmpi_prereq = (
			"bash",
			"glibc",
			"libgcc",
			"libgfortran",
			"gcc-gfortran",
			"libgomp",
			"libibverbs",
			"libquadmath",
			"librdmacm",
			"libstdc++",
			"libstdc++-devel",
			"opensm-libs",
			"papi",
			"pkgconfig",
			"zlib",
);
$comp_prereq_hash{'openmpi_prereq'} = \@openmpi_prereq;

my @gasnet_prereq = (
			"bash",
			"glibc",
);
$comp_prereq_hash{'gasnet_prereq'} = \@gasnet_prereq;

my @openshmem_prereq = (
			"bash",
			"elfutils-libelf-devel",
			"elfutils-libelf",
			"glibc",
);
$comp_prereq_hash{'openshmem_prereq'} = \@openshmem_prereq;

my @mvapich2_gcc_hfi_prereq = (
			"bash",
			"zlib",

);
$comp_prereq_hash{'mvapich2_gcc_hfi_prereq'} = \@mvapich2_gcc_hfi_prereq;

my @mvapich2_intel_hfi_prereq = (
			"bash",
);
$comp_prereq_hash{'mvapich2_intel_hfi_prereq'} = \@mvapich2_intel_hfi_prereq;

my @openmpi_gcc_hfi_prereq = (
			"bash",
			"glibc",
			"infinipath-psm",
			"libgcc",
			"libgfortran",
			"gcc-gfortran",
			"libgomp",
			"libibverbs",
			"libquadmath",
			"librdmacm",
			"libstdc++",
			"libstdc++-devel",
			"opensm-libs",
			"papi",
			"pkgconfig",
			"zlib",
);
$comp_prereq_hash{'openmpi_gcc_hfi_prereq'} = \@openmpi_gcc_hfi_prereq;

my @openmpi_intel_hfi_prereq = (
			"bash",
);
$comp_prereq_hash{'openmpi_intel_hfi_prereq'} = \@openmpi_intel_hfi_prereq;

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8

# This file incorporates work covered by the following copyright and permission notice

#
# Copyright (c) 2006 Mellanox Technologies. All rights reserved.
#
# This Software is licensed under one of the following licenses:
#
# 1) under the terms of the "Common Public License 1.0" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/cpl.php.
#
# 2) under the terms of the "The BSD License" a copy of which is
#    available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/bsd-license.php.
#
# 3) under the terms of the "GNU General Public License (GPL) Version 2" a
#    copy of which is available from the Open Source Initiative, see
#    http://www.opensource.org/licenses/gpl-license.php.
#
# Licensee has the right to choose one of the above licenses.
#
# Redistributions of source code must retain the above copyright
# notice and one of the license notices.
#
# Redistributions in binary form must reproduce both the above copyright
# notice, one of the license notices in the documentation
# and/or other materials provided with the distribution.

use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ==========================================================================
# OFED_Delta installation, includes Intel value-adding packages only

my $default_prefix="/usr";

my $RPMS_SUBDIR = "RPMS";	# within ComponentInfo{'opa_stack'}{'SrcDir'}
my $SRPMS_SUBDIR = "SRPMS";	# within ComponentInfo{'opa_stack'}{'SrcDir'}

# list of components which are part of OFED
# can be a superset or subset of @Components
# ofed_vnic
my @delta_components_other = (
				"opa_stack", 		# Kernel drivers.
				"ibacm", 			# OFA IB communication manager assistant.
				"intel_hfi", 		# HFI drivers
				"delta_ipoib", 		# ipoib module.
				"mpi_selector",
				"mvapich2",
				"openmpi",
				"gasnet",
				"openshmem",
				"opa_stack_dev", 	# dev libraries.
				"delta_mpisrc", 	# Source bundle for MPIs.
				"mpiRest",			# PGI, Intel mpi variants.
				"hfi1_uefi",
				"delta_debug",		# must be last real component
);

my @delta_components_rhel72 = ( @delta_components_other );

my @delta_components_rhel67 = ( @delta_components_other );

my @delta_components_rhel70 = (
				"opa_stack", 		# Kernel drivers.
				"ibacm", 		# OFA IB communication manager assistant.
				"intel_hfi", 		# HFI drivers
				"delta_ipoib", 		# ipoib module.
				"mpi_selector",
				"mvapich2",
				"openmpi",
				"gasnet",
				"openshmem",
				"opa_stack_dev", 	# dev libraries.
				"delta_mpisrc", 	# Source bundle for MPIs.
				"mpiRest",			# PGI, Intel mpi variants.
				"delta_debug",		# must be last real component
);

my @delta_components_sles = ( @delta_components_other );

my @delta_components_rhel70 = (
				"opa_stack", 		# Kernel drivers.
				"ibacm", 		# OFA IB communication manager assistant.
				"intel_hfi", 		# HFI drivers
				"delta_ipoib", 		# ipoib module.
				"mpi_selector",
				"mvapich2",
				"openmpi",
				"gasnet",
				"openshmem",
				"opa_stack_dev", 	# dev libraries.
				"delta_mpisrc", 	# Source bundle for MPIs.
				"mpiRest",			# PGI, Intel mpi variants.
				"delta_debug",		# must be last real component
);

my @delta_components_sles12_sp2 = (
				"opa_stack", 		# Kernel drivers.
				"ibacm",
				"intel_hfi", 		# HFI drivers
				"delta_ipoib", 		# ipoib module.
				"mpi_selector",
				"mvapich2",
				"openmpi",
				"gasnet",
				"openshmem",
				"opa_stack_dev", 	# dev libraries.
				"delta_mpisrc", 	# Source bundle for MPIs.
				"mpiRest",			# PGI, Intel mpi variants.
				"hfi1_uefi",
				"delta_debug",		# must be last real component
);

my @delta_components_rhel73 = (
				"opa_stack", 		# Kernel drivers.
				"ibacm",
				"intel_hfi", 		# HFI drivers
				"delta_ipoib", 		# ipoib module.
				"mpi_selector",
				"mvapich2",
				"openmpi",
				"gasnet",
				"openshmem",
				"opa_stack_dev", 	# dev libraries.
				"delta_mpisrc", 	# Source bundle for MPIs.
				"mpiRest",			# PGI, Intel mpi variants.
				"hfi1_uefi",
				"delta_debug",		# must be last real component
);

my @delta_components = ( );


# information about each component in delta_components
# Fields:
#	KernelRpms => kernel rpms for given component, in dependency order
#				  These are package packages which are kernel version specific and
#				  will have kernel uname -r in rpm package name.
#				  For a given distro a separate version of each of these rpms
#				  may exist per kernel.  These are always architecture dependent
#	UserRpms => user rpms for given component, in dependency order
#				These are rpms which are not kernel specific.  For a given
#				distro a single version of each of these rpms will
#				exist per distro/arch combination.  Some of these may
#				be architecture independent (noarch).
#	Drivers => used so we can load compat-rdma rpm, then remove drivers for
#				ULPs which are not desired.  Ugly but a workaround for fact
#				that compat-rdma has all the ULP drivers in it
#				specifies drivers and subdirs which are within compat-rdma and
#				specific to each component
#	StartupScript => name of startup script which controls startup of this
#					component
#	StartupParams => list of parameter names in $OPA_CONFIG which control
#					startup of this component (set to yes/no values)
#
# Note KernelRpms are always installed before UserRpms
my %ibacm_comp_info = (
	'ibacm' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "ibacm", ],
					DebugRpms =>  [ "ibacm-debuginfo" ],
					Drivers => "", # none
					StartupScript => "ibacm",
					StartupParams => [ ]
					},
);

my %ibacm_sles12_sp2_comp_info = (
        'ibacm' => {
                                        KernelRpms => [ ],
                                        UserRpms =>       [ ],
                                        DebugRpms =>  [ ],
                                        Drivers => "", # none
                                        StartupScript => "ibacm",
                                        StartupParams => [ ]
                                        },
);

my %ibacm_rhel73_comp_info = (
        'ibacm' => {
                                        KernelRpms => [ ],
                                        UserRpms =>       [ ],
                                        DebugRpms =>  [ ],
                                        Drivers => "", # none
                                        StartupScript => "ibacm",
                                        StartupParams => [ ]
                                        },
);

my %intel_hfi_comp_info = (
	'intel_hfi' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "libhfi1", "libhfi1-static",
							    "libpsm2", 
							    "libpsm2-devel", "libpsm2-compat",
							    "hfi1-diagtools-sw", "hfidiags", 
							    "hfi1-firmware", "hfi1-firmware_debug" 
					    ],
					DebugRpms =>  [ "hfi1_debuginfo",
							"hfi1-diagtools-sw-debuginfo",
							"libpsm2-debuginfo", "libhfi1-debuginfo" 
					    ],
					Drivers => "",
					StartupScript => "",
					StartupParams => [  ],
					},
);

my %intel_hfi_sles12_sp2_comp_info = (
	'intel_hfi' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "libpsm2", 
							    "libpsm2-devel", "libpsm2-compat",
							    "hfi1-diagtools-sw", "hfidiags", 
							    "hfi1-firmware", "hfi1-firmware_debug" 
					    ],
					DebugRpms =>  [ "hfi1-diagtools-sw-debuginfo",
							"libpsm2-debuginfo" 
					    ],
					Drivers => "",
					StartupScript => "",
					StartupParams => [  ],
					},
);

my %intel_hfi_rhel73_comp_info = (
	'intel_hfi' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "libpsm2", 
							    "libpsm2-devel", "libpsm2-compat",
							    "hfi1-diagtools-sw", "hfidiags", 
							    "hfi1-firmware", "hfi1-firmware_debug" 
					    ],
					DebugRpms =>  [ "hfi1-diagtools-sw-debuginfo",
							"libpsm2-debuginfo" 
					    ],
					Drivers => "",
					StartupScript => "",
					StartupParams => [  ],
					},
);

my %ib_wfr_lite_comp_info = (
	'ib_wfr_lite' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "ib_wfr_lite", ],
					DebugRpms =>  [ "ib_wfr_lite-debuginfo", ],
					Drivers => "",
					StartupScript => "",
					StartupParams => [  ],
					},
);

my %delta_ipoib_comp_info = (
	'delta_ipoib' => {
					KernelRpms => [ ],
					UserRpms =>	  [ ],
					DebugRpms =>  [ ],
					Drivers => "",
					StartupScript => "",
					StartupParams => [ "IPOIB_LOAD" ],
					},
);

my %mpi_selector_comp_info = (
	'mpi_selector' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "mpi-selector" ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %mvapich2_comp_info = (
	'mvapich2' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "mvapich2_gcc", "mpitests_mvapich2_gcc", ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %openmpi_comp_info = (
	'openmpi' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "openmpi_gcc", "mpitests_openmpi_gcc" ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %gasnet_comp_info = (
	'gasnet' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "gasnet_gcc_hfi", "gasnet_gcc_hfi-devel" , "gasnet_gcc_hfi-tests" ],
					DebugRpms =>  [ "gasnet_gcc_hfi-debuginfo" ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %openshmem_comp_info = (
	'openshmem' => {
					KernelRpms => [ ],
					UserRpms =>	  [ "openshmem_gcc_hfi", "openshmem-test-suite_gcc_hfi", "shmem-benchmarks_gcc_hfi"  ],
					DebugRpms =>  [ "openshmem_gcc_hfi-debuginfo", "openshmem-test-suite_gcc_hfi-debuginfo",
							"shmem-benchmarks_gcc_hfi-debuginfo" ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_dev_comp_info = (
	'opa_stack_dev' => {
					KernelRpms => [ "" ],
					UserRpms =>	  [ "compat-rdma-devel", "ibacm-devel",
							    "libibumad-devel", "libibumad-static",
							    "libibmad-devel", "libibmad-static"
								  ],
					DebugRpms =>  [  ],
					Drivers => "", 	# none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_dev_rhel70_comp_info = (
        'opa_stack_dev' => {
                                        KernelRpms => [ "" ],
                                        UserRpms =>       [ "compat-rdma-devel", "ibacm-devel",
                                                            "libibumad-devel", "libibumad-static",
                                                                  ],
                                        DebugRpms =>  [  ],
                                        Drivers => "",  # none
                                        StartupScript => "",
                                        StartupParams => [ ],
                                        },
);

my %opa_stack_dev_rhel67_comp_info = (
	'opa_stack_dev' => {
					KernelRpms => [ "ifs-kernel-updates-devel" ],
					UserRpms =>	  [ "ibacm-devel",
						            "libibumad-devel", "libibumad-static"
								  ],
					DebugRpms =>  [  ],
					Drivers => "", 	# none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_dev_rhel72_comp_info = (
	'opa_stack_dev' => {
					KernelRpms => [ ],
					UserRpms =>  [ "ifs-kernel-updates-devel", "ibacm-devel" ],
					DebugRpms =>  [  ],
					Drivers => "", 	# none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_dev_sles12_sp2_comp_info = (
	'opa_stack_dev' => {
					KernelRpms => [ ],
					UserRpms =>  [ "ifs-kernel-updates-devel" ],
					DebugRpms =>  [  ],
					Drivers => "", 	# none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_dev_rhel73_comp_info = (
	'opa_stack_dev' => {
					KernelRpms => [ ],
					UserRpms =>  [ "ifs-kernel-updates-devel" ],
					DebugRpms =>  [  ],
					Drivers => "", 	# none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %delta_mpisrc_comp_info = (
	'delta_mpisrc' => {	# nothing to build, just copies srpms
					KernelRpms => [ ],
					UserRpms =>	  [ ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %mpiRest_comp_info = (
	'mpiRest' => {	# rest of MPI stuff which customer can build via do_build
					# this is included here so we can uninstall
					KernelRpms => [ ],
					UserRpms =>	  [
									"mvapich2_pgi",
									"mvapich2_intel", "mvapich2_pathscale",
									"openmpi_pgi",
									"openmpi_intel", "openmpi_pathscale",
									"mpitests_mvapich2_pgi",
									"mpitests_mvapich2_intel",
									"mpitests_mvapich2_pathscale",
									"mpitests_openmpi_pgi",
									"mpitests_openmpi_intel",
									"mpitests_openmpi_pathscale",
								  ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %hfi1_uefi_comp_info = (
	'hfi1_uefi' =>  {
					KernelRpms => [ ],
					UserRpms =>   [ "hfi1-uefi" ],
					DebugRpms =>  [ ],
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %delta_debug_comp_info = (
	'delta_debug' => {
					KernelRpms => [ ],
					UserRpms =>	  [ ],
					DebugRpms =>  [ ],	# listed by comp above
					Drivers => "", # none
					StartupScript => "",
					StartupParams => [ ],
					},
);

my %opa_stack_other_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "compat-rdma" ], # special case
					UserRpms =>	  [ "opa-scripts",
								"libibumad",
								"srptools",
								"libibmad",
								"infiniband-diags",
								  ],
					DebugRpms =>  [ "libibumad-debuginfo",
									"srptools-debuginfo",
								  ],
					Drivers => "", 
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_rhel67_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "ifs-kernel-updates" ], # special case
					UserRpms =>	  [ "opa-scripts",
								"libibumad",
								"srptools",
								"libibmad",
								"infiniband-diags",
								  ],
					DebugRpms =>  [ "libibumad-debuginfo",
									"srptools-debuginfo",
								  ],
					Drivers => "", 
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_rhel72_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "kmod-ifs-kernel-updates" ], # special case
					UserRpms =>	  [ "opa-scripts",
								"srptools",
								"libibmad",
								"infiniband-diags",
								  ],
					DebugRpms =>  [ "srptools-debuginfo",
								  ],
					Drivers => "",
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_rhel70_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "compat-rdma" ], # special case
					UserRpms =>	  [ "opa-scripts",
								"libibumad",
								"srptools",
								"libibmad",
								"infiniband-diags",
								  ],
					DebugRpms =>  [ "libibumad-debuginfo",
									"srptools-debuginfo",
								  ],
					Drivers => "", 
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_sles_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "compat-rdma" ], # special case
					UserRpms =>	  [ "opa-scripts",
								"libibumad3",
								"srptools",
								"libibmad5",
								"infiniband-diags",
								  ],
					DebugRpms =>  [ ],
					Drivers => "", 
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_sles12_sp2_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "ifs-kernel-updates-kmp-default" ], # special case
					UserRpms =>   [ "opa-scripts",
								"infiniband-diags" ],
					DebugRpms =>  [  ],
					Drivers => "",
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %opa_stack_rhel73_comp_info = (
	'opa_stack' => {
					KernelRpms => [ "kmod-ifs-kernel-updates" ], # special case
					UserRpms =>   [ "opa-scripts",
								"infiniband-diags" ],
					DebugRpms =>  [  ],
					Drivers => "",
					StartupScript => "opa",
					StartupParams => [ "ARPTABLE_TUNING" ],
					},
);

my %delta_comp_info_other = (
	%opa_stack_other_comp_info,
	%ibacm_comp_info,
	%intel_hfi_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
);

my %delta_comp_info_rhel67 = (
	%opa_stack_rhel67_comp_info,
	%ibacm_comp_info,
	%intel_hfi_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_rhel67_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
);

my %delta_comp_info_rhel72 = (
	%opa_stack_rhel72_comp_info,
	%ibacm_comp_info,
	%intel_hfi_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_rhel72_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
);

my %delta_comp_info_rhel70 = (
	%opa_stack_rhel70_comp_info,
	%ibacm_comp_info,
	%intel_hfi_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_rhel70_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%delta_debug_comp_info,
);

my %delta_comp_info_sles = (
	%opa_stack_sles_comp_info,
	%ibacm_comp_info,
	%intel_hfi_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
);

my %delta_comp_info_sles12_sp2 = (
	%opa_stack_sles12_sp2_comp_info,
	%intel_hfi_sles12_sp2_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_sles12_sp2_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
	%ibacm_sles12_sp2_comp_info,
);

my %delta_comp_info_rhel73 = (
	%opa_stack_rhel73_comp_info,
	%intel_hfi_rhel73_comp_info,
	%ib_wfr_lite_comp_info,
	%delta_ipoib_comp_info,
	%mpi_selector_comp_info,
	%mvapich2_comp_info,
	%openmpi_comp_info,
	%gasnet_comp_info,
	%openshmem_comp_info,
	%opa_stack_dev_rhel73_comp_info,
	%delta_mpisrc_comp_info,
	%mpiRest_comp_info,
	%hfi1_uefi_comp_info,
	%delta_debug_comp_info,
	%ibacm_rhel73_comp_info,
);

my %delta_comp_info = ( );

# options for building compat-rdma srpm and what platforms they
# are each available for
my %delta_kernel_ib_options = (
	# build option		# arch & kernels supported on
						# (see util_build.pl for more info on format)
	# NOTE: the compat-rdma build takes no arguments right now.
	# This list is now empty, but will probably get used as time goes on.
);

# all kernel srpms
# these are in the order we must build/process them to meet basic dependencies
my @delta_kernel_srpms_other = ( 'compat-rdma' );
my @delta_kernel_srpms_rhel72 = ( 'kmod-ifs-kernel-updates' );
my @delta_kernel_srpms_rhel70 = ( 'compat-rdma' );
my @delta_kernel_srpms_rhel67 = ( 'ifs-kernel-updates' );
my @delta_kernel_srpms_sles = ( 'compat-rdma' );
my @delta_kernel_srpms_sles12_sp2 = ( 'ifs-kernel-updates-kmp-default' );
my @delta_kernel_srpms_rhel73 = ( 'kmod-ifs-kernel-updates' );
my @delta_kernel_srpms = ( );

# all user space srpms
# these are in the order we must build/process them to meet basic dependencies
my @delta_user_srpms_other = (
		"opa-scripts", "libibumad", "ibacm", "mpi-selector",
		"libhfi1", "libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "srptools", "libibmad", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms_rhel67 = (
		"opa-scripts", "libibumad", "ibacm", "mpi-selector",
		"libhfi1", "libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "srptools", "libibmad", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms_rhel72 = (
		"opa-scripts", "mpi-selector", "ibacm",
		"libhfi1", "libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "srptools", "libibmad", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms_rhel70 = (
		"opa-scripts", "libibumad", "ibacm", "mpi-selector",
		"libhfi1", "libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "srptools", "libibmad", "infiniband-diags"
);
my @delta_user_srpms_sles = (
		"opa-scripts", "libibumad3", "ibacm", "mpi-selector",
		"libhfi1", "libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "srptools", "libibmad5", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms_sles12_sp2 = (
		"opa-scripts", "mpi-selector",
		"libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms_rhel73 = (
		"opa-scripts", "mpi-selector",
		"libpsm2", "hfi1-diagtools-sw", "hfidiags", "hfi1-firmware", "hfi1-firmware_debug",
 		"mvapich2", "openmpi", "gasnet", "openshmem", "openshmem-test-suite",
		"shmem-benchmarks", "infiniband-diags", "hfi1_uefi"
);
my @delta_user_srpms = ( );

# rpms not presently automatically built
my @delta_other_srpms = ( );

my @delta_srpms = ( );

# This provides information for all kernel and user space srpms
# Fields:
#	Available => indicate which platforms each srpm can be built for
#	PostReq => after building each srpm, some of its generated rpms will
#				need to be installed so that later srpms will build properly
#				this lists all the rpms which may be needed by subsequent srpms
#	Builds => list of kernel and user rpms built from each srpm
#				caller must know if user/kernel rpm is expected
#	PartOf => delta_components this srpm is part of
#			  this is filled in at runtime based on delta_comp_info
#			  cross referenced to Builds
#	BuildPrereq => OS prereqs needed to build this srpm
#				List in the form of "rpm version mode" for each.
#				version is optional, default is "any"
#				mode is optional, default is "any"
#				Typically mode should be "user" for libraries
#				See rpm_is_installed for more information about mode
my %compat_rdma_srpm_info = (
	"compat-rdma" =>        { Available => "",
					Builds => "compat-rdma compat-rdma-devel",
					PostReq => "compat-rdma compat-rdma-devel",
					PartOf => "", # filled in at runtime
					BuildPrereq => [],
					},
);

my %hfi1_psm_srpm_info = (
	"libpsm2" =>	{ Available => "",
					  Builds => "libpsm2 libpsm2-devel libpsm2-compat",
					  PostReq => "libpsm2 libpsm2-devel libpsm2-compat",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %libhfi1_srpm_info = (
	"libhfi1" =>	{ Available => "",
					  Builds => "libhfi1 libhfi1-static",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %hfi1_diagtools_sw_srpm_info = (
	"hfi1-diagtools-sw" =>	{ Available => "",
					  Builds => "hfi1-diagtools-sw hfi1-diagtools-sw-debuginfo",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'readline-devel', 'ncurses-devel', ],
					},
);

my %hfidiags_srpm_info = (
	"hfidiags" =>	{ Available => "",
					  Builds => "hfidiags",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %hfi1_firmware_srpm_info = (
	"hfi1-firmware" =>	{ Available => "",
					  Builds => "hfi1-firmware",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %hfi1_firmware_debug_srpm_info = (
	"hfi1-firmware_debug" =>	{ Available => "",
					  Builds => "hfi1-firmware_debug",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %ib_wfr_lite_srpm_info = (
	"ib_wfr_lite" =>	{ Available => "",
					  Builds => "ib_wfr_lite",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %opa_scripts_srpm_info = (
	"opa-scripts" => { Available => "",
					  Builds => "opa-scripts",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %libibumad_srpm_info = (
	"libibumad" =>	{ Available => "",
					  Builds => "libibumad libibumad-devel libibumad-static libibumad-debuginfo",
					  PostReq => "libibumad libibumad-devel",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libtool any user' ],
					},
);

my %libibumad3_srpm_info = (
	"libibumad3" =>	{ Available => "",
					  Builds => "libibumad3 libibumad-devel libibumad-static",
					  PostReq => "libibumad3 libibumad-devel",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libtool any user' ],
					},
);

my %ibacm_srpm_info = (
	"ibacm" =>		{ Available => "",
					  Builds => "ibacm ibacm-devel",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %mpi_selector_srpm_info = (
	"mpi-selector" => { Available => "",
					  Builds => "mpi-selector",
					  PostReq => "mpi-selector",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'tcsh' ],
					},
);

my %mvapich2_srpm_info = (
	"mvapich2" =>	{ Available => "",
						# mpitests are built by do_mvapich2_build
		 			  Builds => " mvapich2_gcc mpitests_mvapich2_gcc",
		 			  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libstdc++ any user',
					  				   'libstdc++-devel any user',
									   'sysfsutils any user',
					  				   'g77', 'libgfortran any user'
								   	],
					},
);

my %openmpi_srpm_info = (
	"openmpi" =>	{ Available => "",
						# mpitests are built by do_openmpi_build
		 			  Builds => "openmpi_gcc mpitests_openmpi_gcc",
		 			  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libstdc++ any user',
					  				   'libstdc++-devel any user',
					  				   'g77', 'libgfortran any user',
									   'binutils'
								   	],
					},
);

my %gasnet_srpm_info = (
	"gasnet" =>		{ Available => "",
		 			  Builds => "gasnet_gcc_hfi gasnet_gcc_hfi-devel gasnet_gcc_hfi-tests",
		 			  PostReq => "gasnet_gcc_hfi gasnet_gcc_hfi-devel",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ ],
					},
);

my %openshmem_srpm_info = (
	"openshmem" =>	{ Available => "",
		 			  Builds => "openshmem_gcc_hfi",
		 			  PostReq => "openshmem_gcc_hfi",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ ],
					},
);

my %openshmem_test_suite_srpm_info = (
	"openshmem-test-suite" =>	{ Available => "",
					  Builds => "openshmem-test-suite_gcc_hfi",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %shmem_benchmarks_srpm_info = (
	"shmem-benchmarks" =>	{ Available => "",
					  Builds => "shmem-benchmarks_gcc_hfi",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [],
					},
);

my %srptools_srpm_info = (
	"srptools" =>	{ Available => "",
					  Builds => "srptools srptools-debuginfo",
					  PostReq => "",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libtool any user' ],
					},
);

my %libibmad_srpm_info = (
	"libibmad" =>  { Available => "",
					  Builds => "libibmad libibmad-devel libibmad-static",
					  PostReq => "libibmad libibmad-devel",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libtool any user' ],
					},
);

my %libibmad5_srpm_info = (
	"libibmad5" =>  { Available => "",
					  Builds => "libibmad5 libibmad-devel libibmad-static",
					  PostReq => "libibmad5 libibmad-devel",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'libtool any user' ],
					},
);

my %infiniband_diags_srpm_info = (
	"infiniband-diags" =>  { Available => "",
					  Builds => "infiniband-diags infiniband-diags-compat",
					  PostReq => "infiniband-diags",
					  PartOf => "", # filled in at runtime
					  BuildPrereq => [ 'opensm-devel any user',
							   'glib2-devel any user',
						  	 ],
					},
);

my %hfi1_uefi_srpm_info = (
	"hfi1_uefi" => { Available => "",
					Builds => "hfi1-uefi",
					PostReq => "",
					PartOf => "",
					BuildPrereq => [],
					},
);

my %kmp_ifs_kernel_updates_srpm_info = (
	"ifs-kernel-updates-kmp-default" =>        { Available => "",
					Builds => "ifs-kernel-updates-kmp-default ifs-kernel-updates-devel",
					PostReq => "ifs-kernel-updates-devel",
					PartOf => "", # filled in at runtime
					BuildPrereq => [],
					},
);

my %kmod_ifs_kernel_updates_srpm_info = (
	"kmod-ifs-kernel-updates" =>    { Available => "",
					Builds => "kmod-ifs-kernel-updates ifs-kernel-updates-devel",
					PostReq => "ifs-kernel-updates-devel",
					PartOf => "", # filled in at runtime
					BuildPrereq => [],
					},
);

my %ifs_kernel_updates_rhel67_srpm_info = (
        "ifs-kernel-updates" =>        { Available => "",
                                        Builds => "ifs-kernel-updates ifs-kernel-updates-devel",
                                        PostReq => "ifs-kernel-updates-devel",
                                        PartOf => "", # filled in at runtime
                                        BuildPrereq => [],
                                        },
);

my %delta_srpm_info_other = (
	%compat_rdma_srpm_info,
	%hfi1_psm_srpm_info,
	%libhfi1_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%ib_wfr_lite_srpm_info,
	%opa_scripts_srpm_info,
	%libibumad_srpm_info,
	%ibacm_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%srptools_srpm_info,
	%libibmad_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info_rhel67 = (
	%ifs_kernel_updates_rhel67_srpm_info,
	%hfi1_psm_srpm_info,
	%libhfi1_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%ib_wfr_lite_srpm_info,
	%opa_scripts_srpm_info,
	%libibumad_srpm_info,
	%ibacm_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%srptools_srpm_info,
	%libibmad_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info_rhel72 = (
	%kmod_ifs_kernel_updates_srpm_info,
	%hfi1_psm_srpm_info,
	%libhfi1_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%ib_wfr_lite_srpm_info,
	%opa_scripts_srpm_info,
	%libibumad_srpm_info,
	%ibacm_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%srptools_srpm_info,
	%libibmad_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info_rhel70 = (
	%compat_rdma_srpm_info,
	%hfi1_psm_srpm_info,
	%libhfi1_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%ib_wfr_lite_srpm_info,
	%opa_scripts_srpm_info,
	%libibumad_srpm_info,
	%ibacm_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%srptools_srpm_info,
#	%libibmad_srpm_info,
#	%infiniband_diags_srpm_info,
);

my %delta_srpm_info_sles = (
	%compat_rdma_srpm_info,
	%hfi1_psm_srpm_info,
	%libhfi1_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%ib_wfr_lite_srpm_info,
	%opa_scripts_srpm_info,
	%libibumad3_srpm_info,
	%ibacm_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%srptools_srpm_info,
	%libibmad5_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info_sles12_sp2 = (
	%kmp_ifs_kernel_updates_srpm_info,
	%hfi1_psm_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%opa_scripts_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info_rhel73 = (
	%kmod_ifs_kernel_updates_srpm_info,
	%hfi1_psm_srpm_info,
	%hfi1_diagtools_sw_srpm_info,
	%hfidiags_srpm_info,
	%hfi1_firmware_srpm_info,
	%hfi1_firmware_debug_srpm_info,
	%opa_scripts_srpm_info,
	%mpi_selector_srpm_info,
	%mvapich2_srpm_info,
	%openmpi_srpm_info,
	%gasnet_srpm_info,
	%openshmem_srpm_info,
	%openshmem_test_suite_srpm_info,
	%shmem_benchmarks_srpm_info,
	%infiniband_diags_srpm_info,
	%hfi1_uefi_srpm_info,
);

my %delta_srpm_info = ( );

# This provides information for all kernel and user space rpms
# This is built based on information in delta_srpm_info and delta_comp_info
# Fields:
#	Available => boolean indicating if rpm can be available for this platform
#	Parent => srpm which builds this rpm
#	PartOf => space separate list of components this rpm is part of
#	Mode => mode of rpm (kernel or user)
my %delta_rpm_info = ();
my @delta_rpms = ();

my %delta_autostart_save = ();
# ==========================================================================
# Delta opa_stack build in prep for installation

# based on %delta_srpm_info{}{'Available'} determine if the given SRPM is
# buildable and hence available on this CPU for $osver combination
# "user" and kernel rev values for mode are treated same
sub available_srpm($$$)
{
	my $srpm = shift();
	# $mode can be any other value,
	# only used to select Available
	my $mode = shift();	# "user" or kernel rev
	my $osver = shift();
	my $avail;

	$avail="Available";

	DebugPrint("checking $srpm $mode $osver against '$delta_srpm_info{$srpm}{$avail}'\n");
	return arch_kernel_is_allowed($osver, $delta_srpm_info{$srpm}{$avail});
}

# initialize delta_rpm_info based on specified osver for present system
sub init_delta_rpm_info($)
{
	my $osver = shift();

	%delta_rpm_info = ();	# start fresh

	# filter components by distro
	if ("$CUR_DISTRO_VENDOR" eq 'SuSE'
		&& ("$CUR_VENDOR_VER" eq 'ES12' || "$CUR_VENDOR_VER" eq 'ES121')) {
		@delta_components = ( @delta_components_sles );
		%delta_comp_info = ( %delta_comp_info_sles );
		@delta_kernel_srpms = ( @delta_kernel_srpms_sles );
		@delta_user_srpms = ( @delta_user_srpms_sles );
		%delta_srpm_info = ( %delta_srpm_info_sles );
	} elsif ("$CUR_DISTRO_VENDOR" eq 'SuSE'
		&& "$CUR_VENDOR_VER" eq 'ES122') {
		@delta_components = ( @delta_components_sles12_sp2 );
		%delta_comp_info = ( %delta_comp_info_sles12_sp2 );
		@delta_kernel_srpms = ( @delta_kernel_srpms_sles12_sp2 );
		@delta_user_srpms = ( @delta_user_srpms_sles12_sp2 );
		%delta_srpm_info = ( %delta_srpm_info_sles12_sp2 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES73" ) {
		@delta_components = ( @delta_components_rhel73 );
		%delta_comp_info = ( %delta_comp_info_rhel73 );
		@delta_kernel_srpms = ( @delta_kernel_srpms_rhel73 );
		@delta_user_srpms = ( @delta_user_srpms_rhel73 );
		%delta_srpm_info = ( %delta_srpm_info_rhel73 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES72" ) {
		@delta_components = ( @delta_components_rhel72 );
		%delta_comp_info = ( %delta_comp_info_rhel72 );
		@delta_kernel_srpms = ( @delta_kernel_srpms_rhel72 );
		@delta_user_srpms = ( @delta_user_srpms_rhel72 );
		%delta_srpm_info = ( %delta_srpm_info_rhel72 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES7" ) {
		@delta_components = ( @delta_components_rhel70 );
		%delta_comp_info = ( %delta_comp_info_rhel70 );
		@delta_kernel_srpms = ( @delta_kernel_srpms_rhel70 );
		@delta_user_srpms = ( @delta_user_srpms_rhel70 );
		%delta_srpm_info = ( %delta_srpm_info_rhel70 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES67" ) {
		@delta_components = ( @delta_components_rhel67 );
		%delta_comp_info = ( %delta_comp_info_rhel67 );
		@delta_kernel_srpms = ( @delta_kernel_srpms_rhel67 );
		@delta_user_srpms = ( @delta_user_srpms_rhel67 );
		%delta_srpm_info = ( %delta_srpm_info_rhel67 );
	} else {
		@delta_components = ( @delta_components_other );
		%delta_comp_info = ( %delta_comp_info_other );
		@delta_kernel_srpms = ( @delta_kernel_srpms_other );
		@delta_user_srpms = ( @delta_user_srpms_other );
		%delta_srpm_info = ( %delta_srpm_info_other );
	}

	@delta_srpms = ( @delta_kernel_srpms, @delta_user_srpms, @delta_other_srpms );

	# first get information based on all srpms
	foreach my $srpm ( @delta_srpms ) {
		my @package_list = split /[[:space:]]+/, $delta_srpm_info{$srpm}{'Builds'};
		foreach my $package ( @package_list ) {
			next if ( "$package" eq '' );	# handle leading spaces
			$delta_rpm_info{$package}{'Available'} = available_srpm($srpm, "user", $osver);
			$delta_rpm_info{$package}{'Parent'} = "$srpm";
		}
	}

	# now fill in PartOf and Mode based on all components
	# allow for the case where a package could be part of more than 1 component
	# however assume User vs Kernel is consistent
	foreach my $comp ( @delta_components ) {
		foreach my $package ( @{ $delta_comp_info{$comp}{'UserRpms'}} ) {
			$delta_rpm_info{$package}{'PartOf'} .= " $comp";
			$delta_rpm_info{$package}{'Mode'} = "user";
		}
		foreach my $package ( @{ $delta_comp_info{$comp}{'KernelRpms'}} ) {
			$delta_rpm_info{$package}{'PartOf'} .= " $comp";
			$delta_rpm_info{$package}{'Mode'} = "kernel";
		}
		foreach my $package ( @{ $delta_comp_info{$comp}{'DebugRpms'}} ) {
			$delta_rpm_info{$package}{'PartOf'} .= " delta_debug";
			# this is the only debuginfo with kernel rev in its name
			if ( "$package" eq "ib-bonding-debuginfo" ) {
				$delta_rpm_info{$package}{'Mode'} = "kernel";
			} else {
				$delta_rpm_info{$package}{'Mode'} = "user";
			}
		}
	}
	@delta_rpms = ( keys %delta_rpm_info );	# list of all rpms
	# fixup Available for those in "*Rest" but not in delta_srpm_info{*}{Builds}
	foreach my $package ( @delta_rpms ) {
		if ("$delta_rpm_info{$package}{'Available'}" eq "" ) {
			$delta_rpm_info{$package}{'Available'}=0;
		}
	}

	# -debuginfo is not presently supported on SuSE or Centos
	# also .rpmmacros overrides can disable debuginfo availability
	if ( "$CUR_DISTRO_VENDOR" eq "SuSE"
		|| ! rpm_will_build_debuginfo()) {
		foreach my $package ( @delta_rpms ) {
			if ($package =~ /-debuginfo/) {
				$delta_rpm_info{$package}{'Available'} = 0;
			}
		}
	}

	# disable libibmad and infiniband-diags for RHEL7.0
	if ( "$CUR_VENDOR_VER" eq "ES7" ) {
		foreach my $package ( @delta_rpms ) {
			if ($package =~ /libibmad/ ||
			    $package =~ /infiniband-diag/ ) {
				$delta_rpm_info{$package}{'Available'} = 0;
			}
		}
	}
	# every package must be part of some component (could be a dummy component)
	foreach my $package ( @delta_rpms ) {
		if ( "$delta_rpm_info{$package}{'PartOf'}" eq "" ) {
			LogPrint "$package: Not PartOf anything\n";
		}
	}

	# build $delta_srpm_info{}{PartOf}
	foreach my $srpm ( @delta_srpms ) {
		$delta_srpm_info{$srpm}{'PartOf'} = '';
	}
	foreach my $package ( @delta_rpms ) {
		my @complist = split /[[:space:]]+/, $delta_rpm_info{$package}{'PartOf'};
		my $srpm = $delta_rpm_info{$package}{'Parent'};
		foreach my $comp ( @complist ) {
			next if ( "$comp" eq '' );	# handle leading spaces
			if ( " $delta_srpm_info{$srpm}{'PartOf'} " !~ / $comp / ) {
				$delta_srpm_info{$srpm}{'PartOf'} .= " $comp";
			}
		}
	}
	# fixup special case for compat-rdma, its part of all delta comp w/ Drivers
	#my $srpm = $delta_rpm_info{'compat-rdma'}{'Parent'};
	#foreach my $comp ( @delta_components ) {
	#	if ("$delta_comp_info{$comp}{'Drivers'}" ne "" ) {
	#		if ( " $delta_srpm_info{$srpm}{'PartOf'} " !~ / $comp / ) {
	#			$delta_srpm_info{$srpm}{'PartOf'} .= " $comp";
	#		}
	#	}
	#}

	if (DebugPrintEnabled() ) {
		# dump all SRPM info
		DebugPrint "\nSRPMs:\n";
		foreach my $srpm ( @delta_srpms ) {
			DebugPrint("$srpm => Builds: '$delta_srpm_info{$srpm}{'Builds'}'\n");
			DebugPrint("           PostReq: '$delta_srpm_info{$srpm}{'PostReq'}'\n");
			DebugPrint("           Available: '$delta_srpm_info{$srpm}{'Available'}'\n");
			DebugPrint("           Available: ".available_srpm($srpm, "user", $osver)." PartOf '$delta_srpm_info{$srpm}{'PartOf'}'\n");
		}

		# dump all RPM info
		DebugPrint "\nRPMs:\n";
		foreach my $package ( @delta_rpms ) {
			DebugPrint("$package => Parent: '$delta_rpm_info{$package}{'Parent'}' Available: $delta_rpm_info{$package}{'Available'} \n");
			DebugPrint("           Mode: $delta_rpm_info{$package}{'Mode'} PartOf: '$delta_rpm_info{$package}{'PartOf'}'\n");
		}

		# dump all DELTA component info
		DebugPrint "\nDELTA Components:\n";
		foreach my $comp ( @delta_components ) {
			DebugPrint("   $comp: KernelRpms: @{ $delta_comp_info{$comp}{'KernelRpms'}}\n");
			DebugPrint("           UserRpms: @{ $delta_comp_info{$comp}{'UserRpms'}}\n");
			DebugPrint("           DebugRpms: @{ $delta_comp_info{$comp}{'DebugRpms'}}\n");
			DebugPrint("           Drivers: $delta_comp_info{$comp}{'Drivers'}\n");
			DebugPrint("           StartupParams: @{ $delta_comp_info{$comp}{'StartupParams'}}\n");
		}
		DebugPrint "\n";
	}
}

# delta specific rpm functions,
# install available user or kernel rpms in list
# returns 1 if hfi1 was installed
sub delta_rpm_install_list($$$@)
{
	my $rpmdir = shift();
	my $rpmdir_t;
	my $osver = shift();	# OS version
	my $skip_kernelib = shift();	# should compat-rdma be skipped if in package_list
	my(@package_list) = @_;	# package names
	my $ret = 0;

	# user space RPM installs
	foreach my $package ( @package_list )
	{
		$rpmdir_t=$rpmdir;
		if ($delta_rpm_info{$package}{'Available'} ) {
			if ( "$delta_rpm_info{$package}{'Mode'}" eq "kernel" ) {
				if ( "$CUR_VENDOR_VER" eq "ES72" || "$CUR_VENDOR_VER" eq "ES73" || "$CUR_VENDOR_VER" eq "ES122" ) {
					if ( $package =~ /ifs-kernel-updates/ ) {
						if ( $GPU_Install == 1 ) {
                                                        $rpmdir_t=$rpmdir."/CUDA";
                                                }
						next if ( $skip_kernelib);
						$ret = 1;
					}
				} elsif ( "$CUR_VENDOR_VER" eq "ES67" ) {
					if ( " $package " =~ / ifs-kernel-updates / ) {
                                                next if ( $skip_kernelib);
                                                $ret = 1;
                                        }
				} else {
					if ( " $package " =~ / compat-rdma / ) {
						next if ( $skip_kernelib);
						$ret = 1;
					}
				}
				rpm_install_with_options($rpmdir_t, $osver, $package, " -U --nodeps ");
			} else {
				if ( $GPU_Install == 1 ) {
                                        if ( -d $rpmdir."/CUDA" ) {
                                                if ( $package =~ /libpsm/ || $package =~ /ifs-kernel-updates/) {
                                                        $rpmdir_t=$rpmdir."/CUDA";
                                                }
                                        } else {
                                                NormalPrint("CUDA specific packages do not exist\n");
                                                exit 0;
                                        }
                                }
				rpm_install_with_options($rpmdir_t, "user", $package, " -U --nodeps ");
			}
		}
	}
	return $ret;
}

# verify all rpms in list are installed
sub delta_rpm_is_installed_list($@)
{
	my $osver = shift();
	my(@package_list) = @_;	# package names

	foreach my $package ( @package_list )
	{
		if ($delta_rpm_info{$package}{'Available'} ) {
			if ( "$delta_rpm_info{$package}{'Mode'}" eq "kernel" ) {
				if (! rpm_is_installed($package, $osver) ) {
					return 0;
				}
			} else {
				if (! rpm_is_installed($package, "user") ) {
					return 0;
				}
			}
		}
	}
	return 1;
}
# verify the rpmfiles exist for all the kernel RPMs listed
sub delta_rpm_exists_list($$@)
{
	my $rpmdir = shift();
	my $mode = shift();	#  "user" or kernel rev
	my(@package_list) = @_;	# package names
	my $avail;

	$avail="Available";

	foreach my $package ( @package_list )
	{
		next if ( "$package" eq '' );
		if ($delta_rpm_info{$package}{$avail} ) {
			if (! rpm_exists($rpmdir, $mode, $package) ) {
				return 0;
			}
		}
	}
	return 1;
}

# returns install prefix for presently installed DELTA
sub delta_get_prefix()
{
	my $prefix = "/usr";	# default
	return "$prefix";
}

# unfortunately OFED mpitests leaves empty directories on uninstall
# this can confuse IFS MPI tools because correct MPI to use
# cannot be identified.  This remove such empty directories for all
# compilers in all possible prefixes for OFED
sub delta_cleanup_mpitests()
{
	my $prefix = ofed_get_prefix();

	if ( -e "$ROOT$prefix/mpi") {
		system("cd '$ROOT$prefix/mpi'; rmdir -p */*/tests/* >/dev/null 2>&1");
	}
	if ( -e "$ROOT/usr/mpi") {
		system("cd $ROOT/usr/mpi; rmdir -p */*/tests/* >/dev/null 2>&1");
	}
	if ( -e "$ROOT/$OFED_prefix/mpi") {
		system("cd '$ROOT/$OFED_prefix/mpi'; rmdir -p */*/tests/* >/dev/null 2>&1");
	}
}

# uninstall rpms which are in package_list and are not needed by
# any components in install_list
# all variations of the specified packages are uninstalled
sub delta_rpm_uninstall_not_needed_list($$$$@)
{
	my $install_list = shift();	# components which will remain on system
	my $uninstalling_list = shift();	# components which are being uninstalled
	my $comp = shift();	# component being uninstalled
	my $verbosity = shift();
	my(@package_list) = @_;	# package names to consider for uninstall

RPM: foreach my $package ( reverse(@package_list) ) {
		my @install_list = split /[[:space:]]+/, $install_list;
		foreach my $c ( @install_list ) {
			next if ( "$c" eq '' ); # handling leading spaces
			# see if package is part of a component we are interested in
			if ( " @delta_components " =~ / $c /
				 && " $delta_rpm_info{$package}{'PartOf'} " =~ / $c / ) {
				next RPM;	# its still needed, leave it installed
			}
		}
		if ( $delta_rpm_info{$package}{'Available'} == 0 ) {
			next RPM; # package was not installed.
		}
		# if we get here, package is not in any component we are interested in
		if ( "$uninstalling_list" ne "" && "$comp" ne "" ) {
			# we are doing an explicit uninstall, we must be careful
			# about rpms which are part of more than 1 component
			# uninstalling_list is in dependency order and is executed
			# backwards, so once we get to processing the 1st component
			# in uninstalling list which has this package, we know its
			# safe to remove the package
			my @uninstalling = split /[[:space:]]+/, $uninstalling_list;
			foreach my $c ( @uninstalling ) {
				next if ( "$c" eq '' ); # handling leading spaces
				if ( " @delta_components " =~ / $c /
					&& " $delta_rpm_info{$package}{'PartOf'} " =~ / $c / ) {
					# found 1st uninstalled component with package
					if ("$c" ne "$comp") {
						next RPM;	# don't remove til get to $c's uninstall
					} else {
						last;	# exit this loop and uninstall package
					}
				}
			}
		}
		rpm_uninstall($package, "any", " --nodeps ", $verbosity);
	}
}


# resolve filename within $srcdir/$SRPMS_SUBDIR
# and return filename relative to $srcdir
sub delta_srpm_file($$)
{
	my $srcdir = shift();
	my $globname = shift(); # in $srcdir
	my $result;

        if ( $GPU_Install == 1 ) {
                if ( -d $srcdir."/SRPMS/CUDA" ) {
                        if ("$globname" eq "libpsm2*.src.rpm") {
                                $result = file_glob("$srcdir/$SRPMS_SUBDIR/CUDA/$globname");
                        } elsif ("$globname" eq "ifs-kernel-updates*.src.rpm"){
                                $result = file_glob("$srcdir/$SRPMS_SUBDIR/CUDA/$globname");
                        }
                } else {
                        NormalPrint("CUDA specific SRPMs do not exist\n");
                        exit 0;
                }
        } else {
                $result = file_glob("$srcdir/$SRPMS_SUBDIR/$globname");
        }

	$result =~ s|^$srcdir/||;
	return $result;
}

# indicate where DELTA built RPMs can be found
sub delta_rpms_dir()
{
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};
	# we purposely use a different directory than OFED, this way
	# runs of OFED install or build scripts will not confuse the IFS
	# wrapped install
	##return "$srcdir/$RPMS_SUBDIR/$RPM_DIST/";
	if (-d "$srcdir/$RPMS_SUBDIR/$CUR_DISTRO_VENDOR-$CUR_VENDOR_VER"
		|| ! -d "$srcdir/$RPMS_SUBDIR/$CUR_DISTRO_VENDOR-$CUR_VENDOR_MAJOR_VER") {
		return "$srcdir/$RPMS_SUBDIR/$CUR_DISTRO_VENDOR-$CUR_VENDOR_VER";
	} else {
		return "$srcdir/$RPMS_SUBDIR/$CUR_DISTRO_VENDOR-$CUR_VENDOR_MAJOR_VER";
	}
}

#
# get prefix used when last built rpms
sub get_delta_rpm_prefix($)
{
	my $rpmsdir = shift();

	my $prefix_file = "$rpmsdir/Prefix";
	if ( ! -e "$prefix_file") {
		return "invalid and unknown";	# unknown, play it safe and rebuild
	} else {
		my $prefix = `cat $prefix_file 2>/dev/null`;
		chomp $prefix;
		return $prefix;
	}
}
sub save_delta_rpm_prefix($$)
{
	my $rpmsdir = shift();
	my $prefix = shift();

	my $prefix_file = "$rpmsdir/Prefix";
	system("mkdir -p $rpmsdir");
	system "echo $prefix > $prefix_file";
}

# verify if all rpms have been built from the given srpm
sub is_built_srpm($$)
{
	my $srpm = shift();	# srpm name prefix
	my $mode = shift();	# "user" or kernel rev
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};
	my $rpmsdir = delta_rpms_dir();

	my @rpmlist = split /[[:space:]]+/, $delta_srpm_info{$srpm}{'Builds'};
	return ( delta_rpm_exists_list("$rpmsdir", $mode, @rpmlist) );
}

# see if srpm is part of any of the components being installed/reinstalled
sub need_srpm_for_install($$$$)
{
	my $srpm = shift();	# srpm name prefix
	my $mode = shift();	# "user" or kernel rev
	my $osver = shift();
	# add space at start and end so can search
	# list with spaces around searched comp
	my $installing_list = " ".shift()." "; # items being installed/reinstalled

	if (! available_srpm($srpm, $mode, $osver)) {
		DebugPrint("$srpm $mode $osver not available\n");
		return 0;
	}

	my @complist = split /[[:space:]]+/, $delta_srpm_info{$srpm}{'PartOf'};
	foreach my $comp (@complist) {
		next if ("$comp" eq '');
		DebugPrint("Check for $comp in ( $installing_list )\n");
		if ($installing_list =~ / $comp /) {
			return 1;
		}
	}
	return 0;
}

sub need_build_srpm($$$$$$)
{
	my $srpm = shift();	# srpm name prefix
	my $mode = shift();	# "user" or kernel rev
	my $osver = shift();	# kernel rev
	my $installing_list = shift(); # what items are being installed/reinstalled
	my $force = shift();	# force a rebuild
	my $prompt = shift();	# prompt (only used if ! $force)

	return ( need_srpm_for_install($srpm, $mode, $osver, $installing_list)
			&& ($force
				|| ! is_built_srpm($srpm, $mode)
				|| ($prompt && GetYesNo("Rebuild $srpm src RPM for $mode?", "n"))));
}

sub need_install_rpm_list($$$@)
{
	my $osver = shift();
	my $force = shift();
	my $prompt = shift();	# prompt (only used if ! $force)
	my(@package_list) = @_;	# package names
	my $found = 0;
	my @available_list = ();

	foreach my $package ( @package_list ) {
		if ($delta_rpm_info{$package}{'Available'}) {
			@available_list = ( @available_list, $package );
		}
	}
	if (! scalar(@available_list)) {
		return 0;	# nothing to consider for install
	}
	return ($force
			|| ! delta_rpm_is_installed_list($osver, @available_list)
			|| ($prompt && GetYesNo("Reinstall @available_list for use during build?", "n")));
}

# move rpms from build tree (srcdir) to install tree (destdir)
sub delta_move_rpms($$)
{
	my $srcdir = shift();
	my $destdir = shift();

	system("mkdir -p $destdir");
	if (file_glob("$srcdir/$RPM_ARCH/*") ne "" ) {
		system("mv $srcdir/$RPM_ARCH/* $destdir");
	}
	if (file_glob("$srcdir/$RPM_KERNEL_ARCH/*") ne "" ) {
		system("mv $srcdir/$RPM_KERNEL_ARCH/* $destdir");
	}
	if (file_glob("$srcdir/noarch/*") ne "" ) {
		system("mv $srcdir/noarch/* $destdir");
	}
}

sub remove_unneeded_kernel_ib_drivers($);

# install rpms which were PostReqs of previous srpms
sub delta_install_needed_rpms($$$$$@)
{
	my $install_list = shift();	# total that will be installed when done
	my $osver = shift();	# kernel rev
	my $force_rpm = shift();
	my $prompt_rpm = shift();
	my $rpmsdir = shift();
	my @need_install = @_;

	if (need_install_rpm_list($osver, $force_rpm, $prompt_rpm, @need_install)) {
		if (delta_rpm_install_list("$rpmsdir", $osver, 0, @need_install)) {
			remove_unneeded_kernel_ib_drivers($install_list);
		}
	}
}

# Build RPM from source RPM
# build a specific SRPM
# this is heavily based on build_rpm in OFED install.pl
# main changes from cut and paste are marked with # IFS commands
# this has an srpm orientation and is only called when we really want to
# build the srpm
sub build_srpm($$$$$)
{
	my $srpm = shift();	# the srpm package name
	my $TOPDIR = shift();	# top directory for build
	my $BUILD_ROOT = shift();	# temp directory for build
	my $prefix = shift();	# prefix for install path
	my $resfileop = shift(); # append or replace build.res file
	my $configure_options = '';	# delta keeps per srpm, but only initializes here
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};
	my $SRC_RPM = delta_srpm_file($srcdir, "$srpm*.src.rpm");

	# Deal with SLES renaming
	if ("$srpm" eq "libibumad3") {
		$SRC_RPM = delta_srpm_file($srcdir, "libibumad-*.src.rpm");
	} elsif ("$srpm" eq "libibmad5") {
		$SRC_RPM = delta_srpm_file($srcdir, "libibmad-*.src.rpm");
	} elsif ("$srpm" eq "openshmem") {
		$SRC_RPM = delta_srpm_file($srcdir, "${srpm}_*.src.rpm");
	} elsif ("$srpm" eq "kmod-ifs-kernel-updates") {
		$SRC_RPM = delta_srpm_file($srcdir, "ifs-kernel-updates*.src.rpm");
	} elsif ("$srpm" eq "ifs-kernel-updates-kmp-default") {
		$SRC_RPM = delta_srpm_file($srcdir, "ifs-kernel-updates*.src.rpm");
	}

	# convert a few variables into the names used in OFED's build_rpm
	my $parent = $srpm;
	my $distro = "$CUR_DISTRO_VENDOR";
    my $dist_rpm_rel  = $RPM_DIST_REL;
    my $target_cpu = $RPM_ARCH;
    my $optflags = rpm_query_param('optflags');
    my $mandir = rpm_query_param('_mandir');
    my $sysconfdir = rpm_query_param('_sysconfdir');
    my $arch = my_tolower($ARCH);

    my $cmd;

    my $ldflags;
    my $cflags;
    my $cppflags;
    my $cxxflags;
    my $fflags;
    my $ldlibs;
    my $openmpi_comp_env;

    my $pref_env;
    if ($prefix ne $default_prefix) {
        $pref_env .= " LD_LIBRARY_PATH=$prefix/lib64:$prefix/lib:\$LD_LIBRARY_PATH";
        if ($parent ne "mvapich2" and $parent ne "openmpi") {
            $ldflags .= "$optflags -L$prefix/lib64 -L$prefix/lib";
            $cflags .= "$optflags -I$prefix/include";
            $cppflags .= "$optflags -I$prefix/include";
        }
    }

	# IFS - OFED tested rpm_exist.  We only get here if we
	# want to build the rpm, so we force true and proceed
	# (keeps indentation same as OFED install.pl for easier cut/paste)
    if (1) {
        if ($ldflags) {
            $pref_env   .= " LDFLAGS='$ldflags'";
        }
        if ($cflags) {
            $pref_env   .= " CFLAGS='$cflags'";
        }
        if ($cppflags) {
            $pref_env   .= " CPPFLAGS='$cppflags'";
        }
        if ($cxxflags) {
            $pref_env   .= " CXXFLAGS='$cxxflags'";
        }
        if ($fflags) {
            $pref_env   .= " FFLAGS='$fflags'";
        }
        if ($ldlibs) {
            $pref_env   .= " LDLIBS='$ldlibs'";
        }

        $cmd = "$pref_env rpmbuild --rebuild --define '_topdir $TOPDIR'";
        $cmd .= " --define 'dist  %{nil}'";
        $cmd .= " --target $target_cpu";
		# IFS - also set build_root so we can cleanup and avoid conflicts
    	$cmd .= " --buildroot '${BUILD_ROOT}'";
    	$cmd .= " --define 'build_root ${BUILD_ROOT}'";

        # Prefix should be defined per package
		# IFS - dropped MPIs, built via do_X_build scripts instead
        if ($parent eq "mpi-selector") {
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define 'shell_startup_dir /etc/profile.d'";
        }
# TBD - odd that prefix, exec_prefix, sysconfdir and usr not defined
# IFS - may want to add these 4 just to be safe, they are not in OFED
#            $cmd .= " --define '_prefix $prefix'";
#            $cmd .= " --define '_exec_prefix $prefix'";
#            $cmd .= " --define '_sysconfdir $sysconfdir'";
#            $cmd .= " --define '_usr $prefix'";
        else {
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
        }

		# IFS - keep configure_options as a local
        if ($configure_options or $OFED_user_configure_options) {
            $cmd .= " --define 'configure_options $configure_options $OFED_user_configure_options'";
        }

		# IFS - use SRC_RPM (computed above) instead of srpmpath_for_distro
#       $cmd .= " $main_packages{$parent}{'srpmpath'}";
		$cmd .= " $SRC_RPM";

	if ("$srpm" eq "gasnet") {
	    $cmd .= " --define '_name gasnet_openmpi_hfi'";
	    $cmd .= " --define '_prefix /usr/shmem/gcc/gasnet-1.28.2-openmpi-hfi'";
	    $cmd .= " --define '_name gasnet_gcc_hfi'";
	    $cmd .= " --define 'spawner mpi'";
	    $cmd .= " --define 'mpi_prefix /usr/mpi/gcc/openmpi-1.10.4-hfi'";
	}

	if ("$srpm" eq "openshmem") {
	    $cmd .= " --define '_name openshmem_gcc_hfi'";
	    $cmd .= " --define '_prefix /usr/shmem/gcc/openshmem-1.3-hfi'";
	    $cmd .= " --define 'gasnet_prefix /usr/shmem/gcc/gasnet-1.28.2-openmpi-hfi'";
	    $cmd .= " --define 'configargs --with-gasnet-threnv=seq'";
	}

	if ("$srpm" eq "openshmem-test-suite") {
	    $cmd .= " --define '_name openshmem-test-suite_gcc_hfi'";
	    $cmd .= " --define '_prefix /usr/shmem/gcc/openshmem-1.3-hfi'";
	    $cmd .= " --define 'openshmem_prefix /usr/shmem/gcc/openshmem-1.3-hfi'";
	}

	if ("$srpm" eq "shmem-benchmarks") {
	    $cmd .= " --define '_prefix /usr/shmem/gcc/openshmem-1.3-hfi'";
	    $cmd .= " --define 'openshmem_prefix /usr/shmem/gcc/openshmem-1.3-hfi'";
	}

		return run_build("$srcdir $SRC_RPM $RPM_ARCH", "$srcdir", $cmd, "$resfileop");
	}
	# NOTREACHED
}

# build all OFED components specified in installing_list
# if already built, prompt user for option to build
sub build_delta($$$$$$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift(); # what items are being installed/reinstalled
	my $K_VER = shift();	# osver
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild

	my $prompt_srpm = 0;	# prompt per SRPM
	my $prompt_rpm = 0;	# prompt per RPM
	my $force_srpm = $force;	# force SRPM rebuild
	my $force_kernel_srpm = ("$OFED_kernel_configure_options" ne "");
	my $force_user_srpm = ("$OFED_user_configure_options" ne "");
	my $force_rpm = $force;	# force dependent RPM reinstall
	my $rpmsdir = delta_rpms_dir();

	my $prefix=$OFED_prefix;
	if ("$prefix" ne get_delta_rpm_prefix($rpmsdir)) {
		$force_kernel_srpm = 1;
		$force_user_srpm = 1;
	}

	if (! $force && ! $Default_Prompt && ! ($force_user_srpm && $force_kernel_srpm)) {
		my $choice = GetChoice("Rebuild OFA SRPMs (a=all, p=prompt per SRPM, n=only as needed?)", "n", ("a", "p", "n"));
		if ("$choice" eq "a") {
			$force_srpm=1;
		} elsif ("$choice" eq "p") {
			$prompt_srpm=1;
		} elsif ("$choice" eq "n") {
			$prompt_srpm=0;
		}
	}
	# we base our decision on status of opa_stack.  Possible risk if
	# opa_stack is partially upgraded and was interrupted.
	if (! comp_is_uptodate('opa_stack') || $force_srpm  || $force_user_srpm || $force_kernel_srpm) {
		$force_rpm = 1;
	} elsif (! $Default_Prompt) {
		my $choice = GetChoice("Reinstall OFA dependent RPMs (a=all, p=prompt per RPM, n=only as needed?)", "n", ("a", "p", "n"));
		if ("$choice" eq "a") {
			$force_rpm=1;
		} elsif ("$choice" eq "p") {
			$prompt_rpm=1;
		} elsif ("$choice" eq "n") {
			$prompt_rpm=0;
		}
	}

	# -------------------------------------------------------------------------
	# do all rebuild prompting first so user doesn't have to wait 5 minutes
	# between prompts
	my %build_kernel_srpms = ();
	my $need_build = 0;
	my $build_compat_rdma = 0;

	if(!$skip_kernel) {
		foreach my $kernel_srpm ( @delta_kernel_srpms ) {
			$build_kernel_srpms{"${kernel_srpm}_build_kernel"} = need_build_srpm($kernel_srpm, "$K_VER", "$K_VER",
								$installing_list,
								$force_srpm || $force_kernel_srpm || $OFED_debug,
								$prompt_srpm);
			if ("$kernel_srpm" eq "compat-rdma" &&
				$build_kernel_srpms{"${kernel_srpm}_build_kernel"}) {
				$build_compat_rdma = 1;
			}
			$need_build |= $build_kernel_srpms{"${kernel_srpm}_build_kernel"};
		}
	}

	my %build_user_srpms = ();
	foreach my $srpm ( @delta_user_srpms ) {
		VerbosePrint("check if need to build $srpm\n");
		$build_user_srpms{"${srpm}_build_user"} = 0;

		# mpitests is built as part of mvapich, openmpi and mvapich2
		next if ( "$srpm" eq "mpitests" );

			$build_user_srpms{"${srpm}_build_user"} = 
					need_build_srpm($srpm, "user", "$K_VER", $installing_list,
							$force_srpm || $force_user_srpm,$prompt_srpm);
		$need_build |= $build_user_srpms{"${srpm}_build_user"};
	}

	if (! $need_build) {
		return 0;	# success
	}

	# -------------------------------------------------------------------------
	# check OS dependencies for all srpms which we will build
	my $dep_error = 0;

	NormalPrint "Checking OS Dependencies needed for builds...\n";

	if(!$skip_kernel) {
		foreach my $srpm ( @delta_kernel_srpms ) {
			next if ( ! $build_kernel_srpms{"${srpm}_build_kernel"} );

			VerbosePrint("check dependencies for $srpm\n");
			if (check_kbuild_dependencies($K_VER, $srpm )) {
				DebugPrint "$srpm kbuild dependency failure\n";
				$dep_error = 1;
			}
			if (check_rpmbuild_dependencies($srpm)) {
				DebugPrint "$srpm rpmbuild dependency failure\n";
				$dep_error = 1;
			}
		}
	}

	foreach my $srpm ( @delta_user_srpms ) {
		# mpitests is built as part of mvapich, openmpi and mvapich2
		next if ( "$srpm" eq "mpitests" );

		my $build_user = $build_user_srpms{"${srpm}_build_user"};

		next if ( ! ($build_user));

		VerbosePrint("check dependencies for $srpm\n");

		if (check_rpmbuild_dependencies($srpm)) {
			DebugPrint "$srpm rpmbuild dependency failure\n";
			$dep_error = 1;
		}
		if ($build_user) {
			DebugPrint "Check $srpm user build prereqs\n";
			if (check_build_dependencies($srpm)) {
				$dep_error = 1;
			}
			if (rpm_check_build_os_prereqs("any", $srpm, 
						@{ $delta_srpm_info{$srpm}{'BuildPrereq'}})) {
				DebugPrint "$srpm prereqs dependency failure\n";
				$dep_error = 1;
			}
		}
	}
	if ($dep_error) {
		NormalPrint "ERROR - unable to perform builds due to need for additional OS rpms\n";
		return 1;	# failure
	}

	# -------------------------------------------------------------------------
	# perform the builds
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};

	my $must_force_rpm = 0;	# set if we rebuild something so force updates
	my @need_install = ( );	# keep track of PostReqs not yet installed
	my @installed = ();	# rpms we installed to facilitate builds

	if ("$prefix" ne get_delta_rpm_prefix($rpmsdir)) {
		#system("rm -rf $rpmsdir");	# get rid of stuff with old prefix
		save_delta_rpm_prefix($rpmsdir, $prefix);
	}

	# use a different directory for BUILD_ROOT to limit conflict with OFED
	if ("$build_temp" eq "" ) {
		$build_temp = "/var/tmp/IntelOPA-DELTA";
	}
	my $BUILD_ROOT="$build_temp/build";
	my $RPM_DIR="$build_temp/DELTARPMS";
	my $mandir = rpm_query_param("_mandir");
	my $resfileop = "replace";	# replace for 1st build, append for rest

	system("rm -rf ${build_temp}");

	# use a different directory for BUILD_ROOT to limit conflict with OFED
	if (0 != system("mkdir -p $BUILD_ROOT $RPM_DIR/BUILD $RPM_DIR/RPMS $RPM_DIR/SOURCES $RPM_DIR/SPECS $RPM_DIR/SRPMS")) {
		NormalPrint "ERROR - mkdir -p $BUILD_ROOT $RPM_DIR/BUILD $RPM_DIR/RPMS $RPM_DIR/SOURCES $RPM_DIR/SPECS $RPM_DIR/SRPMS FAILED\n";
		return 1;	# failure
	}

	# OFED has all the ULPs in a single compat-rdma RPM.  We build that
	# RPM here from the compat-rdma SRPM with all ULPs included.
	# Later during install we remove ULPs not desired after installing
	# the compat-rdma RPM
	if ($build_compat_rdma)
	{
		my $OFA_KERNEL_SRC_RPM=delta_srpm_file($srcdir,"compat-rdma*.src.rpm");
		my $K_SRC = "/lib/modules/$K_VER/build";
		my $configure_options_kernel;
		my $cok_macro;
		my $rpm_release = rpm_query_attr("$srcdir/$OFA_KERNEL_SRC_RPM", "RELEASE");

		$configure_options_kernel = get_build_options($K_VER, %delta_kernel_ib_options);
		if ( $OFED_debug ) {
			# TBD --with-memtrack
			#$configure_options_kernel .= " --with-memtrack";
		}
		my $conf_opts = "--with-core-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod --with-ipoib-mod  --with-rdmavt-mod --with-hfi1-mod  --with-qib-mod  --with-srp-mod  --with-srp-target-mod";
		VerbosePrint("OS specific kernel configure options: '$configure_options_kernel'\n");

		if ($configure_options_kernel != "") {
			$cok_macro=" --define 'configure_options ${configure_options_kernel} $OFED_kernel_configure_options'";
		} else {
			$cok_macro=" --define 'configure_options ${conf_opts}'";
		}

		if (0 != run_build("$srcdir $OFA_KERNEL_SRC_RPM $RPM_KERNEL_ARCH $K_VER", "$srcdir",
				 "rpmbuild --rebuild --define '_topdir ${RPM_DIR}'"
        		.		" --target $RPM_KERNEL_ARCH"
				.		" --define '_prefix ${prefix}'"
				.		" --buildroot '${BUILD_ROOT}'"
				.		" --define 'build_root ${BUILD_ROOT}'"
				.		$cok_macro
				.		" --define 'KVERSION ${K_VER}'"
				.		" --define 'KSRC ${K_SRC}'"
				.		" --define 'build_kernel_ib 1'"
				.		" --define 'build_kernel_ib_devel 1'"
				.		" --define 'network_dir ${NETWORK_CONF_DIR}'"
            	.		" --define '__arch_install_post %{nil}'"
				.		" --define '_release $rpm_release'"
				.		" ${OFA_KERNEL_SRC_RPM}",
				"$resfileop"
				)) {
			return 1;	# failure
		}
		$must_force_rpm=1;
		$resfileop = "append";
		delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmsdir");
	}
	@need_install = ( @need_install, split /[[:space:]]+/, $delta_srpm_info{'compat-rdma'}{'PostReq'});

	if(!$skip_kernel) {
		foreach my $srpm ( @delta_kernel_srpms ) {
			VerbosePrint("process $srpm\n");

			# compat-rdma is special cased above skip it here
			next if ( "$srpm" eq "compat-rdma" );

			my $build_kernel = $build_kernel_srpms{"${srpm}_build_kernel"};

			if ($build_kernel) {
				$resfileop = "append";
				if (0 != build_srpm($srpm, $RPM_DIR, $BUILD_ROOT, $prefix, $resfileop)) {
					return 1;	# failure
				}
				@need_install = ( @need_install, split /[[:space:]]+/, $delta_srpm_info{$srpm}{'PostReq'});
				$must_force_rpm=1;
				delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmsdir");
			}
		}
	}

	foreach my $srpm ( @delta_user_srpms ) {
		VerbosePrint("process $srpm\n");

		# mpitests is built as part of mvapich, openmpi and mvapich2
		next if ( "$srpm" eq "mpitests" );

		my $build_user = $build_user_srpms{"${srpm}_build_user"};

			if ($build_user) {
				# load rpms which are were PostReqs from previous srpm builds
				delta_install_needed_rpms($install_list, $K_VER, $force_rpm||$must_force_rpm, $prompt_rpm, $rpmsdir, @need_install);
				@installed = ( @installed, @need_install);
				@need_install = ();
				$must_force_rpm=0;

				# build it
				if ("$srpm" eq "mvapich2" ) {
					if (0 != run_build("mvapich2_gcc and mpitests_mvapich2_gcc", "$srcdir", "STACK_PREFIX='$prefix' BUILD_DIR='$build_temp' MPICH_PREFIX= CONFIG_OPTIONS='$OFED_user_configure_options' INSTALL_ROOT='$ROOT' ./do_mvapich2_build -d -i gcc", $resfileop)) {
						return 1;	# failure
					}
					# build already installed mvapich2_gcc
					@installed = ( @installed, split /[[:space:]]+/, 'mvapich2_gcc');
					$resfileop = "append";
					$must_force_rpm=1;

					delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmsdir");

					if (0 != run_build("mvapich2_gcc_hfi and mpitests_mvapich2_gcc_hfi", "$srcdir", "STACK_PREFIX='$prefix' BUILD_DIR='$build_temp' MPICH_PREFIX= CONFIG_OPTIONS='$OFED_user_configure_options' INSTALL_ROOT='$ROOT' ./do_mvapich2_build -d -i -O  gcc", $resfileop)) {
						return 1;	# failure
					}
					# build already installed mvapich2_gcc_hfi
					@installed = ( @installed, split /[[:space:]]+/, 'mvapich2_gcc_hfi');
					$resfileop = "append";
					$must_force_rpm=1;

				} elsif ("$srpm" eq "openmpi" ) {
					if (0 != run_build("openmpi_gcc and mpitests_openmpi_gcc", "$srcdir", "STACK_PREFIX='$prefix' BUILD_DIR='$build_temp' MPICH_PREFIX= CONFIG_OPTIONS='$OFED_user_configure_options' INSTALL_ROOT='$ROOT' ./do_openmpi_build -d -i gcc", $resfileop)) {
						return 1;	# failure
					}
					# build already installed openmpi_gcc
					@installed = ( @installed, split /[[:space:]]+/, 'openmpi_gcc');
					$resfileop = "append";
					$must_force_rpm=1;

					delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmsdir");

					if (0 != run_build("openmpi_gcc_hfi and mpitests_openmpi_gcc_hfi", "$srcdir", "STACK_PREFIX='$prefix' BUILD_DIR='$build_temp' MPICH_PREFIX= CONFIG_OPTIONS='$OFED_user_configure_options' INSTALL_ROOT='$ROOT' ./do_openmpi_build -d -i -O gcc", $resfileop)) {
						return 1;	# failure
					}
					# build already installed openmpi_gcc
					@installed = ( @installed, split /[[:space:]]+/, 'openmpi_gcc_hfi');
					$resfileop = "append";
					$must_force_rpm=1;
				} else {	# all non-MPI user RPMs
					if ($build_user) {
						if (0 != build_srpm($srpm, $RPM_DIR, $BUILD_ROOT, $prefix, $resfileop)) {
							return 1;	# failure
						}
						$resfileop = "append";
					}
					$resfileop = "append";
					@need_install = ( @need_install, split /[[:space:]]+/, $delta_srpm_info{$srpm}{'PostReq'});
					$must_force_rpm=1;
				}
				delta_move_rpms("$RPM_DIR/$RPMS_SUBDIR", "$rpmsdir");
			} else {
				@need_install = ( @need_install, split /[[:space:]]+/, $delta_srpm_info{$srpm}{'PostReq'});
			}
		}

	# get rid of rpms we installed to enable builds but are not desired to stay
	# eg. uninstall rpms which were installed but are not part of install_list
	delta_rpm_uninstall_not_needed_list($install_list, "", "", "verbose", @installed);

	if (! $debug) {
		system("rm -rf ${build_temp}");
	} else {
		LogPrint "Build remnants left in $BUILD_ROOT and $RPM_DIR\n";
	}

	return 0;	# success
}

# forward declarations
sub installed_delta_opa_stack();

# track if install_kernel_ib function was used so we only install
# compat-rdma once in a given "Perform" of install menu
my $install_kernel_ib_was_run = 0;

# return 0 on success, != 0 otherwise
sub uninstall_old_delta_rpms($$$)
{
	my $mode = shift();	# "user" or kernel rev
						# "any"- checks if any variation of package is installed
	my $verbosity = shift();
	my $message = shift();

	my $ret = 0;	# assume success
	my @packages = ();
	my @prev_release_rpms = ( "hfi1-psm-compat-devel","hfi1-psm","hfi1-psm-devel","hfi1-psm-debuginfo","libhfi1verbs","libhfi1verbs-devel", "ifs-kernel-updates" );

	if ("$message" eq "" ) {
		$message = "previous OFA Delta";
	}
	NormalPrint "\nUninstalling $message RPMs\n";

	# SLES11 includes an old version of OpenMPI that other packages may depend on, but 
	# which must be removed to prevent conflicts with the new version that we are installing. 
	#if ("$CUR_DISTRO_VENDOR" eq 'SuSE' && "$CUR_VENDOR_VER" eq 'ES11') {
	#	DebugPrint("Forcing Uninstall of SLES11 OpenMPI\n");
	#	if (rpm_uninstall_matches("SLES11 OpenMPI", "openmpi-1.2.8", "", "--nodeps")) {
	#		NormalPrint "Unable to uninstall existing openmpi installation.\n";
	#	}
	#}
	# SLES11 includes an old version of OpenMPI that other packages may depend on, but needs to be unselected in mpi-selector
	if ("$CUR_DISTRO_VENDOR" eq 'SuSE' && "$CUR_VENDOR_VER" eq 'ES11' && $mode eq 'any') {
		LogPrint "mpi-selector --unset --system >/dev/null 2>/dev/null\n";
		system("mpi-selector --unset --system >/dev/null 2>/dev/null");
		LogPrint "mpi-selector --unset --user >/dev/null 2>/dev/null\n";
		system("mpi-selector --unset --user >/dev/null 2>/dev/null");
	}

	# uninstall all present version OFA rpms, just to be safe
	foreach my $i ( reverse(@delta_components) ) {
		@packages = (@packages, @{ $delta_comp_info{$i}{'DebugRpms'}});
		@packages = (@packages, @{ $delta_comp_info{$i}{'UserRpms'}});
		@packages = (@packages, @{ $delta_comp_info{$i}{'KernelRpms'}});
	}

	# workaround LAM and other MPIs usng mpi-selector
	# we uninstall mpi-selector separately and ignore failures for its uninstall
	my @filtered_packages = ();
	my @rest_packages = ();
	foreach my $i ( @packages ) {
		if ( $delta_rpm_info{$i}{'Available'} == 0 ) {
			next; # skip, rpm was not installed.
		}
		if (scalar(grep /^$i$/, (@filtered_packages, @rest_packages)) > 0) {
			# skip, already in list
		} elsif ( "$i" eq "mpi-selector" ) {
			@rest_packages = (@rest_packages, "$i");
		} elsif ("$i" eq "openmpi") {
			if ("$CUR_DISTRO_VENDOR" eq 'SuSE' && "$CUR_VENDOR_VER" eq 'ES11') {
				# SLES11 openmpi is used by boost
				# keep openmpi for now
				#@filtered_packages = (@filtered_packages, "boost-devel", "libboost_mpi1_36_0", "$i");
				# try to remove it, but ignore errors
				@rest_packages = (@rest_packages, "$i");
			} else {
				@filtered_packages = (@filtered_packages, "$i");
			}
		} else {
			@filtered_packages = (@filtered_packages, "$i");
		}
	}

	$ret ||= rpm_uninstall_all_list_with_options($mode, " --nodeps ", $verbosity, @filtered_packages);

	# ignore errors uninstalling mpi-selector
	if (scalar(@rest_packages) != 0) {
		if (rpm_uninstall_all_list_with_options($mode, " --nodeps ", $verbosity, @rest_packages) && ! $ret) {
			NormalPrint "The previous errors can be ignored\n";
		}
	}

	if (rpm_uninstall_all_list_with_options($mode, " --nodeps ", $verbosity, @prev_release_rpms) && ! $ret) {
		NormalPrint "The previous errors can be ignored\n";
	}

	delta_cleanup_mpitests();

	if ( $ret ) {
		NormalPrint "Unable to uninstall $message RPMs\n";
	}
	return $ret;
}


# remove any old stacks or old versions of the stack
# this is necessary before doing builds to ensure we don't use old dependent
# rpms
sub uninstall_prev_versions()
{
	if (! installed_delta_opa_stack) {
		return 0;
	} elsif (! comp_is_uptodate('opa_stack')) { # all delta_comp same version
		if (0 != uninstall_old_delta_rpms("any", "silent", "previous OFA DELTA")) {
			return 1;
		}
	}
	return 0;
}

sub media_version_delta()
{
	# all OFED components at same version as opa_stack
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};
	return `cat "$srcdir/Version"`;
}

sub delta_save_autostart()
{
	foreach my $comp ( @delta_components ) {
  		if ($ComponentInfo{$comp}{'HasStart'}
			&& $delta_comp_info{$comp}{'StartupScript'} ne "") { 
			$delta_autostart_save{$comp} = comp_IsAutostart2($comp);
		} else {
			$delta_autostart_save{$comp} = 0;
		}
	}
}

sub delta_restore_autostart($)
{
	my $comp = shift();

	if ( $delta_autostart_save{$comp} ) {
		comp_enable_autostart2($comp, 1);
	} else {
  		if ($ComponentInfo{$comp}{'HasStart'}
			&& $delta_comp_info{$comp}{'StartupScript'} ne "") { 
			comp_disable_autostart2($comp, 1);
		}
	}
}

# makes sure needed OFED components are already built, builts/rebuilds as needed
# called for every delta component's preinstall, noop for all but
# first OFED component in installing_list
sub preinstall_delta($$$)
{
	my $comp = shift();			# calling component
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	# make sure flag cleared so will install this if part of an installed comp
	$install_kernel_ib_was_run = 0;

	# ignore non-delta components at start of installing_list
	my @installing = split /[[:space:]]+/, $installing_list;
	while (scalar(@installing) != 0
			&& ("$installing[0]" eq ""
			 	|| " @delta_components " !~ / $installing[0] /)) {
		shift @installing;
	}
	# now, only do work if $comp is the 1st delta component in installing_list
	if ("$comp" eq "$installing[0]") {
		delta_save_autostart();
		init_delta_rpm_info($CUR_OS_VER);

		# Before we do any builds make sure old stacks removed so we don't
		# build against the wrong version of dependent rpms
		if (0 != uninstall_prev_versions()) {
			return 1;
		}
		if (ROOT_is_set()) {
			# we will build in current image, so must uninstall
			# in / as well as $ROOT (above)
			my $save_ROOT=$ROOT;
			$ROOT='/';
			my $rc = uninstall_prev_versions();
			$ROOT=$save_ROOT;
			if (0 != $rc) {
				return 1;
			}
		}
			
		print_separator;
		my $version=media_version_delta();
		chomp $version;
		printf("Preparing OFA $version $DBG_FREE for Install...\n");
		LogPrint "Preparing OFA $version $DBG_FREE for Install for $CUR_OS_VER\n";
		if (ROOT_is_set()) {
			# this directory is used during rpm installs, create it as needed
			if (0 != system("mkdir -p $ROOT/var/tmp")) {
				NormalPrint("Unable to create $ROOT/var/tmp\n");
				return 1;
			}
		}
	
		if (ROOT_is_set()) {
			# build in current image
			my $save_ROOT=$ROOT;
			$ROOT='/';
			my $rc = build_delta("$install_list", "$installing_list", "$CUR_OS_VER",0,"",$OFED_force_rebuild);
			$ROOT=$save_ROOT;
			return $rc;
		} else {
			return build_delta("$install_list", "$installing_list", "$CUR_OS_VER",0,"",$OFED_force_rebuild);
		}
	} else {
		return 0;
	}
}

# wrapper for installed_driver to handle the fact that OFED drivers used to
# be installed under updates/kernel and now are simply installed under updates
# So we check both places so that upgrade installs can properly detect drivers
# which are in the old location
sub installed_delta_driver($$$)
{
	my $WhichDriver = shift();
	my $driver_subdir = shift();
	my $subdir = shift();

	return installed_driver($WhichDriver, "$driver_subdir/$subdir")
			|| installed_driver($WhichDriver, "$driver_subdir/kernel/$subdir");
}

# ==========================================================================
# OFED DELTA generic installation routines

# since most of OFED components are simply data driven by Rpm lists in
# delta_comp_info, we can implement these support functions which do
# most of the real work for install and uninstall of components

# OFED has a single start script but controls which ULPs are loaded via
# entries in $OPA_CONFIG (rdma.conf)
# change all StartupParams for given delta component to $newvalue
sub delta_comp_change_opa_conf_param($$)
{
	my $comp=shift();
	my $newvalue=shift();

	VerbosePrint("edit $ROOT/$OPA_CONFIG $comp StartUp set to '$newvalue'\n");
	foreach my $p ( @{ $delta_comp_info{$comp}{'StartupParams'} } ) {
		change_opa_conf_param($p, $newvalue);
	}
}

# generic functions to handle autostart needs for delta components with
# more complex rdma.conf based startup needs.  These assume opa_stack handles
# the actual startup script.  Hence these focus on the rdma.conf parameters
# determine if the given capability is configured for Autostart at boot
sub IsAutostart_delta_comp2($)
{
	my $comp = shift();	# component to check
	my $WhichStartup = $delta_comp_info{$comp}{'StartupScript'};
	my $ret = IsAutostart($WhichStartup);	# just to be safe, test this too

	# to be true, all parameters must be yes
	foreach my $p ( @{ $delta_comp_info{$comp}{'StartupParams'} } ) {
			$ret &= ( read_opa_conf_param($p, "") eq "yes");
	}
	return $ret;
}
sub autostart_desc_delta_comp($)
{
	my $comp = shift();	# component to describe
	my $WhichStartup = $delta_comp_info{$comp}{'StartupScript'};
	if ( "$WhichStartup" eq "" ) {
		return "$ComponentInfo{$comp}{'Name'}"
	} else {
		return "$ComponentInfo{$comp}{'Name'} ($WhichStartup)";
	}
}
# enable autostart for the given capability
sub enable_autostart_delta_comp2($)
{
	my $comp = shift();	# component to enable
	#my $WhichStartup = $delta_comp_info{$comp}{'StartupScript'};

	#opa_stack handles this: enable_autostart($WhichStartup);
	delta_comp_change_opa_conf_param($comp, "yes");
}
# disable autostart for the given capability
sub disable_autostart_delta_comp2($)
{
	my $comp = shift();	# component to disable
	#my $WhichStartup = $delta_comp_info{$comp}{'StartupScript'};

	delta_comp_change_opa_conf_param($comp, "no");
}

# OFED has all the ULPs in a single RPM.  This function removes the
# drivers from compat-rdma specific to the given delta_component
# this is a hack, but its better than uninstall and reinstall compat-rdma
# every time a ULP is added/removed
sub remove_delta_kernel_ib_drivers($$)
{
	my $comp = shift();	# component to remove
	my $verbosity = shift();
	# cheat on driver_subdir so delta_components can have some stuff not
	# in @Components
	# we know driver_subdir is same for all delta components in compat-rdma
	my $driver_subdir=$ComponentInfo{'opa_stack'}{'DriverSubdir'};

	my $i;
	my @list = split /[[:space:]]+/, $delta_comp_info{$comp}{'Drivers'};
	for ($i=0; $i < scalar(@list); $i+=2)
	{
		my $driver=$list[$i];
		my $subdir=$list[$i+1];
		remove_driver("$driver", "$driver_subdir/$subdir", $verbosity);
		remove_driver_dirs("$driver_subdir/$subdir");
	}
}

sub print_install_banner_delta_comp($)
{
	my $comp = shift();

	my $version=media_version_delta();
	chomp $version;
	printf("Installing $ComponentInfo{$comp}{'Name'} $version $DBG_FREE...\n");
	# all OFED components at same version as opa_stack
	LogPrint "Installing $ComponentInfo{$comp}{'Name'} $version $DBG_FREE for $CUR_OS_VER\n";
}

# helper to determine if we need to reinstall due to parameter change
sub need_reinstall_delta_comp($$$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	if (get_delta_rpm_prefix(delta_rpms_dir()) ne "$OFED_prefix" ) {
		return "all";
	} elsif (! comp_is_uptodate('opa_stack')) { # all delta_comp same version
		# on upgrade force reinstall to recover from uninstall of old rpms
		return "all";
	} else {
		return "no";
	}
}

# helper which does most of the work for installing rpms and drivers
# for an OFED DELTA component
# installs compat-rdma drivers, KernelRpms and UserRpms
# caller must handle any non-RPM files
sub install_delta_comp($$)
{
	my $comp = shift();
	my $install_list = shift();	# total that will be installed when done

	# special handling for compat-rdma
	if ($ComponentInfo{$comp}{'DriverSubdir'} ne "" ) {
		install_kernel_ib(delta_rpms_dir(), $install_list);
	}
	# skip compat-rdma if in KernelRpms/UserRpms, already handled above
	delta_rpm_install_list(delta_rpms_dir(), $CUR_OS_VER, 1,
							( @{ $delta_comp_info{$comp}{'KernelRpms'}},
							@{ $delta_comp_info{$comp}{'UserRpms'}}) );
	# DebugRpms are installed as part of 'delta_debug' component

}

sub print_uninstall_banner_delta_comp($)
{
	my $comp = shift();

	NormalPrint("Uninstalling $ComponentInfo{$comp}{'Name'}...\n");
}

# uninstall all rpms associated with an OFED Delta component
sub uninstall_delta_comp_rpms($$$$)
{
	my $comp = shift();
	my $install_list = shift();
	my $uninstalling_list = shift();
	my $verbosity = shift();

	# debuginfo never in >1 component, so do explicit uninstall since
	# have an odd PartOf relationship which confuses uninstall_not_needed_list
	rpm_uninstall_list2("any", " --nodeps ", $verbosity,
					 @{ $delta_comp_info{$comp}{'DebugRpms'}});
	delta_rpm_uninstall_not_needed_list($install_list, $uninstalling_list, $comp,
				 	$verbosity, @{ $delta_comp_info{$comp}{'UserRpms'}});
	delta_rpm_uninstall_not_needed_list($install_list, $uninstalling_list, $comp,
				 	$verbosity, @{ $delta_comp_info{$comp}{'KernelRpms'}});
}

# helper which does most of the work for uninstalling rpms and drivers
# for an OFED component
# caller must handle any non-RPM files
sub uninstall_delta_comp($$$$)
{
	my $comp = shift();
	my $install_list = shift();
	my $uninstalling_list = shift();
	my $verbosity = shift();

	uninstall_delta_comp_rpms($comp, $install_list, $uninstalling_list, $verbosity);
	remove_delta_kernel_ib_drivers($comp, $verbosity);
}

# remove compat-rdma drivers for components which will not be installed
sub remove_unneeded_kernel_ib_drivers($)
{
	my $install_list = shift();	# total that will be installed when done
	foreach my $c ( @delta_components )
	{
		if ($install_list !~ / $c /) {
			remove_delta_kernel_ib_drivers($c, "verbose");
		}
	}
}

# OFED has all the ULPs in a single RPM.  This function installs that
# RPM and removes the undesired ULP drivers
sub install_kernel_ib($$)
{
	my $rpmdir = shift();
	my $install_list = shift();	# total that will be installed when done
	my $rpmdir_t = $rpmdir;

	my $driver_subdir=$ComponentInfo{'opa_stack'}{'DriverSubdir'};	# same for all delta components

	if ( $install_kernel_ib_was_run) {
		return;
	}

	$rpmdir_t = $rpmdir;
	if ( $GPU_Install == 1 ) {
                if ( -d $rpmdir."/CUDA" ) {
                        $rpmdir_t=$rpmdir."/CUDA";
                } else {
                        NormalPrint("CUDA specific packages do not exist\n");
                        exit 0;
                }
        }

	if(!$skip_kernel) {
		foreach my $srpm ( @delta_kernel_srpms ) {
			rpm_install_with_options("$rpmdir_t", $CUR_OS_VER, $srpm, " -U --nodeps ");
		}
	}
	remove_unneeded_kernel_ib_drivers($install_list);

	# rdma.conf values not directly associated with driver startup are left
	# untouched delta rpm install will keep existing value

	$install_kernel_ib_was_run = 1;
}

# ==========================================================================
# OFED opa_stack installation

# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_opa_stack()
{
	# opa_stack is tricky, there are multiple parameters.  We just test
	# the things we control here, if user has edited rdma.conf they
	# could end up with startup still disabled by having disabled all
	# the individual HCA drivers
	return IsAutostart_delta_comp2("opa_stack");
}
sub autostart_desc_opa_stack()
{
	return autostart_desc_delta_comp('opa_stack');
}
# enable autostart for the given capability
sub enable_autostart2_opa_stack()
{
	enable_autostart("opa");
}
# disable autostart for the given capability
sub disable_autostart2_opa_stack()
{
	disable_autostart("opa");
}

sub start_opa_stack()
{
	my $driver_subdir=$ComponentInfo{'opa_stack'}{'DriverSubdir'};
	start_driver($ComponentInfo{'opa_stack'}{'Name'}, "ib_core", "$driver_subdir/drivers/infiniband/core", "");
}

sub stop_opa_stack()
{
	stop_driver($ComponentInfo{'opa_stack'}{'Name'}, "ib_core", "");
}

sub available_opa_stack()
{
	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};
# TBD better checks for available?
# check file_glob("$srcdir/SRPMS/compat-rdma*.src.rpm") ne ""
#			|| rpm_exists($rpmsdir, $CUR_OS_VER, "compat-rdma")
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_delta_opa_stack()
{
	my $driver_subdir=$ComponentInfo{'opa_stack'}{'DriverSubdir'};
	if ( "$CUR_VENDOR_VER" eq "ES67" ) {
		return ( -e "$ROOT$BASE_DIR/version_delta" 
				&& rpm_is_installed("libibumad", "user")
				&& rpm_is_installed("ifs-kernel-updates", $CUR_OS_VER));
	} elsif ( "$CUR_VENDOR_VER" eq "ES72" ) {
		return ( -e "$ROOT$BASE_DIR/version_delta"
				&& rpm_is_installed("kmod-ifs-kernel-updates", $CUR_OS_VER)
				|| rpm_is_installed("ifs-kernel-updates", $CUR_OS_VER));
	} elsif ( "$CUR_VENDOR_VER" eq "ES73" ) {
		return ( -e "$ROOT$BASE_DIR/version_delta"
				&& rpm_is_installed("kmod-ifs-kernel-updates", $CUR_OS_VER));
	} elsif ( "$CUR_VENDOR_VER" eq 'ES122' ) {
		return ( -e "$ROOT$BASE_DIR/version_delta"
				&& rpm_is_installed("ifs-kernel-updates-kmp-default", $CUR_OS_VER));
	} elsif ( "$CUR_VENDOR_VER" eq 'ES12' || "$CUR_VENDOR_VER" eq 'ES121' ) {
		return (rpm_is_installed("libibumad3", "user")
				&& -e "$ROOT$BASE_DIR/version_delta"
				&& rpm_is_installed("compat-rdma", $CUR_OS_VER));
	} else {
		return (rpm_is_installed("libibumad", "user")
				&& -e "$ROOT$BASE_DIR/version_delta"
				&& rpm_is_installed("compat-rdma", $CUR_OS_VER));
	}
}

sub installed_opa_stack()
{
	return (installed_delta_opa_stack);
}

# only called if installed_opa_stack is true
sub installed_version_opa_stack()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return 'NONE';
	}
}

# only called if available_opa_stack is true
sub media_version_opa_stack()
{
	return media_version_delta();
}

# return 0 on success, 1 on failure
sub run_uninstall($$$)
{
	my $stack = shift();
	my $cmd = shift();
	my $cmdargs = shift();

	if ( "$cmd" ne "" && -e "$cmd" ) {
		NormalPrint "\nUninstalling $stack: chroot /$ROOT $cmd $cmdargs\n";
		if (0 != system("yes | chroot /$ROOT $cmd $cmdargs")) {
			NormalPrint "Unable to uninstall $stack\n";
			return 1;
		}
	}
	return 0;
}

# return 0 on success, !=0 on failure
sub build_opa_stack($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild

	init_delta_rpm_info($osver);

	# We can't remove old ib stack because we need them for build
	# OFED_DELTA. More importantly, we don't know where are the rpms.

	# Before we do any builds make sure old stacks removed so we don't
	# build against the wrong version of dependent rpms
	#if (0 != uninstall_prev_versions()) {
	#	return 1;
	#}

	if (ROOT_is_set()) {
		# build in current image
		my $save_ROOT=$ROOT;
		$ROOT='/';
		my $rc =  build_delta("@Components", "@Components", $osver, $debug,$build_temp,$force);
		$ROOT=$save_ROOT;
		return $rc;
	} else {
		return build_delta("@Components", "@Components", $osver, $debug,$build_temp,$force);
	}
}

sub need_reinstall_opa_stack($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('opa_stack', $install_list, $installing_list));
}

sub check_os_prereqs_opa_stack
{
	return rpm_check_os_prereqs("opa_stack", "any");
}

sub preinstall_opa_stack($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("opa_stack", $install_list, $installing_list);
}

sub install_opa_stack($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'opa_stack'}{'SrcDir'};

	print_install_banner_delta_comp('opa_stack');

	#override the udev permissions.
	install_udev_permissions("$srcdir/config");

	# setup environment variable so that RPM can configure limits conf
        setup_env("OPA_LIMITS_CONF", 1);
        # so setting up envirnment to install driver for this component. actual install is done by rpm
	setup_env("OPA_INSTALL_CALLER", 1);

	# Check $BASE_DIR directory ...exist 
	check_config_dirs();
	check_dir("/usr/lib/opa");

        prompt_opa_conf_param('ARPTABLE_TUNING', 'Adjust kernel ARP table size for large fabrics?', "y", 'OPA_ARPTABLE_TUNING');
        prompt_opa_conf_param('SRP_LOAD', 'SRP initiator autoload?', "n", 'OPA_SRP_LOAD');
        prompt_opa_conf_param('SRPT_LOAD', 'SRP target autoload?', "n", 'OPA_SRPT_LOAD');

	install_delta_comp('opa_stack', $install_list);

	# prevent distro's open IB from loading
	#add_blacklist("ib_mthca");
	#add_blacklist("ib_ipath");
	disable_distro_ofed();

	# Take care of the configuration files for srptools
	check_rpm_config_file("/etc/srp_daemon.conf");
	check_rpm_config_file("/etc/logrotate.d/srp_daemon");
	check_rpm_config_file("/etc/rsyslog.d/srp_daemon.conf");

	# Start rdma on run level 235 on RHEL67
	run_rdma_on_startup();

	need_reboot();
	$ComponentWasInstalled{'opa_stack'}=1;
}

sub postinstall_opa_stack($$)
{
	my $old_conf = 0;	# do we have an existing conf file
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	if ( -e "$ROOT/$OPA_CONFIG" ) {
		if (0 == system("cp $ROOT/$OPA_CONFIG $ROOT/$OPA_CONFIG-save")) {
			$old_conf=1;
		}
	}

	# For RHEL 7.1 and SLES 12, enable force loading for some distros modules
	if ( "$CUR_VENDOR_VER" eq "ES71" || "$CUR_VENDOR_VER" eq "ES12") {
		enable_mod_force_load("mlx4_ib");
		enable_mod_force_load("ib_qib");
	}

	# adjust rdma.conf autostart settings
	foreach my $c ( @delta_components )
	{
		if ($install_list !~ / $c /) {
			# disable autostart of uninstalled components
			# opa_stack is at least installed
			delta_comp_change_opa_conf_param($c, "no");
		} else {
			# retain previous setting for components being installed
			# set to no if initial install
			# it seems that compat-rdma rpm will do this for us,
			# repeat just to be safe
			foreach my $p ( @{ $delta_comp_info{$c}{'StartupParams'} } ) {
				my $old_value = "";
				if ( $old_conf ) {
					$old_value = read_opa_conf_param($p, "$ROOT/$OPA_CONFIG-save");
				}
				if ( "$old_value" eq "" ) {
					$old_value = "no";
				}
				change_opa_conf_param($p, $old_value);
			}
		}
	}

	delta_restore_autostart('opa_stack');
}

# Do we need to do any of the stuff???
sub uninstall_opa_stack($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	my $driver_subdir=$ComponentInfo{'opa_stack'}{'DriverSubdir'};
	print_uninstall_banner_delta_comp('opa_stack');
	stop_opa_stack;
	remove_blacklist("ib_qib");

	# allow open IB to load
	#remove_blacklist("ib_mthca");
	#remove_blacklist("ib_ipath");

	uninstall_delta_comp('opa_stack', $install_list, $uninstalling_list, 'verbose');
	remove_driver_dirs($driver_subdir);
	#remove_modules_conf;
	remove_limits_conf;

	remove_udev_permissions;

	system("rm -rf $ROOT$BASE_DIR/version_delta");
	system("rm -rf $ROOT/usr/lib/opa/.comp_delta.pl");
	system "rmdir $ROOT/usr/lib/opa 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$BASE_DIR 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$OPA_CONFIG_DIR 2>/dev/null";	# remove only if empty

	need_reboot();
	$ComponentWasInstalled{'opa_stack'}=0;
}
# ==========================================================================
# intel_hfi installation

# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_intel_hfi()
{
    return (! is_blacklisted('hfi1'));
}
sub autostart_desc_intel_hfi()
{
    return autostart_desc_delta_comp('intel_hfi');
}
# enable autostart for the given capability
sub enable_autostart2_intel_hfi()
{
	if (! IsAutostart2_intel_hfi()) {
		remove_blacklist('hfi1');
		rebuild_ramdisk();
	}
}
# disable autostart for the given capability
sub disable_autostart2_intel_hfi()
{
	if (IsAutostart2_intel_hfi()) {
		add_blacklist('hfi1');
		rebuild_ramdisk();
	}
}

sub available_intel_hfi()
{
    my $srcdir=$ComponentInfo{'intel_hfi'}{'SrcDir'};
        return ( (-d "$srcdir/SRPMS" || -d "$srcdir/RPMS" )
		 && build_option_is_allowed($CUR_OS_VER, "", %delta_kernel_ib_options));
}

sub installed_intel_hfi()
{
    my $driver_subdir=$ComponentInfo{'intel_hfi'}{'DriverSubdir'};
    if ( "$CUR_VENDOR_VER" eq "ES67" ) {
	return ( -e "$ROOT$BASE_DIR/version_delta"
			&& rpm_is_installed("libhfi1", "user")
                        && rpm_is_installed("ifs-kernel-updates", $CUR_OS_VER));
    } elsif ( "$CUR_VENDOR_VER" eq "ES72" || "$CUR_VENDOR_VER" eq "ES73" ) {
        return (rpm_is_installed("libhfi1", "user")
                        && -e "$ROOT$BASE_DIR/version_delta"
                        && rpm_is_installed("kmod-ifs-kernel-updates", $CUR_OS_VER));
	} elsif ( "$CUR_VENDOR_VER" eq "ES122" ) {
		return (rpm_is_installed("libhfi1verbs-rdmav2", "user")
                        && -e "$ROOT$BASE_DIR/version_delta"
                        && rpm_is_installed("ifs-kernel-updates-kmp-default", $CUR_OS_VER));
	} else {
        return (rpm_is_installed("libhfi1", "user")
                        && -e "$ROOT$BASE_DIR/version_delta"
                        && rpm_is_installed("compat-rdma", $CUR_OS_VER));
	}
}

# only called if installed_intel_hfi is true
sub installed_version_intel_hfi()
{
    if ( -e "$ROOT$BASE_DIR/version_delta" ) {
	return `cat $ROOT$BASE_DIR/version_delta`;
    } else {
	return "";
    }
}

# only called if available_intel_hfi is true
sub media_version_intel_hfi()
{
    return media_version_delta();
}

sub build_intel_hfi($$$$)
{
    my $osver = shift();
    my $debug = shift();    # enable extra debug of build itself
    my $build_temp = shift();       # temp area for use by build
    my $force = shift();    # force a rebuild
    return 0;       # success
}

sub need_reinstall_intel_hfi($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    return (need_reinstall_delta_comp('intel_hfi', $install_list, $installing_list));
}

sub preinstall_intel_hfi($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    return preinstall_delta("intel_hfi", $install_list, $installing_list);
}

my $irq_perm_string = "Set IrqBalance to Exact?";
AddAnswerHelp("IrqBalance", "$irq_perm_string");
my $Default_IrqBalance = 1;

sub install_intel_hfi($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    print_install_banner_delta_comp('intel_hfi');

    # Adjust irqbalance
    if ( -e "/etc/sysconfig/irqbalance" ) {
		print "Intel strongly recommends that the irqbalance service be enabled\n";
		print "and run using the --hintpolicy=exact option.\n";
        $Default_IrqBalance = GetYesNoWithMemory("IrqBalance", 1, "$irq_perm_string", "y");
        if ( $Default_IrqBalance == 1 ) {
            #set env variable so that RPM can do post install configuration of IRQBALANCE
            #  if opasystemconfig already exists, set it manually
            if ( -f "/sbin/opasystemconfig" ) {
                system("/sbin/opasystemconfig --enable Irq_Balance");
            } else {
                setup_env("OPA_IRQBALANCE", 1);
            }
        }
    }
    install_delta_comp('intel_hfi', $install_list);

    need_reboot();
    $ComponentWasInstalled{'intel_hfi'}=1;
}

sub postinstall_intel_hfi($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled
    delta_restore_autostart('intel_hfi');

	rebuild_ramdisk();
}

sub uninstall_intel_hfi($$)
{
    my $install_list = shift();     # total that will be left installed when done
    my $uninstalling_list = shift();        # what items are being uninstalled

    print_uninstall_banner_delta_comp('intel_hfi');
        # TBD stop_intel_hfi;
    uninstall_delta_comp('intel_hfi', $install_list, $uninstalling_list, 'verbose');
    need_reboot();
    $ComponentWasInstalled{'intel_hfi'}=0;
    remove_blacklist('hfi1');
    rebuild_ramdisk();
}

sub check_os_prereqs_intel_hfi
{
        return rpm_check_os_prereqs("intel_hfi", "any");
}

# ==========================================================================
# ib_wfr_lite installation

# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_ib_wfr_lite()
{
    my $WhichStartup = $delta_comp_info{'ib_wfr_lite'}{'StartupScript'};
	my $ret = IsAutostart($WhichStartup);

	return ($ret && ! is_blacklisted('ib_wfr_lite'));
}
sub autostart_desc_ib_wfr_lite()
{
    return autostart_desc_delta_comp('ib_wfr_lite');
}
# enable autostart for the given capability
sub enable_autostart2_ib_wfr_lite()
{
	remove_blacklist('ib_wfr_lite');
	rebuild_ramdisk();
}
# disable autostart for the given capability
sub disable_autostart2_ib_wfr_lite()
{
	add_blacklist('ib_wfr_lite');
	rebuild_ramdisk();
}

sub available_ib_wfr_lite()
{
    my $srcdir=$ComponentInfo{'ib_wfr_lite'}{'SrcDir'};
        return ( (-d "$srcdir/SRPMS" || -d "$srcdir/RPMS" )
		 && build_option_is_allowed($CUR_OS_VER, "", %delta_kernel_ib_options));
}

sub installed_ib_wfr_lite()
{
    my $driver_subdir=$ComponentInfo{'ib_wfr_lite'}{'DriverSubdir'};
        return (rpm_is_installed("ib_wfr_lite", "user")
                        && -e "$ROOT$BASE_DIR/version_delta"
                        #&& rpm_is_installed("compat-rdma", $CUR_OS_VER)
	    );
}

# only called if installed_ib_wfr_lite is true
sub installed_version_ib_wfr_lite()
{
    if ( -e "$ROOT$BASE_DIR/version_delta" ) {
	return `cat $ROOT$BASE_DIR/version_delta`;
    } else {
	return "";
    }
}

# only called if available_ib_wfr_lite is true
sub media_version_ib_wfr_lite()
{
    return media_version_delta();
}

sub build_ib_wfr_lite($$$$)
{
    my $osver = shift();
    my $debug = shift();    # enable extra debug of build itself
    my $build_temp = shift();       # temp area for use by build
    my $force = shift();    # force a rebuild
    return 0;       # success
}

sub need_reinstall_ib_wfr_lite($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    return (need_reinstall_delta_comp('ib_wfr_lite', $install_list, $installing_list));
}

sub preinstall_ib_wfr_lite($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    return preinstall_delta("ib_wfr_lite", $install_list, $installing_list);
}

sub install_ib_wfr_lite($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled

    print_install_banner_delta_comp('ib_wfr_lite');
    install_delta_comp('ib_wfr_lite', $install_list);

    # because the ib_wfr_lite and qib drivers are attached to the same hardware IDs
    # only one can be active in the system at a given time so blacklist the one that
    # won't currently be in use.
    remove_blacklist("ib_wfr_lite");
    add_blacklist("ib_qib");

    need_reboot();
    $ComponentWasInstalled{'ib_wfr_lite'}=1;
}

sub postinstall_ib_wfr_lite($$)
{
    my $install_list = shift();     # total that will be installed when done
    my $installing_list = shift();  # what items are being installed/reinstalled
    delta_restore_autostart('ib_wfr_lite');
}

sub uninstall_ib_wfr_lite($$)
{
    my $install_list = shift();     # total that will be left installed when done
    my $uninstalling_list = shift();        # what items are being uninstalled

    print_uninstall_banner_delta_comp('ib_wfr_lite');
    uninstall_delta_comp('ib_wfr_lite', $install_list, $uninstalling_list, 'verbose');

    # because the ib_wfr_lite and qib drivers are attached to the same hardware IDs
    # only one can be active in the system at a given time so blacklist the one that
    # won't currently be in use.
    add_blacklist("ib_wfr_lite");
    remove_blacklist("ib_qib");

    need_reboot();
    $ComponentWasInstalled{'ib_wfr_lite'}=0;
}

# ==========================================================================
# OFED opa_stack development installation

sub available_opa_stack_dev()
{
	my $srcdir=$ComponentInfo{'opa_stack_dev'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_opa_stack_dev()
{
	return (rpm_is_installed("libibumad-devel", "user")
			&& -e "$ROOT$BASE_DIR/version_delta");
}

# only called if installed_opa_stack_dev is true
sub installed_version_opa_stack_dev()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return "";
	}
}

# only called if available_opa_stack_dev is true
sub media_version_opa_stack_dev()
{
	return media_version_delta();
}

sub build_opa_stack_dev($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_opa_stack_dev($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('opa_stack_dev', $install_list, $installing_list));
}

sub preinstall_opa_stack_dev($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("opa_stack_dev", $install_list, $installing_list);
}

sub install_opa_stack_dev($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('opa_stack_dev');
	install_delta_comp('opa_stack_dev', $install_list);

	$ComponentWasInstalled{'opa_stack_dev'}=1;
}

sub postinstall_opa_stack_dev($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('opa_stack_dev');
}

sub uninstall_opa_stack_dev($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('opa_stack_dev');
	uninstall_delta_comp('opa_stack_dev', $install_list, $uninstalling_list, 'verbose');
	$ComponentWasInstalled{'opa_stack_dev'}=0;
}

# ==========================================================================
# OFED delta_ipoib installation

my $FirstIPoIBInterface=0; # first device is ib0

# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_delta_ipoib()
{
	return IsAutostart_delta_comp2('delta_ipoib') || IsAutostart("ipoib");
}
sub autostart_desc_delta_ipoib()
{
	return autostart_desc_delta_comp('delta_ipoib');
}
# enable autostart for the given capability
sub enable_autostart2_delta_ipoib()
{
	enable_autostart_delta_comp2('delta_ipoib');
}
# disable autostart for the given capability
sub disable_autostart2_delta_ipoib()
{
	disable_autostart_delta_comp2('delta_ipoib');
	if (Exist_ifcfg("ib")) {
		print "$ComponentInfo{'delta_ipoib'}{'Name'} will autostart if ifcfg files exists\n";
		print "To fully disable autostart, it's recommended to also remove related ifcfg files\n";
		Remove_ifcfg("ib_ipoib","$ComponentInfo{'delta_ipoib'}{'Name'}","ib");
	}
}

sub available_delta_ipoib()
{
	my $srcdir=$ComponentInfo{'delta_ipoib'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_delta_ipoib()
{
	if ( "$CUR_VENDOR_VER" eq "ES67" ) {
		return (( -e "$ROOT$BASE_DIR/version_delta"
			&& rpm_is_installed("ifs-kernel-updates", $CUR_OS_VER)));
	}
	return 1;
}

# only called if installed_delta_ipoib is true
sub installed_version_delta_ipoib()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_delta_ipoib is true
sub media_version_delta_ipoib()
{
	return media_version_delta();
}

sub build_delta_ipoib($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_delta_ipoib($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('delta_ipoib', $install_list, $installing_list));
}

sub preinstall_delta_ipoib($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("delta_ipoib", $install_list, $installing_list);
}

sub install_delta_ipoib($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('delta_ipoib');
	install_delta_comp('delta_ipoib', $install_list);

	# bonding is more involved, require user to edit to enable that
	Config_ifcfg(1,"$ComponentInfo{'delta_ipoib'}{'Name'}","ib", "$FirstIPoIBInterface",1);
	check_network_config;
	#Config_IPoIB_cfg;
	need_reboot();
	$ComponentWasInstalled{'delta_ipoib'}=1;
}

sub postinstall_delta_ipoib($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	delta_restore_autostart('delta_ipoib');
}

sub uninstall_delta_ipoib($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('delta_ipoib');
	# TBD stop_delta_ipoib;
	uninstall_delta_comp('delta_ipoib', $install_list, $uninstalling_list, 'verbose');
	Remove_ifcfg("ib_ipoib","$ComponentInfo{'delta_ipoib'}{'Name'}","ib");
	need_reboot();
	$ComponentWasInstalled{'delta_ipoib'}=0;
}

# ==========================================================================
# OFED DELTA mpi-selector installation

sub available_mpi_selector()
{
	my $srcdir=$ComponentInfo{'mpi_selector'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_mpi_selector()
{
	return (rpm_is_installed("mpi-selector", "user")
			&& -e "$ROOT$BASE_DIR/version_delta");
}

# only called if installed_mpi_selector is true
sub installed_version_mpi_selector()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return "";
	}
}

# only called if available_mpi_selector is true
sub media_version_mpi_selector()
{
	return media_version_delta();
}

sub build_mpi_selector($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_mpi_selector($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('mpi_selector', $install_list, $installing_list));
}

sub check_os_prereqs_mpi_selector
{
	return rpm_check_os_prereqs("mpi_selector", "any");
}

sub preinstall_mpi_selector($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("mpi_selector", $install_list, $installing_list);
}

sub install_mpi_selector($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('mpi_selector');
	install_delta_comp('mpi_selector', $install_list);

	$ComponentWasInstalled{'mpi_selector'}=1;
}

sub postinstall_mpi_selector($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('mpi_selector');
}

sub uninstall_mpi_selector($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	uninstall_delta_comp('mpiRest', $install_list, $uninstalling_list, 'verbose');
	print_uninstall_banner_delta_comp('mpi_selector');
	uninstall_delta_comp('mpi_selector', $install_list, $uninstalling_list, 'verbose');
	delta_cleanup_mpitests();
	$ComponentWasInstalled{'mpi_selector'}=0;
}

# ==========================================================================
# OFED MVAPICH2 for gcc installation

sub available_mvapich2()
{
	my $srcdir=$ComponentInfo{'mvapich2'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_mvapich2()
{
	return ((rpm_is_installed("mvapich2_gcc", "user")
			&& -e "$ROOT$BASE_DIR/version_delta"));
}

# only called if installed_mvapich2 is true
sub installed_version_mvapich2()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_mvapich2 is true
sub media_version_mvapich2()
{
	return media_version_delta();
}

sub build_mvapich2($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_mvapich2($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('mvapich2', $install_list, $installing_list));
}

sub check_os_prereqs_mvapich2
{
	return rpm_check_os_prereqs("mvapich2", "user");
}

sub preinstall_mvapich2($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("mvapich2", $install_list, $installing_list);
}

sub install_mvapich2($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('mvapich2');

	# make sure any old potentially custom built versions of mpi are uninstalled
	rpm_uninstall_list2("any", " --nodeps ", 'silent', @{ $delta_comp_info{'mvapich2'}{'UserRpms'}});
	my $rpmfile = rpm_resolve(delta_rpms_dir(), "any", "mvapich2_gcc");
	if ( "$rpmfile" ne "" && -e "$rpmfile" ) {
		my $mpich_prefix= "$OFED_prefix/mpi/gcc/mvapich2-"
	   							. rpm_query_attr($rpmfile, "VERSION");
		if ( -d "$mpich_prefix" && GetYesNo ("Remove $mpich_prefix directory?", "y")) {
			LogPrint "rm -rf $mpich_prefix\n";
			system("rm -rf $mpich_prefix");
		}
	}

	install_delta_comp('mvapich2', $install_list);

	$ComponentWasInstalled{'mvapich2'}=1;
}

sub postinstall_mvapich2($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('mvapich2');
}

sub uninstall_mvapich2($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('mvapich2');
	uninstall_delta_comp('mvapich2', $install_list, $uninstalling_list, 'verbose');
	delta_cleanup_mpitests();
	$ComponentWasInstalled{'mvapich2'}=0;
}

# ==========================================================================
# OFED OpenMpi for gcc installation

sub available_openmpi()
{
	my $srcdir=$ComponentInfo{'openmpi'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_openmpi()
{
	return ((rpm_is_installed("openmpi_gcc_hfi", "user")
			&& -e "$ROOT$BASE_DIR/version_delta"));
}

# only called if installed_openmpi is true
sub installed_version_openmpi()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_openmpi is true
sub media_version_openmpi()
{
	return media_version_delta();
}

sub build_openmpi($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_openmpi($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('openmpi', $install_list, $installing_list));
}

sub check_os_prereqs_openmpi
{
	return rpm_check_os_prereqs("openmpi", "user");
}

sub preinstall_openmpi($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("openmpi", $install_list, $installing_list);
}

sub install_openmpi($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('openmpi');

	# make sure any old potentially custom built versions of mpi are uninstalled
	rpm_uninstall_list2("any", " --nodeps ", 'silent', @{ $delta_comp_info{'openmpi'}{'UserRpms'}});
	my $rpmfile = rpm_resolve(delta_rpms_dir(), "any", "openmpi_gcc");
	if ( "$rpmfile" ne "" && -e "$rpmfile" ) {
		my $mpich_prefix= "$OFED_prefix/mpi/gcc/openmpi-"
	   							. rpm_query_attr($rpmfile, "VERSION");
		if ( -d "$mpich_prefix" && GetYesNo ("Remove $mpich_prefix directory?", "y")) {
			LogPrint "rm -rf $mpich_prefix\n";
			system("rm -rf $mpich_prefix");
		}
	}

	install_delta_comp('openmpi', $install_list);

	$ComponentWasInstalled{'openmpi'}=1;
}

sub postinstall_openmpi($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('openmpi');
}

sub uninstall_openmpi($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('openmpi');
	uninstall_delta_comp('openmpi', $install_list, $uninstalling_list, 'verbose');
	delta_cleanup_mpitests();
	$ComponentWasInstalled{'openmpi'}=0;
}

# ==========================================================================
# OFED gasnet for gcc installation

sub available_gasnet()
{
	my $srcdir=$ComponentInfo{'gasnet'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_gasnet()
{
	return ((rpm_is_installed("gasnet_gcc_hfi", "user")
			&& -e "$ROOT$BASE_DIR/version_delta"));
}

# only called if installed_gasnet is true
sub installed_version_gasnet()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_gasnet is true
sub media_version_gasnet()
{
	return media_version_delta();
}

sub build_gasnet($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_gasnet($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('gasnet', $install_list, $installing_list));
}

sub preinstall_gasnet($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("gasnet", $install_list, $installing_list);
}

sub install_gasnet($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('gasnet');

	# make sure any old potentially custom built versions of mpi are uninstalled
	rpm_uninstall_list2("any", " --nodeps ", 'silent', @{ $delta_comp_info{'gasnet'}{'UserRpms'}});
	my $rpmfile = rpm_resolve(delta_rpms_dir(), "any", "gasnet");
	if ( "$rpmfile" ne "" && -e "$rpmfile" ) {
		my $mpich_prefix= "$OFED_prefix/shmem/gcc/gasnet-"
	   							. rpm_query_attr($rpmfile, "VERSION");
		if ( -d "$mpich_prefix" && GetYesNo ("Remove $mpich_prefix directory?", "y")) {
			LogPrint "rm -rf $mpich_prefix\n";
			system("rm -rf $mpich_prefix");
		}
	}

	install_delta_comp('gasnet', $install_list);

	$ComponentWasInstalled{'gasnet'}=1;
}

sub postinstall_gasnet($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('gasnet');
}

sub uninstall_gasnet($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('gasnet');
	uninstall_delta_comp('gasnet', $install_list, $uninstalling_list, 'verbose');
#	delta_cleanup_mpitests();
	$ComponentWasInstalled{'gasnet'}=0;
}

sub check_os_prereqs_gasnet()
{
	return rpm_check_os_prereqs("gasnet", "user");
}

# ==========================================================================
# OFED openshmem for gcc installation

sub available_openshmem()
{
	my $srcdir=$ComponentInfo{'openshmem'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_openshmem()
{
	return ((rpm_is_installed("openshmem_gcc_hfi", "user")
			&& -e "$ROOT$BASE_DIR/version_delta"));
}

# only called if installed_openshmem is true
sub installed_version_openshmem()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_openshmem is true
sub media_version_openshmem()
{
	return media_version_delta();
}

sub build_openshmem($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_openshmem($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('openshmem', $install_list, $installing_list));
}

sub preinstall_openshmem($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("openshmem", $install_list, $installing_list);
}

sub install_openshmem($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('openshmem');

	# make sure any old potentially custom built versions of mpi are uninstalled
	rpm_uninstall_list2("any", " --nodeps ", 'silent', @{ $delta_comp_info{'openshmem'}{'UserRpms'}});
	my $rpmfile = rpm_resolve(delta_rpms_dir(), "any", "openshmem");
	if ( "$rpmfile" ne "" && -e "$rpmfile" ) {
		my $mpich_prefix= "$OFED_prefix/shmem/gcc/openshmem-"
	   							. rpm_query_attr($rpmfile, "VERSION");
		if ( -d "$mpich_prefix" && GetYesNo ("Remove $mpich_prefix directory?", "y")) {
			LogPrint "rm -rf $mpich_prefix\n";
			system("rm -rf $mpich_prefix");
		}
	}

	install_delta_comp('openshmem', $install_list);

	$ComponentWasInstalled{'openshmem'}=1;
}

sub postinstall_openshmem($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('openshmem');
}

sub uninstall_openshmem($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('openshmem');
	uninstall_delta_comp('openshmem', $install_list, $uninstalling_list, 'verbose');
#	delta_cleanup_mpitests();
	$ComponentWasInstalled{'openshmem'}=0;
}

sub check_os_prereqs_openshmem
{
	return rpm_check_os_prereqs("openshmem", "user");
}

# ==========================================================================
# OFED DELTA delta_mpisrc installation

sub available_delta_mpisrc()
{
	my $srcdir=$ComponentInfo{'delta_mpisrc'}{'SrcDir'};
# TBD better checks for available?
# check file_glob("$srcdir/SRPMS/mvapich-*.src.rpm") ne ""
# check file_glob("$srcdir/SRPMS/mvapich2-*.src.rpm") ne ""
# check file_glob("$srcdir/SRPMS/openmpi-*.src.rpm") ne ""
	return ( (-d "$srcdir/SRPMS" || -d "$srcdir/RPMS" ) );
}

sub installed_delta_mpisrc()
{
	return ((-e "$ROOT$BASE_DIR/version_delta"
			&& file_glob("$ROOT/usr/src/opa/MPI/mvapich*.src.rpm") ne ""
			&& file_glob("$ROOT/usr/src/opa/MPI/openmpi*.src.rpm") ne ""
			&& file_glob("$ROOT/usr/src/opa/MPI/mpitests*.src.rpm") ne ""));
}

# only called if installed_delta_mpisrc is true
sub installed_version_delta_mpisrc()
{
	return `cat $ROOT$BASE_DIR/version_delta`;
}

# only called if available_delta_mpisrc is true
sub media_version_delta_mpisrc()
{
	return media_version_delta();
}

sub build_delta_mpisrc($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_delta_mpisrc($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('delta_mpisrc', $install_list, $installing_list));
}

sub check_os_prereqs_delta_mpisrc
{
	return rpm_check_os_prereqs("delta_mpisrc", "any");
}

sub preinstall_delta_mpisrc($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("delta_mpisrc", $install_list, $installing_list);
}

sub install_delta_mpisrc($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'delta_mpisrc'}{'SrcDir'};

	print_install_banner_delta_comp('delta_mpisrc');
	install_delta_comp('delta_mpisrc', $install_list);
	check_dir("/usr/src/opa");
	check_dir("/usr/src/opa/MPI");
	# remove old versions (.src.rpm and built .rpm files too)
	system "rm -rf $ROOT/usr/src/opa/MPI/mvapich[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/mvapich2[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/openmpi[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/mpitests[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.res 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.err 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.warn 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/.mpiinfo 2>/dev/null";

	# install new versions
	foreach my $srpm ( "mvapich2", "openmpi", "mpitests" ) {
		my $srpmfile = file_glob("$srcdir/$SRPMS_SUBDIR/${srpm}-*.src.rpm");
		if ( "$srpmfile" ne "" ) {
			my $file = my_basename($srpmfile);
			copy_data_file($srpmfile, "/usr/src/opa/MPI/$file");
		}
	}
	copy_systool_file("$srcdir/do_build", "/usr/src/opa/MPI/do_build");
	copy_systool_file("$srcdir/do_mvapich2_build", "/usr/src/opa/MPI/do_mvapich2_build");
	copy_systool_file("$srcdir/do_openmpi_build", "/usr/src/opa/MPI/do_openmpi_build");

	$ComponentWasInstalled{'delta_mpisrc'}=1;
}

sub postinstall_delta_mpisrc($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('delta_mpisrc');
}

sub uninstall_delta_mpisrc($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('delta_mpisrc');

	# remove old versions (.src.rpm and built .rpm files too)
	system "rm -rf $ROOT/usr/src/opa/MPI/mvapich2[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/openmpi[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/mpitests[-_]*.rpm 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.res 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.err 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/make.*.warn 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/.mpiinfo 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/do_build 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/do_mvapich2_build 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/do_openmpi_build 2>/dev/null";
	system "rm -rf $ROOT/usr/src/opa/MPI/.mpiinfo 2>/dev/null";

	uninstall_delta_comp('delta_mpisrc', $install_list, $uninstalling_list, 'verbose');
	system "rmdir $ROOT/usr/src/opa/MPI 2>/dev/null"; # remove only if empty
	system "rmdir $ROOT/usr/src/opa 2>/dev/null"; # remove only if empty
	$ComponentWasInstalled{'delta_mpisrc'}=0;
}

# ==========================================================================
# OFED delta_debug installation

# this is an odd component.  It consists of the debuginfo files which
# are built and identified in DebugRpms in other components.  Installing this
# component installs the debuginfo files for the installed components.
# uninstalling this component gets rid of all debuginfo files.
# uninstalling other components will get rid of individual debuginfo files
# for those components

sub available_delta_debug()
{
	my $srcdir=$ComponentInfo{'delta_debug'}{'SrcDir'};
	return (( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS")
			&&	$delta_rpm_info{'libibumad-debuginfo'}{'Available'});
}

sub installed_delta_debug()
{
	return (rpm_is_installed("libibumad-debuginfo", "user")
			&& -e "$ROOT$BASE_DIR/version_delta");
}

# only called if installed_delta_debug is true
sub installed_version_delta_debug()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return "";
	}
}

# only called if available_delta_debug is true
sub media_version_delta_debug()
{
	return media_version_delta();
}

sub build_delta_debug($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_delta_debug($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	my $reins = need_reinstall_delta_comp('delta_debug', $install_list, $installing_list);
	if ("$reins" eq "no" ) {
		# if delta components with DebugRpms have been added we need to reinstall
		# this component.  Note uninstall for individual components will
		# get rid of associated debuginfo files
		foreach my $comp ( @delta_components ) {
			if ( " $installing_list " =~ / $comp /
				 && 0 != scalar(@{ $delta_comp_info{$comp}{'DebugRpms'}})) {
				return "this";
			}
		}
		
	}
	return $reins;
}

sub preinstall_delta_debug($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("delta_debug", $install_list, $installing_list);
}

sub install_delta_debug($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	my @list;

	print_install_banner_delta_comp('delta_debug');
	install_delta_comp('delta_debug', $install_list);

	# install DebugRpms for each installed component
	foreach my $comp ( @delta_components ) {
		if ( " $install_list " =~ / $comp / ) {
			delta_rpm_install_list(delta_rpms_dir(), $CUR_OS_VER, 1,
							( @{ $delta_comp_info{$comp}{'DebugRpms'}}));
		}
	}

	$ComponentWasInstalled{'delta_debug'}=1;
}

sub postinstall_delta_debug($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	#delta_restore_autostart('delta_debug');
}

sub uninstall_delta_debug($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('delta_debug');

	uninstall_delta_comp('delta_debug', $install_list, $uninstalling_list, 'verbose');
	# uninstall debug rpms for all components
	# debuginfo never in >1 component, so do explicit uninstall since
	# have an odd PartOf relationship which confuses uninstall_not_needed_list
	foreach my $comp ( reverse(@delta_components) ) {
		rpm_uninstall_list2("any", " --nodeps ", 'verbose',
					 @{ $delta_comp_info{$comp}{'DebugRpms'}});
	}
	$ComponentWasInstalled{'delta_debug'}=0;
}

# ==========================================================================
# OFED DELTA ibacm installation

# determine if the given capability is configured for Autostart at boot
sub IsAutostart2_ibacm()
{
	return IsAutostart_delta_comp2('ibacm');
}
sub autostart_desc_ibacm()
{
	return autostart_desc_delta_comp('ibacm');
}
# enable autostart for the given capability
sub enable_autostart2_ibacm()
{
	enable_autostart($delta_comp_info{'ibacm'}{'StartupScript'});
}
# disable autostart for the given capability
sub disable_autostart2_ibacm()
{
	disable_autostart($delta_comp_info{'ibacm'}{'StartupScript'});
}

sub start_ibacm()
{
	my $prefix = delta_get_prefix();
	start_utility($ComponentInfo{'ibacm'}{'Name'}, "$prefix/sbin", "ibacm", "ibacm");
}

sub stop_ibacm()
{
	stop_utility($ComponentInfo{'ibacm'}{'Name'}, "ibacm", "ibacm");
}

sub available_ibacm()
{
	my $srcdir=$ComponentInfo{'ibacm'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_ibacm()
{
	return (rpm_is_installed("ibacm", "user")
			&& -e "$ROOT$BASE_DIR/version_delta");
}

# only called if installed_ibacm is true
sub installed_version_ibacm()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return "";
	}
}

# only called if available_ibacm is true
sub media_version_ibacm()
{
	return media_version_delta();
}

sub build_ibacm($$$$)
{
	my $osver = shift();
	my $debug = shift();	# enable extra debug of build itself
	my $build_temp = shift();	# temp area for use by build
	my $force = shift();	# force a rebuild
	return 0;	# success
}

sub need_reinstall_ibacm($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return (need_reinstall_delta_comp('ibacm', $install_list, $installing_list));
}

sub preinstall_ibacm($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return preinstall_delta("ibacm", $install_list, $installing_list);
}

sub install_ibacm($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	print_install_banner_delta_comp('ibacm');
	install_delta_comp('ibacm', $install_list);

	$ComponentWasInstalled{'ibacm'}=1;
}

sub postinstall_ibacm($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled
	delta_restore_autostart('ibacm');
}

sub uninstall_ibacm($$)
{
	my $install_list = shift();	# total that will be left installed when done
	my $uninstalling_list = shift();	# what items are being uninstalled

	print_uninstall_banner_delta_comp('ibacm');
	stop_ibacm;

	uninstall_delta_comp('ibacm', $install_list, $uninstalling_list, 'verbose');
	$ComponentWasInstalled{'ibacm'}=0;
}

sub check_os_prereqs_ibacm
{
	return rpm_check_os_prereqs("ibacm", "user");
}

# ------------------------------------------------------------------
# # subroutines for rdma-ndd component
# # -----------------------------------------------------------------
sub installed_rdma_ndd()
{
        return (rpm_is_installed("infiniband-diags", "user"));
}

sub enable_autostart2_rdma_ndd()
{
        system "systemctl enable rdma-ndd >/dev/null 2>&1";
}

sub disable_autostart2_rdma_ndd()
{
        system "systemctl disable rdma-ndd >/dev/null 2>&1";
}

sub IsAutostart2_rdma_ndd()
{
        my $status = `systemctl is-enabled rdma-ndd`;
        if ( $status eq "enabled\n" ){
                return 1;
        }
        else{
                return 0;
        }
}

# ------------------------------------------------------------------
# subroutines for hfi1_uefi component
# ------------------------------------------------------------------
sub available_hfi1_uefi()
{
	my $srcdir=$ComponentInfo{'hfi1_uefi'}{'SrcDir'};
	return ( -d "$srcdir/SRPMS" || -d "$srcdir/RPMS" );
}

sub installed_hfi1_uefi()
{
	return (rpm_is_installed("hfi1-uefi", "user")
		&& -e "$ROOT$BASE_DIR/version_delta");
}

# only called if installed_xxxx is true
sub installed_version_hfi1_uefi()
{
	if ( -e "$ROOT$BASE_DIR/version_delta" ) {
		return `cat $ROOT$BASE_DIR/version_delta`;
	} else {
		return "";
	}
}
# only called if available_xxxxxis true
sub media_version_hfi1_uefi()
{
	return media_version_delta();
}

sub need_reinstall_hfi1_uefi($$)
{
	my $install_list = shift();     # total that will be installed when done
	my $installing_list = shift();  # what items are being installed/reinstalled

	return (need_reinstall_delta_comp('hfi1_uefi', $install_list, $installing_list));
}

sub preinstall_hfi1_uefi($$)
{
	my $install_list = shift();     # total that will be installed when done
	my $installing_list = shift();  # what items are being installed/reinstalled

	return preinstall_delta("hfi1_uefi", $install_list, $installing_list);
}

sub install_hfi1_uefi($$)
{
	my $install_list = shift();     # total that will be installed when done
	my $installing_list = shift();  # what items are being installed/reinstalled

	print_install_banner_delta_comp('hfi1_uefi');
	install_delta_comp('hfi1_uefi', $install_list);

	$ComponentWasInstalled{'hfi1_uefi'}=1;
}

sub postinstall_hfi1_uefi($$)
{

}
sub uninstall_hfi1_uefi($$)
{
	my $install_list = shift();     # total that will be left installed when done
	my $uninstalling_list = shift();        # what items are being uninstalled

	print_uninstall_banner_delta_comp('hfi1_uefi');
	uninstall_delta_comp('hfi1_uefi', $install_list, $uninstalling_list, 'verbose');
	$ComponentWasInstalled{'hfi1_uefi'}=0;
}

#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
# 
# Copyright (c) 2015, Intel Corporation
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: @(#) ./opaconfig 10_5_1_0_2 [09/13/17 20:18]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# ===========================================================================
# Main menus, option handling and version handling for FF for OFED install
#

$MainInstall="omnipathwrap";

@supported_kernels = ( $CUR_OS_VER );	# TBD how do we verify OS
my $Build_OsVer=$CUR_OS_VER;
my $Build_Debug=0;	# should we provide more info for debug
my $Build_Temp="";	# temp area to use for build
my $Default_Build = 0;	# -B option used to select build
my $Build_Force = 0;# rebuild option used to force full rebuild

$FirstIPoIBInterface=0; # first device is ib0

	# Names of supported install components
	# must be listed in depdency order such that prereqs appear 1st

my @OmniPathAllComponents = ( "mvapich2_gcc_hfi",
		   			"mvapich2_intel_hfi",
					"openmpi_gcc_hfi",
				   	"openmpi_intel_hfi",
 					);

# these are now gone, list them so they get uninstalled
my @Components_other = ( "opa_stack", "ibacm", "mpi_selector", "intel_hfi",
		"oftools", "opa_stack_dev", "fastfabric", "rdma_ndd",
		"delta_ipoib", "opafm", "opamgt_sdk",
	   	@OmniPathAllComponents, 
		"gasnet", "openshmem",
	   	"mvapich2", "openmpi",
	   	"delta_mpisrc", "hfi1_uefi", "delta_debug", );
my @Components_rhel72 = ( "opa_stack", "ibacm", "mpi_selector", "intel_hfi",
		"oftools", "opa_stack_dev", "fastfabric", "rdma_ndd",
		"delta_ipoib", "opafm", "opamgt_sdk",
	   	@OmniPathAllComponents,
		"openmpi_gcc_cuda_hfi", "gasnet", "openshmem",
	   	"mvapich2", "openmpi",
	   	"delta_mpisrc", "hfi1_uefi", "delta_debug", );
my @Components_sles12_sp2 = ( "opa_stack", "ibacm", "mpi_selector", "intel_hfi",
		"oftools", "opa_stack_dev", "fastfabric", "rdma_ndd",
		"delta_ipoib", "opafm", "opamgt_sdk",
	   	@OmniPathAllComponents,
		"openmpi_gcc_cuda_hfi", "gasnet", "openshmem",
	   	"mvapich2", "openmpi",
	   	"delta_mpisrc", "hfi1_uefi", "delta_debug", );
my @Components_rhel73 = ( "opa_stack", "ibacm", "mpi_selector", "intel_hfi",
		"oftools", "opa_stack_dev", "fastfabric", "rdma_ndd",
		"delta_ipoib", "opafm", "opamgt_sdk",
	   	@OmniPathAllComponents,
		"openmpi_gcc_cuda_hfi",	"gasnet", "openshmem",
	   	"mvapich2", "openmpi",
	   	"delta_mpisrc", "hfi1_uefi", "delta_debug", );
@Components = ( );

# delta_debug must be last

@SubComponents = ( );

	# an additional "special" component which is always installed when
	# we install/upgrade anything and which is only uninstalled when everything
	# else has been uninstalled.  Typically this will be the opaconfig
	# file and related files absolutely required by it (such as wrapper_version)
$WrapperComponent = "opaconfig";

# This provides more detailed information about each Component in @Components
# since hashes are not retained in the order specified, we still need
# @Components and @SubComponents to control install and menu order
# Fields are as follows:
#	Name => full name of component/subcomponent for prompts
# 	DefaultInstall => default installation (State_DoNotInstall or State_Install)
#					  used only when available and ! installed
#	SrcDir => directory name within install media for component
#	DriverSubdir => directory within /lib/modules/$CUR_OS_VERSION/ to
#					install driver to.  Set to "" if no drivers in component
#					set to "." if no subdir
# 	PreReq => other components which are prereqs of a given
#				component/subcomponent
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	CoReq =>  other components which are coreqs of a given component
#				Note that CoReqs can also be listed as prereqs to provide
#				install verification as each component is installed,
#				however prereqs should only refer to items earlier in the list
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	Hidden => component should not be shown in menus/prompts
#			  used for hidden PreReq.  Hidden components can't HasStart
#			  nor HasFirmware
#	Disabled =>  components/subcomponents which are disabled from installation
#	HasStart =>  components/subcomponents which have autostart capability
#	DefaultStart =>  should autostart default to Enable (1) or Disable (0)
#				Not needed/ignored unless HasStart=1
# 	StartPreReq => other components/subcomponents which must be autostarted
#				before autostarting this component/subcomponent
#				Not needed/ignored unless HasStart=1
#				Need space before and after each component name to
#				facilitate compares so that compares do not mistake names
#				such as mpidev for mpi
#	StartComponents => components/subcomponents with start for this component
#				if a component has a start script 
#				list the component as a subcomponent of itself
#	HasFirmware =>  components which need HCA firmware update after installed
#
# Note both Components and SubComponents are included in the list below.
# Components require all fields be supplied
# SubComponents only require the following fields:
#	Name, PreReq (should reference only components), HasStart, StartPreReq,
#	DefaultStart
my %ComponentInfo_other = (
		# our special WrapperComponent, limited use
	"opaconfig" =>	{ Name => "opaconfig",
					  DefaultInstall => $State_Install,
					  SrcDir => ".", DriverSubdir => "",
					  PreReq => "", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
		# "ofed" is only used for source_comp
	"ofed_delta" =>	{ Name => "OFA_DELTA",
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					},
	"opa_stack" =>	{ Name => "OFA OPA Stack",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => "", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => "",
					  StartComponents => [ "opa_stack" ],
					},
	"ibacm" =>		{ Name => "OFA IBACM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"), 
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "ibacm" ],
					},
	"intel_hfi" =>	{ Name => "Intel HFI Components",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "intel_hfi" ],
					},
	"oftools" =>	{ Name => "OPA Tools",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ibacm ", CoReq => " opa_stack ",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ", # TBD
					  StartComponents => [ ],
					},
	"mpi_selector" =>	{ Name => "MPI selector",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 1, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opa_stack_dev" => { Name => "OFA OPA Development",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"fastfabric" =>	{ Name => "FastFabric",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack oftools ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
					},
	"delta_ipoib" =>	{ Name => "OFA IP over IB",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "delta_ipoib" ],
					},
	"mvapich2" =>	{ Name => "MVAPICH2 (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi" =>	{ Name => "OpenMPI (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"gasnet" =>	{ Name => "GASNet (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openshmem" =>	{ Name => "OpenSHMEM (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack gasnet intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"mvapich2_gcc_hfi" =>	{ Name => "MVAPICH2 (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"mvapich2_intel_hfi" =>	{ Name => "MVAPICH2 (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_hfi" =>	{ Name => "OpenMPI (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_intel_hfi" =>	{ Name => "OpenMPI (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"delta_mpisrc" =>{ Name => "MPI Source",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack opa_stack_dev mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opafm" =>	{ Name => "OPA FM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-FM.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  #StartComponents => [ "qlgc_fm", "qlgc_fm_snmp"],
					  StartComponents => [ "opafm" ],
					},
	"opamgt_sdk" => { Name => "OPA Management SDK",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  Prereq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
				  },
	"delta_debug" =>	{ Name => "OFA Debug Info",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"hfi1_uefi" =>		{ Name => "Pre-Boot Components",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"rdma_ndd" =>              { Name => "RDMA NDD",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "rdma_ndd" ],
                                        },
	);
my %ComponentInfo_rhel72 = (
		# our special WrapperComponent, limited use
	"opaconfig" =>	{ Name => "opaconfig",
					  DefaultInstall => $State_Install,
					  SrcDir => ".", DriverSubdir => "",
					  PreReq => "", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
		# "ofed" is only used for source_comp
	"ofed_delta" =>	{ Name => "OFA_DELTA",
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					},
	"opa_stack" =>	{ Name => "OFA OPA Stack",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "extra/ifs-kernel-updates",
					  PreReq => "", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => "",
					  StartComponents => [ "opa_stack" ],
					},
	"ibacm" =>		{ Name => "OFA IBACM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"), 
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "ibacm" ],
					},
	"intel_hfi" =>	{ Name => "Intel HFI Components",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "intel_hfi" ],
					},
	"oftools" =>	{ Name => "OPA Tools",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ibacm ", CoReq => " opa_stack ",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ", # TBD
					  StartComponents => [ ],
					},
	"mpi_selector" =>	{ Name => "MPI selector",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 1, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opa_stack_dev" => { Name => "OFA OPA Development",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"fastfabric" =>	{ Name => "FastFabric",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack oftools ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
					},
	"delta_ipoib" =>	{ Name => "OFA IP over IB",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "delta_ipoib" ],
					},
	"mvapich2" =>	{ Name => "MVAPICH2 (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi" =>	{ Name => "OpenMPI (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"gasnet" =>	{ Name => "GASNet (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openshmem" =>	{ Name => "OpenSHMEM (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack gasnet intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
 	"openmpi_gcc_cuda_hfi" =>{ Name => "OpenMPI (cuda,gcc)",
                                         DefaultInstall => $State_Install,
                                         SrcDir => file_glob ("./OFED_MPIS.*"),
                                         DriverSubdir => "",
                                         PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
                                         Hidden => 0, Disabled => 0,
                                         HasStart => 0, HasFirmware => 0, DefaultStart => 0,
                                         StartPreReq => "",
                                         StartComponents => [ ],
					},
	"mvapich2_gcc_hfi" =>	{ Name => "MVAPICH2 (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"mvapich2_intel_hfi" =>	{ Name => "MVAPICH2 (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_hfi" =>	{ Name => "OpenMPI (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_intel_hfi" =>	{ Name => "OpenMPI (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"delta_mpisrc" =>{ Name => "MPI Source",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack opa_stack_dev mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opafm" =>	{ Name => "OPA FM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-FM.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  #StartComponents => [ "qlgc_fm", "qlgc_fm_snmp"],
					  StartComponents => [ "opafm" ],
					},
	"opamgt_sdk" => { Name => "OPA Management SDK",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  Prereq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
				  },
	"delta_debug" =>	{ Name => "OFA Debug Info",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"hfi1_uefi" =>		{ Name => "Pre-Boot Components",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"rdma_ndd" =>              { Name => "RDMA NDD",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "rdma_ndd" ],
                                        },
	);

my %ComponentInfo_sles12_sp2 = (
		# our special WrapperComponent, limited use
	"opaconfig" =>	{ Name => "opaconfig",
					  DefaultInstall => $State_Install,
					  SrcDir => ".", DriverSubdir => "",
					  PreReq => "", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
		# "ofed" is only used for source_comp
	"ofed_delta" =>	{ Name => "OFA_DELTA",
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					},
	"opa_stack" =>	{ Name => "OFA OPA Stack",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates/ifs-kernel-updates",
					  PreReq => "", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => "",
					  StartComponents => [ "opa_stack" ],
					},
	"ibacm" =>              { Name => "OFA IBACM",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "ibacm" ],
                                        },
	"intel_hfi" =>	{ Name => "Intel HFI Components",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "intel_hfi" ],
					},
	"oftools" =>	{ Name => "OPA Tools",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => " opa_stack ",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ", # TBD
					  StartComponents => [ ],
					},
	"mpi_selector" =>	{ Name => "MPI selector",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 1, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opa_stack_dev" => { Name => "OFA OPA Development",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"fastfabric" =>	{ Name => "FastFabric",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack oftools ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
					},
	"delta_ipoib" =>	{ Name => "OFA IP over IB",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "delta_ipoib" ],
					},
	"mvapich2" =>	{ Name => "MVAPICH2 (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi" =>	{ Name => "OpenMPI (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"gasnet" =>	{ Name => "GASNet (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openshmem" =>	{ Name => "OpenSHMEM (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack gasnet intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_cuda_hfi" =>{ Name => "OpenMPI (cuda,gcc)",
                                         DefaultInstall => $State_Install,
                                         SrcDir => file_glob ("./OFED_MPIS.*"),
                                         DriverSubdir => "",
                                         PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
                                         Hidden => 0, Disabled => 0,
                                         HasStart => 0, HasFirmware => 0, DefaultStart => 0,
                                         StartPreReq => "",
                                         StartComponents => [ ],
					},
	"mvapich2_gcc_hfi" =>	{ Name => "MVAPICH2 (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"mvapich2_intel_hfi" =>	{ Name => "MVAPICH2 (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_hfi" =>	{ Name => "OpenMPI (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_intel_hfi" =>	{ Name => "OpenMPI (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"delta_mpisrc" =>{ Name => "MPI Source",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack opa_stack_dev mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opafm" =>	{ Name => "OPA FM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-FM.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  #StartComponents => [ "qlgc_fm", "qlgc_fm_snmp"],
					  StartComponents => [ "opafm" ],
					},
	"opamgt_sdk" => { Name => "OPA Management SDK",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  Prereq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
				  },
	"delta_debug" =>	{ Name => "OFA Debug Info",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"hfi1_uefi" =>		{ Name => "Pre-Boot Components",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"rdma_ndd" =>              { Name => "RDMA NDD",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "rdma_ndd" ],
                                        },
	);
my %ComponentInfo_rhel73 = (
		# our special WrapperComponent, limited use
	"opaconfig" =>	{ Name => "opaconfig",
					  DefaultInstall => $State_Install,
					  SrcDir => ".", DriverSubdir => "",
					  PreReq => "", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
		# "ofed" is only used for source_comp
	"ofed_delta" =>	{ Name => "OFA_DELTA",
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					},
	"opa_stack" =>	{ Name => "OFA OPA Stack",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "extra/ifs-kernel-updates",
					  PreReq => "", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => "",
					  StartComponents => [ "opa_stack" ],
					},
	"ibacm" =>              { Name => "OFA IBACM",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "ibacm" ],
                                        },
	"intel_hfi" =>	{ Name => "Intel HFI Components",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => " oftools ",
 						# TBD - HasFirmware - FW update
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "intel_hfi" ],
					},
	"oftools" =>	{ Name => "OPA Tools",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => " opa_stack ",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ", # TBD
					  StartComponents => [ ],
					},
	"mpi_selector" =>	{ Name => "MPI selector",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 1, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opa_stack_dev" => { Name => "OFA OPA Development",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"fastfabric" =>	{ Name => "FastFabric",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack oftools ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
					},
	"delta_ipoib" =>	{ Name => "OFA IP over IB",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "updates",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 1,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ "delta_ipoib" ],
					},
	"mvapich2" =>	{ Name => "MVAPICH2 (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi" =>	{ Name => "OpenMPI (verbs,gcc)",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack mpi_selector intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"gasnet" =>	{ Name => "GASNet (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openshmem" =>	{ Name => "OpenSHMEM (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack gasnet intel_hfi ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_cuda_hfi" =>{ Name => "OpenMPI (cuda,gcc)",
                                         DefaultInstall => $State_Install,
                                         SrcDir => file_glob ("./OFED_MPIS.*"),
                                         DriverSubdir => "",
                                         PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
                                         Hidden => 0, Disabled => 0,
                                         HasStart => 0, HasFirmware => 0, DefaultStart => 0,
                                         StartPreReq => "",
                                         StartComponents => [ ],
					},
	"mvapich2_gcc_hfi" =>	{ Name => "MVAPICH2 (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"mvapich2_intel_hfi" =>	{ Name => "MVAPICH2 (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_gcc_hfi" =>	{ Name => "OpenMPI (hfi,gcc)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"openmpi_intel_hfi" =>	{ Name => "OpenMPI (hfi,Intel)",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob ("./OFED_MPIS.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack intel_hfi mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"delta_mpisrc" =>{ Name => "MPI Source",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack opa_stack_dev mpi_selector ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"opafm" =>	{ Name => "OPA FM",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-FM.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 1, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  #StartComponents => [ "qlgc_fm", "qlgc_fm_snmp"],
					  StartComponents => [ "opafm" ],
					},
	"opamgt_sdk" => { Name => "OPA Management SDK",
					  DefaultInstall => $State_Install,
					  SrcDir => file_glob("./IntelOPA-Tools*.*"),
					  DriverSubdir => "",
					  Prereq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => " opa_stack ",
					  StartComponents => [ ],
				  },
	"delta_debug" =>	{ Name => "OFA Debug Info",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"hfi1_uefi" =>		{ Name => "Pre-Boot Components",
					  DefaultInstall => $State_DoNotInstall,
					  SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
					  DriverSubdir => "",
					  PreReq => " opa_stack ", CoReq => "",
					  Hidden => 0, Disabled => 0,
					  HasStart => 0, HasFirmware => 0, DefaultStart => 0,
					  StartPreReq => "",
					  StartComponents => [ ],
					},
	"rdma_ndd" =>              { Name => "RDMA NDD",
                                          DefaultInstall => $State_Install,
                                          SrcDir => file_glob("./IntelOPA-OFED_DELTA.*"),
                                          DriverSubdir => "",
                                          PreReq => " opa_stack ", CoReq => "",
                                          Hidden => 1, Disabled => 1,
                                          HasStart => 1, HasFirmware => 0, DefaultStart => 0,
                                          StartPreReq => " opa_stack ",
                                          StartComponents => [ "rdma_ndd" ],
                                        },
	);

%ComponentInfo = ( );

	# translate from startup script name to component/subcomponent name
%StartupComponent = (
				"opa_stack" => "opa_stack",
				"opafm" => "opafm",
			);
	# has component been loaded since last configured autostart
%ComponentWasInstalled = (
				"opa_stack" => 0,
				"ibacm" => 0,
				"oftools" => 0,
				"mpi_selector" => 0,
				"opa_stack_dev" => 0,
				"fastfabric" => 0,
				"delta_ipoib" => 0,
				"mvapich2" => 0,
				"openmpi" => 0,
				"mvapich2_gcc_hfi" => 0,
				"mvapich2_intel_hfi" => 0,
				"openmpi_gcc_hfi" => 0,
				"openmpi_gcc_cuda_hfi" => 0,
				"openmpi_intel_hfi" => 0,
				"delta_mpisrc" => 0,
				"opafm" => 0,
				"opamgt_sdk" => 0,
				"hfi1_uefi" => 0,
				"delta_debug" => 0,
				"rdma_ndd" => 0,
			);

sub init_components
{
	if ( "$CUR_VENDOR_VER" eq "ES72" ) {
		@Components = ( @Components_rhel72 );
		%ComponentInfo = ( %ComponentInfo_rhel72 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES122" ) {
		@Components = ( @Components_sles12_sp2 );
		%ComponentInfo = ( %ComponentInfo_sles12_sp2 );
	} elsif ( "$CUR_VENDOR_VER" eq "ES73" ) {
		@Components = ( @Components_rhel73 );
		%ComponentInfo = ( %ComponentInfo_rhel73 );
	} else {
		@Components = ( @Components_other );
		%ComponentInfo = ( %ComponentInfo_other );
	}
}

# ==========================================================================
# opaconfig installation
# This is a special WrapperComponent which only needs:
#	available, install and uninstall
# it cannot have startup scripts, dependencies, prereqs, etc

sub available_opaconfig
{
	my $srcdir=$ComponentInfo{'opaconfig'}{'SrcDir'};
	return (rpm_resolve("$srcdir/*/", "any", "opaconfig"));
}

sub installed_opaconfig
{
	return rpm_is_installed("opaconfig", "any");
}

sub installed_version_opaconfig
{
	my $version = rpm_query_version_release_pkg("opaconfig");
	return dot_version("$version");
}

sub media_version_opaconfig
{
	my $srcdir = $ComponentInfo{'opaconfig'}{'SrcDir'};
	my $rpm = rpm_resolve("$srcdir/RPMS/*/", "any", "opaconfig");
	my $version = rpm_query_version_release($rpm);
	return dot_version("$version");
}

sub build_opaconfig
{
	my $osver = $_[0];
	my $debug = $_[1];      # enable extra debug of build itself
	my $build_temp = $_[2]; # temp area for use by build
	my $force = $_[3];      # force a rebuild
	return 0;       # success
}

sub need_reinstall_opaconfig($$)
{
	my $install_list = shift();	# total that will be installed when done
	my $installing_list = shift();	# what items are being installed/reinstalled

	return "no";
}

sub check_os_prereqs_opaconfig
{
	return rpm_check_os_prereqs("opaconfig", "user");
}

sub preinstall_opaconfig
{
        my $install_list = $_[0];       # total that will be installed when done
        my $installing_list = $_[1];    # what items are being installed/reinstalled

        return 0;       # success
}

sub install_opaconfig
{
	my $install_list = $_[0];	# total that will be installed when done
	my $installing_list = $_[1];	# what items are being installed/reinstalled

	my $srcdir=$ComponentInfo{'opaconfig'}{'SrcDir'};
	NormalPrint("Installing $ComponentInfo{'opaconfig'}{'Name'}...\n");

	# New Install Code
	my $rpmfile = rpm_resolve("$srcdir/RPMS/*/", "any", "opaconfig");
	rpm_run_install($rpmfile, "any", " -U ");
	# New Install Code

	# remove the old style version file
	system("rm -rf $ROOT/$BASE_DIR/version");
	# version_wrapper is only for support (fetched in opacapture)
	system("echo '$VERSION' > $BASE_DIR/version_wrapper 2>/dev/null");
	# there is no ideal answer here, if we install updates separately
	# then upgrade or reinstall with wrapper, make sure we cleanup possibly old
	# opaconfig_* files
	system("rm -rf $ROOT/sbin/opa_config_ff");
	system("rm -rf $ROOT/sbin/opa_config_fm");
	system("rm -rf $ROOT/sbin/opa_config_srp");
	system("rm -rf $ROOT/sbin/opa_config_vnic");
	system("rm -rf $ROOT/sbin/opa_config_delta");

	$ComponentWasInstalled{'opaconfig'}=1;
}

sub postinstall_opaconfig
{
        my $install_list = $_[0];       # total that will be installed when done
        my $installing_list = $_[1];    # what items are being installed/reinstalled
}

sub uninstall_opaconfig
{
	my $install_list = $_[0];	# total that will be left installed when done
	my $uninstalling_list = $_[1];	# what items are being uninstalled

	NormalPrint("Uninstalling $ComponentInfo{'opaconfig'}{'Name'}...\n");

	# New Uninstall Code
	rpm_uninstall_list("any", "verbose", ("opaconfig") );
	# New Uninstall Code

	system("rm -rf $ROOT$BASE_DIR/version_wrapper");
	system("rm -rf $ROOT$BASE_DIR/osid_wrapper");
	# remove the old style version file
	system("rm -rf $ROOT/$BASE_DIR/version");
	system("rm -rf $ROOT/sbin/opaconfig");
	# there is no ideal answer here, if we install updates separately
	# then uninstall all with wrapper, make sure we cleanup
	system("rm -rf $ROOT/sbin/opa_config_ff");
	system("rm -rf $ROOT/sbin/opa_config_fm");
	system("rm -rf $ROOT/sbin/opa_config_srp");
	system("rm -rf $ROOT/sbin/opa_config_vnic");
	system("rm -rf $ROOT/sbin/opa_config_delta");
	system "rmdir $ROOT$BASE_DIR 2>/dev/null";	# remove only if empty
	system "rmdir $ROOT$OPA_CONFIG_DIR 2>/dev/null";	# remove only if empty
	$ComponentWasInstalled{'opaconfig'}=0;
}

# source a component specific comp.pl file which will provide the
# API for managing the component's installation state
sub source_comp
{
	my($comp)=$_[0];
	my($allow_install)=$_[1];	# if not INSTALL, don't use present dir
	#print "$comp: $ComponentInfo{$comp}{'SrcDir'}/comp.pl\n"; sleep 10;
	if ( $allow_install && -e "$ComponentInfo{$comp}{'SrcDir'}/comp.pl" ) {
		# TBD - odd that require treats as package, do seems to not eval
		# the ugly eval approach seems to work
		#do "$ComponentInfo{$comp}{'SrcDir'}/comp.pl";
		#print "do $ComponentInfo{$comp}{'SrcDir'}/comp.pl\n"; sleep 5;
		#require "$ComponentInfo{$comp}{'SrcDir'}/comp.pl";
		#do "$ComponentInfo{$comp}{'SrcDir'}/comp.pl";
		# print "$ComponentInfo{$comp}{'SrcDir'}/comp.pl\n"; sleep 10;
		eval `cat "$ComponentInfo{$comp}{'SrcDir'}/comp.pl"`;
		if ( "$@" ne "" ) {
			NormalPrint "$@\n";
			Abort "Corrupted $ComponentInfo{$comp}{'Name'} script: $ComponentInfo{$comp}{'SrcDir'}/comp.pl";
		} else {
			LogPrint "Loaded $ComponentInfo{$comp}{'Name'} script: $ComponentInfo{$comp}{'SrcDir'}/comp.pl\n";
		}
		#eval "available_$comp";
	} elsif ( -e "$ROOT/usr/lib/opa/.comp_$comp.pl" ) {
		# source the installed file, mainly to aid uninstall
		#print "$ROOT/usr/lib/opa/.comp_$comp.pl\n"; sleep 10;
		eval `cat "$ROOT/usr/lib/opa/.comp_$comp.pl"`;
		if ( "$@" ne "" ) {
			NormalPrint "$@\n";
			NormalPrint "Warning: Ignoring Corrupted $ComponentInfo{$comp}{'Name'} script: $ROOT/usr/lib/opa/.comp_$comp.pl\n";
			HitKeyCont;
		} else {
			LogPrint "Loaded $ComponentInfo{$comp}{'Name'} script: $ROOT/usr/lib/opa/.comp_$comp.pl\n";
		}
	} else {
		# component not available and not installed
		LogPrint "$ComponentInfo{$comp}{'Name'} script not available\n";
	}
}

my $allow_install;
if ( my_basename($0) ne "INSTALL" )
{
	$allow_install=0;
} else {
	$allow_install=1;
	$FabricSetupScpFromDir="..";
}

#
# Check if all basic requirements are ok
#
sub verify_os_ver 
{
	#my $supported_kernel;
	#
	#if (!$allow_install)
	#{
	#	my $catkernels = `cat $ROOT$BASE_DIR/supported_kernels`;
	#	@supported_kernels = split( / +/, $catkernels);
	#} else {
	#	system("echo -n @supported_kernels > ./config/supported_kernels");
	#}
	#
	#foreach my $supported_kernel_path ( @supported_kernels ) 
	#{    
	#	$supported_kernel = my_basename($supported_kernel_path);
	#
	#	$module_dirs[++$#module_dirs] = "/lib/modules/$supported_kernel";
	#}
	# make sure current OS version included so remove_driver works
	$module_dirs[++$#module_dirs] = "/lib/modules/$CUR_OS_VER";
}

sub Usage
{
	if ( $allow_install ) {
		#printf STDERR "Usage: $0 [-r root] [-v|-vv] -R osver -B osver [-d][-t tempdir] [--user_configure_options 'options'] [--kernel_configure_options 'options'] [--prefix dir] [--without-depcheck] [--rebuild] [--force] [--answer keyword=value] [--debug]\n";
		#printf STDERR "               or\n";
		#printf STDERR "Usage: $0 [-r root] [-v|-vv] [-a|-n|-U|-F|-u|-s|-i comp|-e comp] [-E comp] [-D comp] [-f] [--fwupdate asneeded|always] [-l] [--user_configure_options 'options'] [--kernel_configure_options 'options'] [--prefix dir] [--without-depcheck] [--rebuild] [--force] [--answer keyword=value] [--debug]\n";
		#printf STDERR "Usage: $0 [-r root] [-v|-vv] [-a|-n|-U|-F|-u|-s|-i comp|-e comp] [-E comp] [-D comp] [-f] [--fwupdate asneeded|always] [--user_configure_options 'options'] [--kernel_configure_options 'options'] [--prefix dir] [--without-depcheck] [--rebuild] [--force] [--answer keyword=value]\n";
		printf STDERR "Usage: $0 [-r root] [-v|-vv] -R osver -B osver [-a|-n|-U|-u|-s|-O|-N|-i comp|-e comp] [-E comp] [-D comp] [--user-space] [--user_configure_options 'options'] [--kernel_configure_options 'options'] [--prefix dir] [--without-depcheck] [--rebuild] [--force] [--answer keyword=value]\n";
	} else {
#		printf STDERR "Usage: $0 [-r root] [-v|-vv] [-F|-u|-s|-e comp] [-E comp] [-D comp]\n";
#		printf STDERR "          [--fwupdate asneeded|always] [--user_queries|--no_user_queries] [--answer keyword=value]\n";
		printf STDERR "Usage: $0 [-r root] [-v|-vv] [-u|-s|-e comp] [-E comp] [-D comp]\n";
		printf STDERR "          [--user_queries|--no_user_queries] [--answer keyword=value]\n";
	}
	printf STDERR "               or\n";
	printf STDERR "Usage: $0 -C\n";
	printf STDERR "               or\n";
	printf STDERR "Usage: $0 -V\n";
	if ( $allow_install ) {
		printf STDERR "       -a - install all ULPs and drivers with default options\n";
		printf STDERR "       -n - install all ULPs and drivers with default options\n";
		printf STDERR "            but with no change to autostart options\n";
		printf STDERR "       -U - upgrade/re-install all presently installed ULPs and drivers with\n";
		printf STDERR "            default options and no change to autostart options\n";
		printf STDERR "       -i comp - install the given component with default options\n";
		printf STDERR "            can appear more than once on command line\n";
#		printf STDERR "       -f - skip HCA firmware upgrade during install\n";
		printf STDERR "       --user-space - Skip kernel space components during installation\n";
		#printf STDERR "       -l - skip creating/removing symlinks to /usr/local from /usr/lib/opa\n";
		printf STDERR "       --user_configure_options 'options' - specify additional OFA build\n";
		printf STDERR "             options for user space srpms.  Causes rebuild of all user srpms\n";
		printf STDERR "       --kernel_configure_options 'options' - specify additional OFA build\n";
		printf STDERR "             options for driver srpms.  Causes rebuild of all driver srpms\n";
		printf STDERR "       --prefix dir - specify alternate directory prefix for install of OFA\n";
		printf STDERR "             default is /usr.  Causes rebuild of needed srpms\n";
		printf STDERR "       --without-depcheck - disable check of OS dependencies\n";
		printf STDERR "       --rebuild - force OFA Delta rebuild\n";
		printf STDERR "       --force - force install even if distos don't match\n";
		printf STDERR "                 Use of this option can result in undefined behaviors\n";
		printf STDERR "       -O - Keep current modified rpm config file\n";
		printf STDERR "       -N - Use new default rpm config file\n";
		# --debug, -t and -d options are purposely not documented
		#printf STDERR "       --debug - build a debug version of modules\n";
		printf STDERR "       -B osver - run build for all components targetting kernel osver\n";
		#printf STDERR "       -t - temp area for use by builds, only valid with -B\n";
		#printf STDERR "       -d - enable build debugging assists, only valid with -B\n";
		printf STDERR "       -R osver - force install for kernel osver rather than running kernel.\n";
	}
#	printf STDERR "       -F - upgrade HCA Firmware with default options\n";
#	printf STDERR "       --fwupdate asneeded|always - select fw update auto update mode\n";
#	printf STDERR "            asneeded - update or downgrade to match version in this release\n";
#	printf STDERR "            always - rewrite with this releases version even if matches\n";
#	printf STDERR "            default is to upgrade as needed but not downgrade\n";
#	printf STDERR "            this option is ignored for interactive install\n";
	printf STDERR "       -u - uninstall all ULPs and drivers with default options\n";
	printf STDERR "       -s - enable autostart for all installed drivers\n";
	printf STDERR "       -r - specify alternate root directory, default is /\n";
	printf STDERR "       -e comp - uninstall the given component with default options\n";
	printf STDERR "            can appear more than once on command line\n";
	printf STDERR "       -E comp - enable autostart of given component\n";
	printf STDERR "            can appear with -D or more than once on command line\n";
	printf STDERR "       -D comp - disable autostart of given component\n";
	printf STDERR "            can appear with -E or more than once on command line\n";
	printf STDERR "       -G - install GPU Direct components\n";
	printf STDERR "       -v - verbose logging\n";
	printf STDERR "       -vv - very verbose debug logging\n";
	printf STDERR "       -C - output list of supported components\n";
	printf STDERR "       -V - output Version\n";

	printf STDERR "       --user_queries - permit non-root users to query the fabric. (default)\n";
	printf STDERR "       --no_user_queries - non root users cannot query the fabric.\n";
	showAnswerHelp();

	printf STDERR "       default options retain existing configuration files\n";
	printf STDERR "       supported component names:\n";
	printf STDERR "            ";
	foreach my $comp ( @Components )
	{
		printf STDERR " $comp";
	}
	printf STDERR "\n";
	printf STDERR "       supported component name aliases:\n";
	printf STDERR "            opa ipoib mpi psm_mpi verbs_mpi pgas mpisrc opadev\n";
	if (scalar(@SubComponents) > 0) {
		printf STDERR "       additional component names allowed for -E and -D options:\n";
		printf STDERR "            ";
		foreach my $comp ( @SubComponents )
		{
			printf STDERR " $comp";
		}
		printf STDERR "\n";
	}
	exit (2);
}

my $Default_FirmwareUpgrade=0;	# -F option used to select default firmware upgrade

# translate an ibaccess component name into the corresponding list of ofed comps
# if the given name is invalid or has no corresponding OFED component
# returns an empty list
sub translate_comp
{
	my($arg)=$_[0];
	if ("$arg" eq "opadev")			{ return ( "opa_stack_dev" );
	} elsif ("$arg" eq "opa")		{ return ( "oftools",
		"mvapich2_gcc_hfi", "openmpi_gcc_hfi", "mvapich2_intel_hfi",
		"openmpi_intel_hfi");
	} elsif ("$arg" eq "ipoib")		{ return ( "delta_ipoib" );
	} elsif ("$arg" eq "mpi")		{ return ( "mvapich2", "openmpi", 
		"mvapich2_gcc_hfi", "openmpi_gcc_hfi", "mvapich2_intel_hfi", 
		"openmpi_intel_hfi");
	} elsif ("$arg" eq "psm_mpi")	{ return ( "mvapich2_gcc_hfi",
		"openmpi_gcc_hfi", "mvapich2_intel_hfi", 
		"openmpi_intel_hfi");
	} elsif ("$arg" eq "verbs_mpi")	{ return ( "mvapich2", "openmpi" );
	} elsif ("$arg" eq "pgas")		{ return ( "gasnet", "openshmem" );
	} elsif ("$arg" eq "mpisrc")	{ return ( "delta_mpisrc" );
		# no ibaccess argument equivalent for:  
		#	openmpi, delta_debug
		#
	} else {
		return ();	# invalid name
	}
}

sub process_args
{
	my $arg;
	my $last_arg;
	my $setroot = 0;
	my $install_opt = 0;
	my $setcomp = 0;
	my $setanswer = 0;
	my $setenabled = 0;
	my $setdisabled = 0;
	my $setosver = 0;
	my $setbuildtemp = 0;
	my $comp = 0;
	my $osver = 0;
	my $setuseroptions = 0;
	my $setcurosver = 0;
	my $setkerneloptions = 0;
	my $setprefix = 0;
	my $setfwmode = 0;
	my $patch_ofed=0;

	if (scalar @ARGV >= 1) {
		foreach $arg (@ARGV) {
			if ( $setroot ) {
				$ROOT="$arg";
				if (substr($ROOT,0,1) ne "/") {
					printf STDERR "Invalid -r root (must be absolute path): '$ROOT'\n";
					Usage;
				}
				if (! -d $ROOT) {
					printf STDERR "Invalid -r root (directory not found): '$ROOT'\n";
					Usage;
				}
				$setroot=0;
			} elsif ( $setanswer ) {
				my @pair = split /=/,$arg;
				if ( scalar(@pair) != 2 ) {
					printf STDERR "Invalid --answer keyword=value: '$arg'\n";
					Usage;
				}
				set_answer($pair[0], $pair[1]);
				$setanswer=0;
			} elsif ( $setcomp ) {
				foreach $comp ( @Components )
				{
					if ( "$arg" eq "$comp" )
					{
						$Default_Components{$arg} = 1;
						$setcomp=0;
					}
				}
				if ( $setcomp )
				{
					my @comps = translate_comp($arg);
					# if empty list returned, we will not clear setcomp and
					# will get error below
					foreach $comp ( @comps )
					{
						$Default_Components{$comp} = 1;
						$setcomp=0;
					}
				}
				if ( $setcomp )
				{
					printf STDERR "Invalid component: $arg\n";
					Usage;
				}
			} elsif ( $setenabled ) {
				foreach $comp ( @Components, @SubComponents )
				{
					if ( "$arg" eq "$comp" )
					{
						$Default_EnabledComponents{$arg} = 1;
						$setenabled=0;
					}
				}
				if ( $setenabled )
				{
					my @comps = translate_comp($arg);
					# if empty list returned, we will not clear setcomp and
					# will get error below
					foreach $comp ( @comps )
					{
						$Default_EnabledComponents{$comp} = 1;
						$setenabled=0;
					}
				}
				if ( $setenabled )
				{
					printf STDERR "Invalid component: $arg\n";
					Usage;
				}
			} elsif ( $setdisabled ) {
				foreach $comp ( @Components, @SubComponents )
				{
					if ( "$arg" eq "$comp" )
					{
						$Default_DisabledComponents{$arg} = 1;
						$setdisabled=0;
					}
				}
				if ( $setdisabled )
				{
					my @comps = translate_comp($arg);
					# if empty list returned, we will not clear setcomp and
					# will get error below
					foreach $comp ( @comps )
					{
						$Default_DisabledComponents{$comp} = 1;
						$setdisabled=0;
					}
				}
				if ( $setdisabled )
				{
					printf STDERR "Invalid component: $arg\n";
					Usage;
				}
			} elsif ( $setosver ) {
				$Build_OsVer="$arg";
				$setosver=0;
			} elsif ( $setbuildtemp ) {
				$Build_Temp="$arg";
				$setbuildtemp=0;
			} elsif ( $setuseroptions ) {
				$OFED_user_configure_options="$arg";
				$setuseroptions=0;
			} elsif ( $setkerneloptions ) {
				$OFED_kernel_configure_options="$arg";
				$setkerneloptions=0;
			} elsif ( $setprefix ) {
				$OFED_prefix="$arg";
				$setprefix=0;
#			} elsif ( $setfwmode ) {
#				if ( "$arg" eq "always" || "$arg" eq "asneeded") {
#					$Default_FirmwareUpgradeMode="$arg";
#				} else {
#					printf STDERR "Invalid --fwupdate mode: $arg\n";
#					Usage;
#				}
#				$setfwmode = 0;
			} elsif ( $setcurosver ) {
				$CUR_OS_VER="$arg";
				@supported_kernels = ( $CUR_OS_VER );
				$setcurosver=0;
			} elsif ( "$arg" eq "-r" ) {
				$setroot=1;
			} elsif ( "$arg" eq "-v" ) {
				$LogLevel=1;
			} elsif ( "$arg" eq "-vv" ) {
				$LogLevel=2;
#			} elsif ( "$arg" eq "-f" ) {
#				$Skip_FirmwareUpgrade=1;
			} elsif ( "$arg" eq "-i" ) {
				$Default_CompInstall=1;
				$Default_Prompt=1;
				$setcomp=1;
				if ($install_opt || $Default_CompUninstall || $Default_Build) {
					# can't mix -i with other install controls
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "-e" ) {
				$Default_CompUninstall=1;
				$Default_Prompt=1;
				$setcomp=1;
				if ($install_opt || $Default_CompInstall || $Default_Build) {
					# can't mix -e with other install controls
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "-E" ) {
				$Default_Autostart=1;
				$Default_EnableAutostart=1;
				$Default_Prompt=1;
				$setenabled=1;
				if ($Default_Build) {
					# can't mix -E with other install controls
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "-D" ) {
				$Default_Autostart=1;
				$Default_DisableAutostart=1;
				$Default_Prompt=1;
				$setdisabled=1;
				if ($Default_Build) {
					# can't mix -D with other install controls
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "--user_configure_options" ) {
				$setuseroptions=1;
			} elsif ( "$arg" eq "--kernel_configure_options" ) {
				$setkerneloptions=1;
			} elsif ( "$arg" eq "--prefix" ) {
				$setprefix=1;
			} elsif ( "$arg" eq "--fwupdate" ) {
				$setfwmode=1;
			} elsif ( "$arg" eq "--answer" ) {
				$setanswer=1;
			} elsif ( "$arg" eq "--without-depcheck" ) {
				$rpm_check_dependencies=0;
			} elsif ( "$arg" eq "--user-space" ) {
				$skip_kernel = 1;
			} elsif ( "$arg" eq "--force" ) {
				$Force_Install=1;
			} elsif ( "$arg" eq "-G" ) {
				$GPU_Install=1;
			} elsif ( "$arg" eq "-C" ) {
				ShowComponents;
				exit(0);
			} elsif ( "$arg" eq "-V" ) {
				printf "$VERSION\n";
				exit(0);
			} elsif ( "$arg" eq "-R" ) {
				$setcurosver=1;
			} elsif ( "$arg" eq "-B" ) {
				# undocumented option to do a build for specific OS
				$Default_Build=1;
				$Default_Prompt=1;
				$setosver=1;
				if ($install_opt || $Default_CompInstall || $Default_CompUninstall || $Default_Autostart) {
					# can't mix -B with install
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "-d" ) {
				# undocumented option to aid debug of build
				$Build_Debug=1;
				if ($install_opt || $Default_CompInstall || $Default_CompUninstall || $Default_Autostart) {
					# can't mix -d with install
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "-t" ) {
				# undocumented option to aid debug of build
				$setbuildtemp=1;
				if ($install_opt || $Default_CompInstall || $Default_CompUninstall || $Default_Autostart) {
					# can't mix -t with install
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
			} elsif ( "$arg" eq "--rebuild" ) {
				# force rebuild
				$Build_Force=1;
				$OFED_force_rebuild=1;
			} elsif ( "$arg" eq "--debug" ) {
				$OFED_debug=1;
			} elsif ( "$arg" eq "--user_queries" ) {
				$Default_UserQueries=1;
			} elsif ( "$arg" eq "--no_user_queries" ) {
				$Default_UserQueries=-1;
			} elsif ( "$arg" eq "--patch_ofed" ) {
				$patch_ofed=1;
			} else {
				# Install options
				if ( "$arg" eq "-a" ) {
					$Default_Install=1;
				} elsif ( "$arg" eq "-u" ) {
					$Default_Uninstall=1;
				} elsif ( "$arg" eq "-s" ) {
					$Default_Autostart=1;
				} elsif ( "$arg" eq "-n" ) {
					$Default_Install=1;
					$Default_SameAutostart=1;
				} elsif ( "$arg" eq "-U" ) {
					$Default_Upgrade=1;
					$Default_SameAutostart=1;
#				} elsif ( "$arg" eq "-F" ) {
#					$Default_FirmwareUpgrade=1;
				} elsif ("$arg" eq "-O") {
					$Default_RpmConfigKeepOld=1;
					$Default_RpmConfigUseNew=0;
				} elsif ("$arg" eq "-N") {
					$Default_RpmConfigKeepOld=0;
					$Default_RpmConfigUseNew=1;
				} else {
					printf STDERR "Invalid option: $arg\n";
					Usage;
				}
				if ($install_opt || $Default_CompInstall
					 || $Default_CompUninstall) {
					# only one of the above install selections
					printf STDERR "Invalid combination of options: $arg not permitted with previous options\n";
					Usage;
				}
				$install_opt=1;
				$Default_Prompt=1;
			}
			$last_arg=$arg;
		}
	}
	if ( $setroot || $setcomp || $setenabled || $setdisabled  || $setosver || $setbuildtemp || $setuseroptions || $setkerneloptions || $setprefix || $setfwmode || $setanswer) {
		printf STDERR "Missing argument for option: $last_arg\n";
		Usage;
	}
	if ( ($Default_Install || $Default_CompInstall || $Default_Upgrade
			|| $Force_Install)
         && ! $allow_install) {
		printf STDERR "Installation options not permitted in this mode\n";
		Usage;
	}
	if ( ($Default_Build || $OFED_force_rebuild || $OFED_debug
		 || ($OFED_user_configure_options ne '')
			 || ($OFED_kernel_configure_options ne '')
			 || ($OFED_prefix ne '/usr'))
		&& ! $allow_install) {
		printf STDERR "Build options not permitted in this mode\n";
		Usage;
	}
	if ( $patch_ofed) {
		NormalPrint("Patching OFA...\n");
		LogPrint("Executing: cd $ComponentInfo{'opa_stack'}{'SrcDir'}; ./patch_ofed3\n");
		system("cd $ComponentInfo{'opa_stack'}{'SrcDir'}; ./patch_ofed3");
		HitKeyCont;
	}
}

my @INSTALL_CHOICES= ();
sub show_menu
{
	my $inp;
	my $max_inp;

	@INSTALL_CHOICES= ();
	if ( $Default_Install ) {
		NormalPrint ("Installing All OPA Software\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 1);
	}
   	if ( $Default_CompInstall ) {
		NormalPrint ("Installing Selected OPA Software\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 1);
	}
  	if ( $Default_Upgrade ) {
		NormalPrint ("Upgrading/Re-Installing OPA Software\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 1);
	}
#   	if ( $Default_FirmwareUpgrade ) {
#		NormalPrint ("Upgrading HCA Firmware\n");
#		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 4);
#	}
   	if ($Default_Uninstall ) {
		NormalPrint ("Uninstalling All OPA Software\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 6);
	}
   	if ($Default_CompUninstall ) {
		NormalPrint ("Uninstalling Selected OPA Software\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 6);
	}
   	if ($Default_Autostart) {
		NormalPrint ("Configuring autostart for Selected installed OPA Drivers\n");
		@INSTALL_CHOICES = ( @INSTALL_CHOICES, 3);
	}
	if (scalar(@INSTALL_CHOICES) > 0) {
		return;
	}
START:	
	system "clear";
	printf ("$BRAND OPA $VERSION Software\n\n");
	if ($allow_install) {
		printf ("   1) Install/Uninstall Software\n");
	} else {
		printf ("   1) Show Installed Software\n");
	}
	printf ("   2) Reconfigure $ComponentInfo{'delta_ipoib'}{'Name'}\n");
	printf ("   3) Reconfigure Driver Autostart \n");
	printf ("   4) Generate Supporting Information for Problem Report\n");
	printf ("   5) FastFabric (Host/Chassis/Switch Setup/Admin)\n");
#	printf ("   6) Update HCA Firmware\n");
	$max_inp=5;
	if (!$allow_install)
	{
#		printf ("   7) Uninstall Software\n");
		printf ("   6) Uninstall Software\n");
		$max_inp=6;
	}
	printf ("\n   X) Exit\n");


	$inp = getch();      

	if ($inp =~ /[qQ]/ || $inp =~ /[Xx]/ ) {
		@INSTALL_CHOICES = ( 99999 );	# indicates exit, none selected
		return;
	}
	if (ord($inp) == $KEY_ENTER) {           
		goto START;
	}

	if ($inp =~ /[0123456789abcdefABCDEF]/)
	{
		$inp = hex($inp);
	}

	if ($inp < 1 || $inp > $max_inp) 
	{
#		printf ("Invalid choice...Try again\n");
		goto START;
	}
	@INSTALL_CHOICES = ( $inp );
}

determine_os_version;
init_components;

process_args;
check_root_user;
if ( ! $Default_Build ) {
	open_log("");
} else {
	open_log("./build.log");
}

source_comp("ofed_delta", $allow_install);
source_comp("oftools", $allow_install);	# allow oftools installed w/o fastfabric
source_comp("fastfabric", $allow_install);
source_comp("opafm", $allow_install);

if ( ! $Default_Build ) {
	verify_os_ver;
	verify_modtools;
	if ($allow_install) {
		verify_distrib_files;
	}
}

foreach my $comp ( @OmniPathAllComponents )
{
        $ComponentInfo{$comp}{'DefaultInstall'} = $State_Install;
	$Default_EnabledComponents{$comp} = 1;
}

set_libdir;
init_delta_rpm_info($CUR_OS_VER);

RESTART:
if ($Default_Build) {
	$exit_code = build_all_components($Build_OsVer, $Build_Debug, $Build_Temp, $Build_Force);
	goto DONE;
} else {
	show_menu;
}

foreach my $INSTALL_CHOICE ( @INSTALL_CHOICES )
{
	if ($allow_install && $INSTALL_CHOICE == 1) 
	{
		select_debug_release(".");
		show_install_menu(1);
		if (! $Default_Prompt) {
			goto RESTART;
		} else {
			if ($exit_code == 0) {
				print "Done Installing OPA Software.\n"
			} else {
				print "Failed to install all OPA software.\n"
			}
		}
	} 
	elsif ($INSTALL_CHOICE == 1) {
		show_installed(1);
		goto RESTART;
	}
	elsif ($INSTALL_CHOICE == 6)
	{
		show_uninstall_menu(1);
		if (! $Default_Prompt ) {
			goto RESTART;
		} else {
			if ($exit_code == 0) {
				print "Done Uninstalling OPA Software.\n"
			} else {
				print "Failed to uninstall all OPA Software.\n"
			}
		}
	}
	elsif ($INSTALL_CHOICE == 2) 
	{     
		Config_ifcfg(1,"$ComponentInfo{'delta_ipoib'}{'Name'}","ib", "$FirstIPoIBInterface",1);
		check_network_config;
		#Config_IPoIB_cfg;
		goto RESTART;
	}
	elsif ($INSTALL_CHOICE == 3) 
	{
		reconfig_autostart;
		if (! $Default_Prompt ) {
			goto RESTART;
		} else {
			print "Done OPA Driver Autostart Configuration.\n"
		}
	}
#	elsif ($INSTALL_CHOICE == 6)
#	{
#		# Update HFI Firmware
#		update_hca_firmware;
#		if (! $Default_Prompt ) {
#			goto RESTART;
#		} else {
#			print "Done HFI Firmware Update.\n"
#		}
#	}
	elsif ($INSTALL_CHOICE == 4) 
	{
		# Generate Supporting Information for Problem Report
		capture_report($ComponentInfo{'oftools'}{'Name'});
		goto RESTART;
	}
	elsif ($INSTALL_CHOICE == 5) 
	{
		# FastFabric (Host/Chassis/Switch Setup/Admin)
		if ( "$ROOT" eq "" || "$ROOT" eq "/" ) {
			run_fastfabric($ComponentInfo{'fastfabric'}{'Name'});
		} else {
			print "Unable to run fastfabric when using an alternate root (-r)\n";
			HitKeyCont;
		}
		goto RESTART;
	}
}
DONE:
close_log;
exit $exit_code;
