#!/usr/bin/perl
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# Copyright (c) 2012 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 File::Basename;
use File::Path;
use File::Find;
use File::Copy;
use File::Temp;
use Cwd;
use Term::ANSIColor qw(:constants);
use sigtrap 'handler', \&sig_handler, 'normal-signals';
my $PREREQUISIT = "172";
my $MST_START_FAIL = "173";
my $NO_HARDWARE = "171";
my $SUCCESS = "0";
my $DEVICE_INI_MISSING = "2";
my $ERROR = "1";
my $EINVAL = "22";
my $ENOSPC = "28";
my $NONOFEDRPMS = "174";
my $enable_mlnx_tune = 0;

$ENV{"LANG"} = "C";

if ($<) {
    print RED "Only root can run $0", RESET "\n";
    exit $PREREQUISIT;
}

$| = 1;
my $LOCK_EXCLUSIVE = 2;
my $UNLOCK         = 8;
#Setup some defaults
my $KEY_ESC=27;
my $KEY_CNTL_C=3;
my $KEY_ENTER=13;

my $BASIC = 1;
my $HPC = 2;
my $ALL = 3;
my $CUSTOM = 4;
my $VMA = 5;
my $VMAVPI = 6;
my $VMAETH = 7;
my $GUESTOS = 8;
my $HYPERVISOROS = 9;
my $BLUEFIELD = 10;

my $interactive = 1;
my $kernel_only = 0;
my $quiet = 0;
my $verbose = 1;
my $verbose2 = 0;
my $verbose3 = 0;

my $print_available = 0;

my $clear_string = `clear`;
my $bonding_force_all_os = 0;

my $vendor_pre_install = "";
my $vendor_post_install = "";
my $vendor_pre_uninstall = "";
my $vendor_post_uninstall = "";

# list of scripts to run for each package
my %package_pre_build_script = ();
my %package_post_build_script = ();
my %package_pre_install_script = ();
my %package_post_install_script = ();

my $DISTRO = "";
my $rpmbuild_flags = "";
my $rpminstall_flags = "";
my $rpminstall_parameter = "-i";
my $speed_up_kmp = 0;

my $WDIR    = dirname(`readlink -f $0`);
chdir $WDIR;
require("$WDIR/common.pl");
my $CWD     = getcwd;
my $TMPDIR  = '/tmp';
my $netdir;

my $conf_dir = $CWD;
my $config = $conf_dir . '/ofed.conf';
chomp $config;
my $config_net;

my $builddir = "/var/tmp";
chomp $builddir;

my $PACKAGE     = 'OFED';

my $default_prefix = '/usr';
chomp $default_prefix;
my $prefix = $default_prefix;

my $build32 = 0;
my $arch = `uname -m`;
chomp $arch;
my $kernel = `uname -r`;
chomp $kernel;
my $kernel_sources = "/lib/modules/$kernel/build";
chomp $kernel_sources;
my $ib_udev_rules = "/etc/udev/rules.d/90-ib.rules";

# Define RPMs environment
my $dist_rpm;
my $dist_rpm_ver = 0;
my $dist_rpm_rel = 0;

my $umad_dev_rw = 0;
my $umad_dev_na = 0;
my $config_given = 0;
my $config_net_given = 0;
my $kernel_given = 0;
my $kernel_source_given = 0;
my $install_option;
my $force_all = 0;
if (-e "$CWD/.def_option" ) {
    $install_option = `cat $CWD/.def_option 2>/dev/null`;
    chomp $install_option;
}
my $user_space_only = 0;
my $check_linux_deps = 1;
my $force = 0;
my $update = 0;
my $build_only = 0;
my $check_deps_only = 0;
my $uninstall = 1;
my $kmp = 1;
my $kmp_build_num = "";
my %disabled_packages;
my %force_enable_packages;
my %packages_deps = ();
my %modules_deps = ();
my $knem_prefix = '';
my $mxm_prefix = '/opt/mellanox/mxm';
my $fca_prefix = '/opt/mellanox/fca';
my $hcoll_prefix = '/opt/mellanox/hcoll';
my $openshmem_prefix = '/opt/mellanox/openshmem';
my $mlnx_ethtool_prefix = "/opt/mellanox/ethtool";
my $mlnx_ethtool_mandir = "$mlnx_ethtool_prefix/share/man";
my $mlnx_ethtool_defaultdocdir = "$mlnx_ethtool_prefix/share/doc";
my $with_memtrack = 0;
my $with_vma = 0;
my $with_fabric_collector = 0;
my $with_libdisni = 0;
my $package_manager = "";
my $with_valgrind = 0;
my $disable_valgrind = 0;
my $have_numa_libs = 0;
my $use_upstream_libs = 0;
my $enable_opensm = 0;
my $cuda_version = "9-2";
my $cuda_top_dir = "";
my $add_debuginfo_macros = 0;
my $rpm_macros_path = "";
my $rpm_macros_file; # Global for File::Temp scoping

my $is_bf = `lspci -s 00:00.0 2> /dev/null | grep -wq "PCI bridge: Mellanox Technologies" && echo 1 || echo 0`;
chomp $is_bf;

my $with_bluefield = 0;
if  ($is_bf) {
    $with_bluefield = 1;
}

my $CMD = "$0 " . join(' ', @ARGV);
while ( $#ARGV >= 0 ) {

   my $cmd_flag = shift(@ARGV);

    if ( $cmd_flag eq "-c" or $cmd_flag eq "--config" ) {
        $config = shift(@ARGV);
        $interactive = 0;
        $config_given = 1;
    } elsif ( $cmd_flag eq "-n" or $cmd_flag eq "--net" ) {
        $config_net = shift(@ARGV);
        $config_net_given = 1;
    } elsif ( $cmd_flag eq "-l" or $cmd_flag eq "--prefix" ) {
        $prefix = shift(@ARGV);
        $prefix =~ s/\/$//;
    } elsif ( $cmd_flag eq "-k" or $cmd_flag eq "--kernel" ) {
        $kernel = shift(@ARGV);
        $kernel_given = 1;
    } elsif ( $cmd_flag eq "-s" or $cmd_flag eq "--kernel-sources" ) {
        $kernel_sources = shift(@ARGV);
        $kernel_source_given = 1;
    } elsif ( $cmd_flag eq "-U" or $cmd_flag eq "--update" ) {
        $update = 1;
    } elsif ( $cmd_flag eq "-b" or $cmd_flag eq "--build-only" ) {
        $build_only = 1;
    } elsif ( $cmd_flag eq "--check-deps-only" ) {
        $check_deps_only = 1;
    } elsif ( $cmd_flag eq "-p" or $cmd_flag eq "--print-available" ) {
        $print_available = 1;
    } elsif ( $cmd_flag eq "--force" ) {
        $force = 1;
    } elsif ( $cmd_flag eq "--disable-kmp" ) {
        $kmp = 0;
    } elsif ( $cmd_flag eq "--bump-kmp-version" ) {
        $kmp_build_num = shift(@ARGV);
    } elsif ( $cmd_flag eq "--speed-up-kmp" ) {
        $speed_up_kmp = 1;
    } elsif ( $cmd_flag eq "--all" ) {
        $interactive = 0;
        $install_option = 'all';
        $force_all = 1;
    } elsif ( $cmd_flag eq "--bluefield" ) {
        $interactive = 0;
        # Do not override other install options to enable bluefield packages as an extension
        $install_option = 'bluefield' if (not $install_option or ($install_option eq 'all' and not $force_all));
        $with_bluefield = 1;
    } elsif ( $cmd_flag eq "--hpc" ) {
        $interactive = 0;
        $install_option = 'hpc';
    } elsif ( $cmd_flag eq "--with-vma" and not ($install_option eq 'eth-only')) {
        $with_vma = 1;
    } elsif ( $cmd_flag eq "--vma" ) {
        $interactive = 0;
        $install_option = 'vma';
        $with_vma = 1;
    } elsif ( $cmd_flag eq "--vma-eth" ) {
        $interactive = 0;
        $install_option = 'vmaeth';
        $with_vma = 1;
    } elsif ( $cmd_flag eq "--vma-vpi" ) {
        $interactive = 0;
        $install_option = 'vmavpi';
        $with_vma = 1;
    } elsif ( $cmd_flag eq "--basic" ) {
        $interactive = 0;
        $install_option = 'basic';
    } elsif ( $cmd_flag eq "--guest" ) {
        $interactive = 0;
        $install_option = 'guest-os';
    } elsif ( $cmd_flag eq "--hypervisor" ) {
        $interactive = 0;
        $install_option = 'hypervisor-os';
    } elsif ( $cmd_flag eq "--kernel-only" ) {
        $interactive = 0;
        $kernel_only = 1;
        $install_option = 'kernel-only';
    } elsif ( $cmd_flag eq "--user-space-only" ) {
        $user_space_only = 1;
    } elsif ( $cmd_flag eq "--dpdk" ) {
        $interactive = 0;
        $install_option = 'dpdk';
    } elsif ( $cmd_flag eq "--upstream-libs" ) {
        $use_upstream_libs = 1;
    } elsif ( $cmd_flag eq "--mlnx-libs" ) {
        $use_upstream_libs = 0;
    } elsif ( $cmd_flag eq "--umad-dev-rw" ) {
        $umad_dev_rw = 1;
    } elsif ( $cmd_flag eq "--umad-dev-na" ) {
        $umad_dev_na = 1;
    } elsif ( $cmd_flag eq "--eth-only" ) {
        $interactive = 0;
        $install_option = 'eth-only';
    } elsif ( $cmd_flag eq "--build32" ) {
        if (supported32bit()) {
            $build32 = 1;
        }
    } elsif ( $cmd_flag eq "--without-depcheck" ) {
        $check_linux_deps = 0;
    } elsif ( $cmd_flag eq "--with-memtrack" ) {
        $with_memtrack = 1;
    } elsif ( $cmd_flag eq "--builddir" ) {
        $builddir = shift(@ARGV);
        $builddir = clean_path($builddir);
    } elsif ( $cmd_flag eq "--tmpdir" ) {
        $TMPDIR = shift(@ARGV);
        $TMPDIR = clean_path($TMPDIR);
    } elsif ( $cmd_flag eq "-q" ) {
        $quiet = 1;
    } elsif ( $cmd_flag eq "-v" ) {
        $verbose = 1;
    } elsif ( $cmd_flag eq "-vv" ) {
        $verbose = 1;
        $verbose2 = 1;
    } elsif ( $cmd_flag eq "-vvv" ) {
        $verbose = 1;
        $verbose2 = 1;
        $verbose3 = 1;
    } elsif ($cmd_flag eq "--conf-dir") {
	$conf_dir = shift(@ARGV);
	mkpath([$conf_dir]) unless -d "$conf_dir";
	if (not $config_given) {
		$config = $conf_dir . '/ofed.conf';
	}
    } elsif ($cmd_flag eq "--with-fabric-collector") {
        $with_fabric_collector = 1;
    } elsif ($cmd_flag eq "--with-libdisni") {
        $with_libdisni = 1;
    } elsif ( $cmd_flag eq "--with-valgrind" ) {
        $with_valgrind = 1;
        $disable_valgrind = 0;
    } elsif ( $cmd_flag eq "--without-valgrind" ) {
        $with_valgrind = 0;
        $disable_valgrind = 1;
    } elsif ( $cmd_flag eq "--enable-mlnx_tune" ) {
        $enable_mlnx_tune = 1;
    } elsif ( $cmd_flag eq "--enable-opensm" ) {
        $enable_opensm = 1;
    } elsif ( $cmd_flag =~ /--without|--disable/ ) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--without-|--disable-//;
        $disabled_packages{$pckg} = 1;
    } elsif ( $cmd_flag =~ /--with-|--enable-/ ) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--with-|--enable-//;
        $force_enable_packages{$pckg} = 1;
    } elsif ( $cmd_flag eq "--distro" ) {
        $DISTRO = shift(@ARGV);
    } elsif ( $cmd_flag =~ /--pre-build-/) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--pre-build-//;
        my $script = shift(@ARGV);
        $package_pre_build_script{$pckg} = $script;
    } elsif ( $cmd_flag =~ /--post-build-/) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--post-build-//;
        my $script = shift(@ARGV);
        $package_post_build_script{$pckg} = $script;
    } elsif ( $cmd_flag =~ /--pre-install-/) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--pre-install-//;
        my $script = shift(@ARGV);
        $package_pre_install_script{$pckg} = $script;
    } elsif ( $cmd_flag =~ /--post-install-/) {
        my $pckg = $cmd_flag;
        $pckg =~ s/--post-install-//;
        my $script = shift(@ARGV);
        $package_post_install_script{$pckg} = $script;
    } elsif ( $cmd_flag eq "--package-install-options" ) {
        my $install_opt = shift(@ARGV);
        $install_opt =~ s/,/ /g;
        $rpminstall_flags .= " $install_opt";
    } elsif ( $cmd_flag eq "--help" or $cmd_flag eq "-h" ) {
        usage();
        exit 0;
    } else {
        print RED "\nUnsupported installation option: '$cmd_flag'", RESET "\n";
        print "To see list of supported options, run: $0 --help\n";
        exit 1;
    }
}

my $modules_list = "$TMPDIR/mlnx_kos.$$";
system("/bin/rm -f $modules_list >/dev/null 2>&1");

if ($build_only and not (($install_option eq 'kernel-only') or ($install_option eq 'eth-only'))) {
    print RED "\nError: The '--build-only' option is supported only when '--kernel-only' option is given!", RESET "\n";
    print "To see list of supported options, run: $0 --help\n";
    exit 1;
}

$ENV{"OFA_DIR"} = "$prefix/src/ofa_kernel";

if (-e "/etc/issue") {
    $dist_rpm = `rpm -qf /etc/issue 2> /dev/null | grep -v "is not owned by any package" | head -1`;
    chomp $dist_rpm;
    if ($dist_rpm) {
        $dist_rpm = `rpm -q --queryformat "[%{NAME}]-[%{VERSION}]-[%{RELEASE}]" $dist_rpm 2>/dev/null`;
        chomp $dist_rpm;
        $dist_rpm_ver = get_rpm_ver_inst($dist_rpm);
        $dist_rpm_rel = get_rpm_rel_inst($dist_rpm);
    } else {
        $dist_rpm = `rpm -qf /etc/os-release 2> /dev/null | grep -v "is not owned by any package" | head -1`;
        chomp $dist_rpm;
        if ($dist_rpm) {
          $dist_rpm = `rpm -q --queryformat "[%{NAME}]-[%{VERSION}]-[%{RELEASE}]" $dist_rpm 2>/dev/null`;
          chomp $dist_rpm;
          $dist_rpm_ver = get_rpm_ver_inst($dist_rpm);
          $dist_rpm_rel = get_rpm_rel_inst($dist_rpm);
        } else {
          $dist_rpm = "unsupported";
        }
    }
}
else {
    $dist_rpm = "unsupported";
}
chomp $dist_rpm;

#
# logging
#
my $ofedlogs = "$TMPDIR/$PACKAGE.$$.logs";
mkpath([$ofedlogs]);
my $glog = "$ofedlogs/general.log";
rmtree $glog;
open(GLOG, ">$glog") or die "Can't open $glog: $!\n";
close(GLOG);

sub print_and_log
{
    my $msg = shift @_;
    my $verb = shift @_;

    open(GLOG, ">>$glog") or die "Can't open $glog: $!\n";
    print GLOG "$msg";
    close(GLGO);

    if ($verb) {
        print "$msg";
    }
}

sub print_and_log_colored
{
    my $msg = shift @_;
    my $verb = shift @_;
    my $color = shift @_;

    open(GLOG, ">>$glog") or die "Can't open $glog: $!\n";
    print GLOG "$msg\n";
    close(GLGO);

    if ($verb) {
        if ($color eq "RED") {
            print RED "$msg", RESET "\n";
        } elsif ($color eq "YELLOW") {
            print YELLOW "$msg", RESET "\n";
        } elsif ($color eq "GREEN") {
            print GREEN "$msg", RESET "\n";
        } else {
            print "$msg\n";
        }
    }
}

print_and_log("Install command: $CMD\n", 0);

my $rpm_distro = '';

# don't auto-detect distro if it's provided by the user.
if ($DISTRO eq "") {
    print_and_log("Distro was not provided, trying to auto-detect the current distro...\n", $verbose2);
    print_and_log("dist_rpm: $dist_rpm\n", $verbose2);

    if ($dist_rpm =~ /openSUSE-release-11.2/) {
        $DISTRO = "openSUSE11.2";
        $rpm_distro = "opensuse11sp2";
    } elsif ($dist_rpm =~ /openSUSE-release-12.1/) {
        $DISTRO = "openSUSE12.1";
        $rpm_distro = "opensuse12sp1";
    } elsif ($dist_rpm =~ /openSUSE-release-20151203-1.1/) {
        $DISTRO = "openSUSE_TUMBLEWEED";
        $rpm_distro = "opensuse_tumbleweed";
    } elsif ($dist_rpm =~ /openSUSE/) {
        $DISTRO = "openSUSE";
        $rpm_distro = "opensuse11sp0";
    } elsif ($dist_rpm =~ /sles-release-(1[\d])(|\.([\d]))-/) {
        # example: dist_rpm: "sles-release-15.1-39.1"
        #                    "sles-release-12-1.377"
        my $sp = $2? $3 : "0";
        $DISTRO = "SLES$1";               # "SLES15"
        $rpm_distro = "sles${1}sp${sp}";  # "sles15sp1"
    } elsif ($dist_rpm =~ /sles-release-12\.4|SLES.*release-12\.4/) {
        $DISTRO = "SLES12";
        $rpm_distro = "sles12sp4";
    } elsif ($dist_rpm =~ /sles-release-12\.3|SLES.*release-12\.3/) {
        $DISTRO = "SLES12";
        $rpm_distro = "sles12sp3";
    } elsif ($dist_rpm =~ /sles-release-12\.2|SLES.*release-12\.2/) {
        $DISTRO = "SLES12";
        $rpm_distro = "sles12sp2";
    } elsif ($dist_rpm =~ /sles-release-12\.1|SLES.*release-12\.1/) {
        $DISTRO = "SLES12";
        $rpm_distro = "sles12sp1";
    } elsif ($dist_rpm =~ /sles-release-12|SLES.*release-12/) {
        $DISTRO = "SLES12";
        $rpm_distro = "sles12sp0";
    } elsif ($dist_rpm =~ /sles-release-11.4|SLES.*release-11.4/) {
        $DISTRO = "SLES11";
        $rpm_distro = "sles11sp4";
    } elsif ($dist_rpm =~ /sles-release-11.3|SLES.*release-11.3/) {
        $DISTRO = "SLES11";
        $rpm_distro = "sles11sp3";
    } elsif ($dist_rpm =~ /sles-release-11.2|SLES.*release-11.2/) {
        $DISTRO = "SLES11";
        $rpm_distro = "sles11sp2";
    } elsif ($dist_rpm =~ /sles-release-11.1|SLES.*release-11.1/) {
        $DISTRO = "SLES11";
        $rpm_distro = "sles11sp1";
    } elsif ($dist_rpm =~ /sles-release-11/) {
        $DISTRO = "SLES11";
        $rpm_distro = "sles11sp0";
    } elsif ($dist_rpm =~ /sles-release-10-15.45.8/) {
        $DISTRO = "SLES10";
        $rpm_distro = "sles10sp3";
    } elsif ($dist_rpm =~ /sles-release-10-15.57.1/) {
        $DISTRO = "SLES10";
        $rpm_distro = "sles10sp4";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.0|centos-release-6-0/) {
        $DISTRO = "RHEL6.0";
        $rpm_distro = "rhel6u0";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.1[.-]|sl-release-6.1[.-]|centos-release-6-1[.-]/) {
        $DISTRO = "RHEL6.1";
        $rpm_distro = "rhel6u1";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.2|sl-release-6.2|centos-release-6-2/) {
        $DISTRO = "RHEL6.2";
        $rpm_distro = "rhel6u2";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.3|sl-release-6.3|centos-release-6-3/) {
        $DISTRO = "RHEL6.3";
        $rpm_distro = "rhel6u3";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.4|sl-release-6.4|centos-release-6-4/) {
        $DISTRO = "RHEL6.4";
        $rpm_distro = "rhel6u4";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.5|sl-release-6.5|centos-release-6-5/) {
        $DISTRO = "RHEL6.5";
        $rpm_distro = "rhel6u5";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.6|sl-release-6.6|centos-release-6-6/) {
        $DISTRO = "RHEL6.6";
        $rpm_distro = "rhel6u6";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.7|sl-release-6.7|centos-release-6-7/) {
        $DISTRO = "RHEL6.7";
        $rpm_distro = "rhel6u7";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.8|sl-release-6.8|centos-release-6-8/) {
        $DISTRO = "RHEL6.8";
        $rpm_distro = "rhel6u8";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.9|sl-release-6.9|centos-release-6-9/) {
        $DISTRO = "RHEL6.9";
        $rpm_distro = "rhel6u9";
    } elsif ($dist_rpm =~ /redhat-release-.*-6.10|sl-release-6.10|centos-release-6-10/) {
        $DISTRO = "RHEL6.10";
        $rpm_distro = "rhel6u10";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.0|sl-release-7.0|centos-release-7-0/) {
        $DISTRO = "RHEL7.0";
        $rpm_distro = "rhel7u0";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.1[.-]|sl-release-7.1[.-]|centos-release-7-1[.-]/) {
        $DISTRO = "RHEL7.1";
        $rpm_distro = "rhel7u1";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.2|sl-release-7.2|centos-release-7-2/) {
        $DISTRO = "RHEL7.2";
        $rpm_distro = "rhel7u2";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.3|sl-release-7.3|centos-release-7-3/) {
        $DISTRO = "RHEL7.3";
        $rpm_distro = "rhel7u3";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.4.*el7a|sl-release-7.4.*el7a|centos-release-7-4.*el7.centos.a/) {
        $DISTRO = "RHEL7.4ALTERNATE";
        $rpm_distro = "rhel7u4alternate";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.5.*el7a|sl-release-7.5.*el7a|centos-release-7-5.*el7.centos.a/) {
        $DISTRO = "RHEL7.5ALTERNATE";
        $rpm_distro = "rhel7u5alternate";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.6.*el7a|sl-release-7.6.*el7a|centos-release-7-6.*el7.centos.a/) {
        $DISTRO = "RHEL7.6ALTERNATE";
        $rpm_distro = "rhel7u6alternate";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.4|sl-release-7.4|centos-release-7-4/) {
        $DISTRO = "RHEL7.4";
        $rpm_distro = "rhel7u4";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.5|sl-release-7.5|centos-release-7-5/) {
        $DISTRO = "RHEL7.5";
        $rpm_distro = "rhel7u5";
    } elsif ($dist_rpm =~ /redhat-release-.*-7.6|sl-release-7.6|centos-release-7-6/) {
        $DISTRO = "RHEL7.6";
        $rpm_distro = "rhel7u6";
        if ($kernel =~ /^4\.14.*el7/) {
            $DISTRO = "RHEL7.6ALTERNATE";
            $rpm_distro = "rhel7u6alternate";
        }
    } elsif ($dist_rpm =~ /redhat-release-.*-7.7|sl-release-7.7|centos-release-7-7/) {
        $DISTRO = "RHEL7.7";
        $rpm_distro = "rhel7u7";
    } elsif ($dist_rpm =~ /(redhat|centos)-release-8\.([0-1])-/) {
        $DISTRO = "RHEL8.$2";
        $rpm_distro = "rhel8u$2";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-1\./) {
        $DISTRO = "OL6.1";
        $rpm_distro = "ol6u1";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-2/) {
        $DISTRO = "OL6.2";
        $rpm_distro = "ol6u2";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-3/) {
        $DISTRO = "OL6.3";
        $rpm_distro = "ol6u3";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-4/) {
        $DISTRO = "OL6.4";
        $rpm_distro = "ol6u4";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-5/) {
        $DISTRO = "OL6.5";
        $rpm_distro = "ol6u5";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-6/) {
        $DISTRO = "OL6.6";
        $rpm_distro = "ol6u6";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-7/) {
        $DISTRO = "OL6.7";
        $rpm_distro = "ol6u7";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-8/) {
        $DISTRO = "OL6.8";
        $rpm_distro = "ol6u8";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-9/) {
        $DISTRO = "OL6.9";
        $rpm_distro = "ol6u9";
    } elsif ($dist_rpm =~ /oraclelinux-release-6.*-10/) {
        $DISTRO = "OL6.10";
        $rpm_distro = "ol6u10";
    } elsif ($dist_rpm =~ /oraclelinux-release-7.([0-7])/) {
        $DISTRO = "OL7.$1";
        $rpm_distro = "ol7u$1";
    } elsif ($dist_rpm =~ /oraclelinux-release-8.([0])/) {
        $DISTRO = "OL8.$1";
        $rpm_distro = "ol8u$1";
    } elsif ($dist_rpm =~ /redhat-release-.*-5.8|centos-release-5-8|enterprise-release-5-8/) {
        $DISTRO = "RHEL5.8";
        $rpm_distro = "rhel5u8";
    } elsif ($dist_rpm =~ /centos-release-5-10.el5.centos/) {
        $DISTRO = "XenServer6.5";
        $rpm_distro = "xenserver6u5";
    } elsif ($dist_rpm =~ /xenserver-release-7.2.0/) {
        $DISTRO = "XenServer7.2";
        $rpm_distro = "xenserver7u2";
    } elsif ($dist_rpm =~ /xenserver-release-7.1.0/) {
        $DISTRO = "XenServer7.1";
        $rpm_distro = "xenserver7u1";
    } elsif ($dist_rpm =~ /xenserver-release-7.0.0/) {
        $DISTRO = "XenServer7.0";
        $rpm_distro = "xenserver7u0";
    } elsif ($dist_rpm =~ /redhat-release-.*-5.7|centos-release-5-7|enterprise-release-5-7/) {
        if ($kernel =~ /xs/) {
            $DISTRO = "XenServer6.2";
            $rpm_distro = "xenserver6u2";
        } else {
            $DISTRO = "RHEL5.7";
            $rpm_distro = "rhel5u7";
        }
    } elsif ($dist_rpm =~ /redhat-release-.*-5.6|centos-release-5-6|enterprise-release-5-6/) {
        $DISTRO = "RHEL5.6";
        $rpm_distro = "rhel5u6";
    } elsif ($dist_rpm =~ /redhat-release-.*-5.5|centos-release-5-5|enterprise-release-5-5/) {
        system("grep -wq XenServer /etc/issue > /dev/null 2>&1");
        my $res = $? >> 8;
        my $sig = $? & 127;
        if ($sig or $res) {
            $DISTRO = "RHEL5.5";
            $rpm_distro = "rhel5u5";
        } else {
            $DISTRO = "XenServer5.6";
            $rpm_distro = "xenserver5u6";
        }
    } elsif ($dist_rpm =~ /redhat-release-.*-5.4|centos-release-5-4/) {
        $DISTRO = "RHEL5.4";
        $rpm_distro = "rhel5u4";
    } elsif ($dist_rpm =~ /redhat-release-.*-5.3|centos-release-5-3/) {
        $DISTRO = "RHEL5.3";
        $rpm_distro = "rhel5u3";
    } elsif ($dist_rpm =~ /redhat-release-.*-5.2|centos-release-5-2/) {
        $DISTRO = "RHEL5.2";
        $rpm_distro = "rhel5u2";
    } elsif ($dist_rpm =~ /redhat-release-4AS-9/) {
        $DISTRO = "RHEL4.8";
        $rpm_distro = "rhel4u8";
    } elsif ($dist_rpm =~ /redhat-release-4AS-8/) {
        $DISTRO = "RHEL4.7";
        $rpm_distro = "rhel4u7";
    } elsif ($dist_rpm =~ /fedora-release-(\d+)/ and
            ($1 >= 12) and ($1 <= 29)) {
        $DISTRO = "FC$1";
        $rpm_distro = "fc$1";
    } elsif ($dist_rpm =~ /base-files-3.0/) {
        system("grep -q \"Bluenix 1.0\" /etc/issue > /dev/null 2>&1");
        my $res = $? >> 8;
        my $sig = $? & 127;
        if ($sig or $res) {
            $DISTRO = "WINDRIVER6.0";
            $rpm_distro = "windriver6u0";
        } else {
            $DISTRO = "BLUENIX1.0";
            $rpm_distro = "bluenix1u0";
        }
    } elsif ($dist_rpm =~ /ibm_powerkvm-release-3.1.0/) {
        $DISTRO = "POWERKVM3.1.0";
        $rpm_distro = "powerkvm3u1u0";
    } elsif ($dist_rpm =~ /ibm_powerkvm-release-3.1.1/) {
        $DISTRO = "POWERKVM3.1.1";
        $rpm_distro = "powerkvm3u1u1";
    } elsif ($dist_rpm =~ /euleros-release-2.0SP([2358])/) {
        my $sp = $1;
        $DISTRO = "EULEROS2.0SP${sp}";
        $rpm_distro = "euleros2u0sp${sp}";
    } else {
        $DISTRO = "unsupported";
        $rpm_distro = "unsupported";
        print_and_log_colored("Current operation system is not supported!", 1, "RED");
        exit 1;
    }

    print_and_log("Auto-detected $DISTRO distro.\n", $verbose2);
} else {
    print_and_log("Using provided distro: $DISTRO\n", $verbose2);

    $rpm_distro = $DISTRO;
    $rpm_distro = lc($rpm_distro);
    $rpm_distro =~ s/\./u/g;

    $DISTRO = uc ($DISTRO);
    if ($DISTRO =~ /SLES/) {
        $DISTRO =~ s/SP.*//g;
    } elsif ($DISTRO =~ /OPEN/) {
        $DISTRO =~ s/OPEN/open/g;
    }
}

my $SRPMS = $CWD . '/' . 'SRPMS/';
chomp $SRPMS;
my $RPMS  = $CWD . '/' . 'RPMS' . '/' . $dist_rpm . '/' . $arch;
chomp $RPMS;
if (not -d $RPMS) {
    mkpath([$RPMS]);
}

my $target_cpu  = `rpm --eval '%{_target_cpu}'`;
chomp $target_cpu;

my $target_cpu32;
if ($arch eq "x86_64") {
    if (-e "/etc/SuSE-release") {
        $target_cpu32 = 'i586';
    } elsif ($DISTRO =~ /XenServer/) {
        $target_cpu32 = 'i386';
    } else {
        $target_cpu32 = 'i686';
    }
}
elsif ($arch eq "ppc64") {
    $target_cpu32 = 'ppc';
}
chomp $target_cpu32;

if (not supported32bit()) {
    $build32=0;
}

if ($update and $build32) {
    print_and_log_colored("Update is not supported for 32-bit libraries.", 1, "RED");
    exit $ENOSPC if (not $force);
    print_and_log_colored("Disabling update. The previous version will be removed...", 1, "YELLOW");
    $update = 0;
}

$uninstall = 0 if ($update or $build_only);
$rpminstall_parameter = "-UF" if ($update);

if ($kernel_given and not $kernel_source_given) {
    if (-d "/lib/modules/$kernel/build") {
        $kernel_sources = "/lib/modules/$kernel/build";
    }
    else {
        print_and_log_colored("Provide path to the kernel sources for $kernel kernel.", 1, "RED");
        exit 1;
    }
}

my $kernel_rel = $kernel;
$kernel_rel =~ s/-/_/g;

if ($DISTRO =~ m/WINDRIVER6|BLUENIX1/) {
    $rpmbuild_flags .= ' --nodeps';
    $rpminstall_flags .= ' --nodeps';
}

if (not $check_linux_deps) {
    $rpmbuild_flags .= ' --nodeps';
    $rpminstall_flags .= ' --nodeps';
}
my $optflags  = `rpm --eval '%{optflags}'`;
chomp $optflags;

my $mandir      = `rpm --eval '%{_mandir}'`;
chomp $mandir;
my $sysconfdir  = "/etc";
chomp $sysconfdir;
my %main_packages = ();
my @selected_packages = ();
my @selected_by_user = ();
my @selected_modules_by_user = ();
my @packages_to_uninstall = ();
my @dependant_packages_to_uninstall = ();
my %selected_for_uninstall = ();
my %non_ofed_for_uninstall = ();
my @selected_kernel_modules = ();

my $ibutils_prefix = '/opt/ibutils';
my $ibutils2_prefix = '/usr';
my $compiler = "gcc";

my $infiniband_diags_compat = 'infiniband-diags-compat';
my $infiniband_diags_guest = 'infiniband-diags-guest';
my $fca = "fca";

if ($install_option eq 'guest-os') {
    $rpminstall_flags .= ' --nodeps ';
}

if ($DISTRO =~ /SLES|SUSE/) {
    $package_manager = "zypper";
} elsif ($DISTRO =~ /BLUENIX/) {
    $package_manager = "smart";
} else {
    $package_manager = "yum";
}

my $pmi_opt = '';
#if (is_installed("slurm")) {
#    $pmi_opt = '--with-pmi';
#}

my $gcc = "gcc";
my $gcc_cpp = "gcc-c++";
my $libstdc = '';
my $libgcc = 'libgcc';
my $libgfortran = '';
my $fortran = 'gcc-gfortran';
my $curl_devel = 'curl-devel';
my $libnl_devel = 'libnl-devel';
my $libnl3_devel = 'libnl3-devel';
my $libdb_devel = 'libdb-devel';
my $elfutils_devel = 'elfutils-devel';
my $kernel_elfutils_devel = 'elfutils-libelf-devel';
my $iptables_devel = 'iptables-devel';
my $libmnl = 'libmnl';
my $libnl = 'libnl';
my $libnl3 = 'libnl3';
my $glib2 = 'glib2';
my $glib2_devel = 'glib2-devel';
my $glibc_devel = 'glibc-devel';
my $openssl_devel = 'openssl-devel';
my $openssl = 'openssl';
my $libcurl = 'libcurl';
my $python = "python";
my $python_devel = "python-devel";
my $python_cython = "";
my $cairo = "cairo";
my $atk = "atk";
my $gtk2 = "gtk2";
my $pkgconfig = "pkgconfig";
my $tcl_devel = 'tcl-devel';
my $zlib_devel = 'zlib-devel';
my $java = 'java-1.8.0-openjdk';
my $java_devel = 'java-1.8.0-openjdk-devel';

if ($DISTRO eq "openSUSE_TUMBLEWEED") {
    $libstdc = 'libstdc++6';
    $pkgconfig = "python-pkgconfig";
    $libgcc = 'libgcc_s1';
    $glib2 = "glib2-tools";
} elsif ($DISTRO eq "openSUSE11.2") {
    $libstdc = 'libstdc++44';
    $libgcc = 'libgcc44';
    $libgfortran = 'libgfortran44';
    $libcurl = "libcurl4";
    $pkgconfig = "pkg-config";
} elsif ($DISTRO eq "openSUSE12.1") {
    $libstdc = 'libstdc++46';
    $libgcc = 'libgcc46';
    $libgfortran = 'libgfortran46';
    $fortran = 'libgfortran46';
    $curl_devel = 'libcurl-devel';
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3-200';
    $glib2 = "glib2-tools";
    $libcurl = "libcurl4";
    $pkgconfig = "pkg-config";
} elsif ($DISTRO eq "openSUSE") {
    $libstdc = 'libstdc++42';
    $libgcc = 'libgcc42';
    $libcurl = "libcurl4";
    $pkgconfig = "pkg-config";
} elsif ($DISTRO =~ /UBUNTU/) {
    $libstdc = 'libstdc++6';
    $libgfortran = 'libgfortran3';
} elsif ($DISTRO =~ m/SLES11/) {
    $libstdc = 'libstdc++43';
    $libgcc = 'libgcc43';
    $libgfortran = 'libgfortran43';
    $curl_devel = 'libcurl-devel';
    if ($rpm_distro eq "sles11sp2") {
        $libstdc = 'libstdc++46';
        $libgcc = 'libgcc46';
        $libgfortran = 'libgfortran46';
    }
    $fortran = "gcc-fortran";
    $openssl_devel = 'libopenssl-devel';
    $openssl = 'libopenssl0_9_8';
    $libcurl = "libcurl4";
    $pkgconfig = "pkg-config";
    $libdb_devel = 'libdb-4_5-devel';
    $elfutils_devel = 'libelf-devel';
    $kernel_elfutils_devel = 'libelf-devel';
    if ($rpm_distro =~ "sles11sp[4-9]") {
        $iptables_devel = 'libxtables-devel';
    }
    $libmnl = 'libmnl0';
} elsif ($DISTRO =~ m/SLES12/) {
    $libstdc = 'libstdc++6';
    $libgcc = 'libgcc_s1';
    $libgfortran = 'libgfortran3';
    $curl_devel = 'libcurl-devel';
    $fortran = "gcc-fortran";
    $openssl_devel = 'libopenssl-devel';
    $openssl = 'libopenssl1_0_0';
    $libcurl = "libcurl4";
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3-200';
    $glib2 = 'libglib-2_0-0';
    $cairo = "libcairo2";
    $atk = "libatk-1_0-0";
    $gtk2 = "libgtk-2_0-0";
    $pkgconfig = "pkg-config";
    $java = "java-1_8_0-openjdk";
    $java_devel = "java-1_8_0-openjdk-devel";
    $libdb_devel = 'libdb-4_8-devel';
    $elfutils_devel = 'libelf-devel';
    $kernel_elfutils_devel = 'libelf-devel';
    $iptables_devel = 'libxtables-devel';
    $libmnl = 'libmnl0';
} elsif ($DISTRO =~ m/SLES15/) {
    $libstdc = 'libstdc++6-devel-gcc7';
    $libgcc = 'libgcc_s1';
    $curl_devel = 'libcurl-devel';
    $fortran = "gcc-fortran";
    $openssl_devel = 'libopenssl-devel';
    $openssl = 'libopenssl1_1';
    $libcurl = "libcurl4";
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3-200';
    $glib2 = 'libglib-2_0-0';
    $cairo = "libcairo2";
    $atk = "libatk-1_0-0";
    $gtk2 = "libgtk-2_0-0";
    $pkgconfig = "pkg-config";
    $java = "java-1_8_0-openjdk";
    $java_devel = "java-1_8_0-openjdk-devel";
    $libdb_devel = 'libdb-4_8-devel';
    $elfutils_devel = 'libelf-devel';
    $kernel_elfutils_devel = 'libelf-devel';
    $libmnl = 'libmnl0';
    $iptables_devel = 'libxtables-devel';
    $libgfortran = "libgfortran4";
} elsif ($DISTRO =~ m/RHEL|OL|FC|POWERKVM|EULEROS/) {
    $libstdc = 'libstdc++';
    $libgcc = 'libgcc';
    $libgfortran = 'gcc-gfortran';
    if ($DISTRO =~ m/RHEL6|RHEL7|OL6|OL7|FC|POWERKVM|EULEROS/) {
        $curl_devel = 'libcurl-devel';
    }
    if ($DISTRO =~ /FC19|FC[2-9]|OL[7-9]|RHEL[7-9]|POWERKVM|EULEROS/) {
        $openssl = 'openssl-libs';
    }
    if ($DISTRO =~ /RHEL6\.|OL6\./) {
        $libdb_devel = 'db4-devel';
    }
    if ($DISTRO =~ m/EULEROS/) {
        $libnl_devel = 'libnl3-devel';
    }
}else {
    $libstdc = 'libstdc++';
}

if ($DISTRO =~ /(SLES|openSUSE)1[25] | openSUSE_TUMBLEWEED/x) {
    $libnl3 = 'libnl3-200';
}

my $libstdc_devel = ($DISTRO =~ m/UBUNTU/)?"libstdc++6-4.4-dev":"$libstdc-devel";
my $libexpat = "expat";
my $libexpat_devel = "";
my $tk = "tk";
my $insserv_compat = "";

if ($DISTRO =~ m/SLES11/) {
    $libexpat_devel = "libexpat-devel";
} elsif ($DISTRO =~ m/SLES12/) {
    $libstdc_devel = 'libstdc++-devel';
} elsif ($DISTRO =~ m/SLES15/){
    $libstdc_devel = "libstdc++6-devel-gcc7";
    $insserv_compat = "insserv-compat";
} elsif ($DISTRO eq "openSUSE_TUMBLEWEED") {
    $libstdc_devel = 'libstdc++6-devel-gcc5';
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3-200';
} elsif ($DISTRO =~ m/RHEL5.[4-6]|RHEL6|RHEL7|OL6|OL7|EULEROS/) {
    $libexpat_devel = "expat-devel";
} elsif ($DISTRO =~ m/RHEL5.3/) {
    $libexpat_devel = "expat-devel";
} elsif ($DISTRO =~ m/SLES10/) {
    $libexpat_devel = "expat";
} elsif ($DISTRO =~ m/WINDRIVER6/) {
    $gcc = "toolchain-wrappers";
    $gcc_cpp = "toolchain-wrappers";
    $python = "python-core";
    $python_devel = "python-dev";
    $libgcc = 'libgcc1';
    $libnl_devel = 'libnl-3-dev';
    $libnl = 'libnl-3-200';
    $libstdc = "libstdc++6";
    $libstdc_devel = "libstdc++-dev";
    $libexpat = "libexpat1";
    $libexpat_devel = "libexpat-dev";
    $tk = "";
    $curl_devel = 'curl-dev';
    $glib2 = 'libglib-2.0-0';
    $glib2_devel = 'libglib-2.0-dev';
    $glibc_devel = 'libc6-dev';
    $tcl_devel = 'tcl-dev';
    $zlib_devel = 'libz-dev';
} elsif ($DISTRO =~ m/POWERKVM|FC2[2-9]/) {
    $libexpat_devel = "expat-devel";
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3';
} elsif ($DISTRO =~ m/BLUENIX1/) {
    $gcc_cpp = "g++";
    $python = "python-core";
    $python_devel = "python-dev";
    $libgcc = 'libgcc1';
    $libnl_devel = 'libnl-3-dev';
    $libnl = 'libnl-3-200';
    $libstdc = "libstdc++6";
    $libstdc_devel = "libstdc++-dev";
    $libexpat = "libexpat1";
    $libexpat_devel = "libexpat-dev";
    $tk = "";
    $curl_devel = 'curl-dev';
    $glib2 = 'libglib-2.0-0';
    $glib2_devel = 'libglib-2.0-dev';
    $glibc_devel = 'libc6-dev';
    $tcl_devel = 'tcl-dev';
    $zlib_devel = 'libz-dev';
} else {
    $libexpat_devel = "expat-devel";
}

if ($DISTRO =~ /SLES/) {
    $add_debuginfo_macros = 1;
    set_rpm_macros_path();
    $rpmbuild_flags .= "--macros='$rpm_macros_path'";
}

my $libudev = "libudev";
my $libudev_devel = "libudev-devel";
if ($DISTRO =~ m/SLES11/) {
    $libudev = "libudev0";
} elsif ($DISTRO =~ m/SLES12|SLES15/) {
    $libudev = "libudev1";
} elsif ($DISTRO =~ m/RHEL[78]|OL[78]|FC|EULEROS|POWERKVM/) {
    $libudev = "systemd-libs";
    $libudev_devel = "systemd-devel";
} elsif ($DISTRO =~ m/WINDRIVER6/) {
    $libudev = "libudev0";
    $libudev_devel = "udev-dev";
} elsif ($DISTRO =~ m/BLUENIX1|XenServer/) {
    $libudev = "";
    $libudev_devel = "";
}

if ($DISTRO =~ m/FC2[6-9]/) {
    $python = "python3";
    $python_devel = "python3-devel";
    $python_cython = "python3-Cython";
    $pkgconfig = "pkgconf-pkg-config";
}

if ($DISTRO =~ m/RHEL8 | OL8/x) {
    $python = "python36";
    $python_devel = "python36-devel";
    $python_cython = "python3-Cython";
    $pkgconfig = "pkgconf-pkg-config";
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3';
}

if ($DISTRO =~ m/EULEROS2.0SP8/x) {
    $python = "python2";
    $python_devel = "python2-devel";
    $python_cython = "";
    $pkgconfig = "pkgconf-pkg-config";
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3';
}

# build with libnl3 on RHEL7, the libnl3-devel here comes from Optional packages
if ($DISTRO =~ m/RHEL7|OL7/) {
    $libnl_devel = 'libnl3-devel';
    $libnl = 'libnl3';
}

my $valgrind_devel = (($DISTRO =~ m/RHEL/ and not $disable_valgrind) or $with_valgrind) ? "valgrind-devel" : "";

# Suffix for 32 and 64 bit packages
my $is_suse_suff64 = $arch eq "ppc64" && $DISTRO !~ /SLES11|SLES12/;
my $suffix_32bit = ($DISTRO =~ m/SLES|openSUSE/ && !$is_suse_suff64) ? "-32bit" : ".$target_cpu32";
my $suffix_64bit = ($DISTRO =~ m/SLES|openSUSE/ &&  $is_suse_suff64) ? "-64bit" : "";

sub usage
{
   print GREEN;
   print "\n";
   print "Usage: $0 [-c <packages config_file>|--all|--hpc|--vma|--basic|--bluefield] [OPTIONS]\n";

   print "\n";
   print "Installation control:\n";
   print "    --force              Force installation\n";
   print "    --tmpdir             Change tmp directory. Default: $TMPDIR\n";
   print "    -l|--prefix          Set installation prefix\n";
   print "    -k|--kernel <version>\n";
   print "                         Default on this system: $kernel\n";
   print "    -s|--kernel-sources <path>\n";
   print "                         Default on this system: $kernel_sources\n";
   print "    -U|--update          Update installed version\n";
   print "    -b|--build-only      Build binary RPMs without installing them\n";
   print "                         - This option is supported only when '--kernel-only' option is given.\n";
   print "    --build32            Build 32-bit libraries. Relevant for x86_64 platforms\n";
   print "    --distro             Set Distro name for the running OS (e.g: rhel6.5, sles11sp3)\n";
   print "                         Default: Use auto-detection\n";
   print "    --without-depcheck   Run the installation without verifying that all required Distro's packages are installed\n";
   print "    --check-deps-only    Check for missing required Distro's packages and exit\n";
   print "    --disable-kmp        Build kernel RPMs without KMP support\n";
   print "    --speed-up-kmp       Speed up KMP RPMs installation by skipping %post section and running the required operations once for all KMPs\n";
   print "    --builddir           Change build directory. Default: $builddir\n";
   print "    --umad-dev-rw        Grant non root users read/write permission for umad devices instead of default\n";
   print "    --umad-dev-na        Prevent from non root users read/write access for umad devices. Overrides '--umad-dev-rw'\n";
   print "    --enable-mlnx_tune   Enable Running the mlnx_tune utility\n";
   print "    --enable-opensm      Run opensm upon boot\n";
   print "\n";
   print "    --package-install-options\n";
   print "                         RPM install options to use when installing RPM packages (comma separated list)\n";
   print "    --pre-build-<package> <path to script>\n";
   print "                         Run given script before given package's build\n";
   print "    --post-build-<package> <path to script>\n";
   print "                         Run given script after given package's build\n";
   print "    --pre-install-<package> <path to script>\n";
   print "                         Run given script before given package's install\n";
   print "    --post-install-<package> <path to script>\n";
   print "                         Run given script after given package's install\n";
   print "\n";
   print "Package selection:\n";
   print "    -c|--config <packages config_file>\n";
   print "                         Example of the config file can be found under docs (ofed.conf-example)\n";
if (not $install_option eq 'eth-only') {
   print "    --all                Install all available packages\n";
   print "    --bluefield          Install BlueField packages\n";
   print "    --hpc                Install minimum packages required for HPC\n";
   print "    --basic              Install minimum packages for basic functionality\n";
} else {
   print "    --eth-only           Install Ethernet drivers only\n";
}
   print "    --dpdk               Install minimum packages required for DPDK\n";
if (not $install_option eq 'eth-only') {
   print "    --with-vma           Enable installing and configuring VMA package (to be used with any of the above installation options)\n";
}
   print "    --vma|--vma-vpi      Install minimum packages required by VMA to support VPI\n";
   print "    --vma-eth            Install minimum packages required by VMA to work over Ethernet\n";
if (not $install_option eq 'eth-only') {
   print "    --guest              Install minimum packages required by guest OS\n";
   print "    --hypervisor         Install minimum packages required by hypervisor OS\n";
   print "    --with-fabric-collector\n";
   print "                         Enable installing fabric-collector package\n";
   print "    --with-libdisni      Install the libdisni package - Java interface to ib_verbs\n";
   print "                         see https://github.com/zrlio/disni for more information\n";
   print "User-Space and libraries selection:\n";
   print "    --upstream-libs      Install Upstream libraries (rdma-core).\n";
}
   print "Extra package filtering:\n";
if (not $install_option eq 'eth-only') {
   print "    --kernel-only        Install kernel space packages only\n";
   print "    --user-space-only    Filter selected packages and install only User Space packages\n";
}
   print "    --without-<package>  Do not install package\n";
   print "    --with-<package>     Force installing package\n";
   print "    --with-memtrack      Build ofa_kernel RPM with memory tracking enabled for debugging\n";
   print "\n";
   print "Miscellaneous:\n";
   print "    -h|--help            Display this help message and exit\n";
   print "    -p|--print-available Print available packages for current platform\n";
   print "                         And create corresponding ofed.conf file\n";
   print "    --conf-dir           Destination directory to save the configuration file\n";
   print "                         Default: $CWD\n";
   print "\n";
   print "Output control:\n";
   print "    -v|-vv|-vvv          Set verbosity level\n";
   print "    -q                   Set quiet - no messages will be printed\n";
   print RESET "\n\n";
}

my $sysfsutils;
my $sysfsutils_devel;

if ($DISTRO =~ m/SLES|openSUSE/) {
    $sysfsutils = "sysfsutils";
    $sysfsutils_devel = "sysfsutils";
} elsif ($DISTRO =~ m/RHEL5/) {
    $sysfsutils = "libsysfs";
    $sysfsutils_devel = "libsysfs";
} elsif ($DISTRO =~ m/RHEL6|RHEL7|OL6|OL7|POWERKVM|EULEROS2.0SP[235]/) {
    $sysfsutils = "libsysfs";
    $sysfsutils_devel = "libsysfs";
} elsif ($DISTRO =~ m/BLUENIX1/) {
    $sysfsutils = "sysfsutils";
    $sysfsutils_devel = "sysfsutils-dev"
}

my $kernel_req = "";
my $kernel_devel = "kernel-devel-$kernel";
if ($DISTRO =~ /RHEL8 | OL8 | EULEROS2.0SP8 | FC29 | FC3./x) {
    $kernel_req = "kernel-rpm-macros";
} elsif ($DISTRO =~ /RHEL|OL|FC|XenServer|EULEROS2.0SP[235]/) {
    $kernel_req = "redhat-rpm-config";
} elsif ($DISTRO =~ /POWERKVM/) {
    $kernel_req = "base-rpm-config";
} elsif ($DISTRO =~ /SLES10/) {
    $kernel_req = "kernel-syms";
    $kernel_devel = "kernel-syms";
} elsif ($DISTRO =~ /SLES11|SLES12/) {
    $kernel_req = "kernel-source";
    $kernel_req = "kernel-syms";
} elsif ($DISTRO =~ /WINDRIVER6|BLUENIX1/) {
    $kernel_req = "kernel-dev";
    $kernel_devel = "kernel-dev";
}
if ($kernel =~ /uek/) {
    $kernel_devel = "kernel-uek-devel-$kernel";
}

my $network_dir;
if ($DISTRO =~ m/SLES/) {
    $network_dir = "/etc/sysconfig/network";
}
elsif ($DISTRO =~ m/BLUENIX1/) {
    $network_dir = "/etc/network";
} else {
    $network_dir = "/etc/sysconfig/network-scripts";
}

# List of packages that were included in the previous OFED releases
# for uninstall purpose
my $openvswitch = "";
if ($with_bluefield and $DISTRO =~ /RHEL7/) {
    $openvswitch = "openvswitch";
}


my @prev_ofed_packages = (
                        "kernel-ib", "kernel-ib-devel", "mlnx-ofa_kernel",
                        "mpich_mlx", "ibtsal", "openib", "opensm", "opensm-devel", "opensm-libs", "opensm-libs3",
                        "libopensmssa", "libopensmssa-debuginfo", "ibssa", "ibssa-debuginfo", "ibacm_ssa", "ibacm_ssa-devel","ibacm_ssa-debuginfo",
                        "mpi_ncsa", "mpi_osu", "thca", "ib-osm", "osm", "diags", "ibadm",
                        "ib-diags", "ibgdiag", "ibdiag", "ib-management",
                        "ib-verbs", "ib-ipoib", "ib-cm", "ib-sdp", "ib-dapl", "udapl",
                        "udapl-devel", "libdat", "libibat", "ib-kdapl", "ib-srp", "ib-srp_target",
                        "libipathverbs", "libipathverbs-devel",
                        "libehca", "libehca-devel", "dapl", "dapl-devel",
                        "libibcm", "libibcm-devel", "libibcommon", "libibcommon-devel",
                        "libibmad", "libibmad-devel", "libibumad", "libibumad-devel",
                        "libibprof",
                        "ibsim", "ibsim-debuginfo",
                        "libibverbs1", "libibverbs", "libibverbs-devel", "libibverbs-utils", "libibverbs-runtime", "libibverbs1-32bit",
                        "libipathverbs", "libipathverbs-devel", "libmthca",
                        "libmthca-devel", "libmlx4", "libmlx4-devel",
                        "librdmacm1", "librdmacm", "librdmacm-devel", "librdmacm-utils", "ibacm",
                        "openib-diags", "openib-mstflint", "openib-perftest", "openib-srptools", "openib-tvflash",
                        "openmpi", "openmpi-devel", "openmpi-libs",
                        "ibutils", "ibutils-devel", "ibutils-libs", "ibutils2", "ibutils2-devel",
                        "libnes", "libnes-devel",
                        "infinipath-psm", "infinipath-psm-devel",
                        "mellanox-firmware", "mellanox-ofed", "mlnxofed", "mft-int", "mft-oem", "kernel-mft", "mft-compat", "mlx4_accl", "mlx4_accl_sys",
                        "compat-dapl", "compat-dapl-devel",
                        "mvapich", "mvapich2",
                        "mvapich_gcc", "openmpi_gcc", "mvapich2_gcc", "mpitests_mvapich2", "mpitests_openmpi",
                        "fabric-collector", "fabric-collector-debuginfo",
                        "libsdp", "libsdp-devel", "libsdp-debuginfo",
                        "sdpnetstat-debuginfo", "sdpnetstat",
                        "intel-mic-ofed-dapl-utils",
                        "mlnx-ethtool", "mlnx-ethtool-debuginfo",
                        "mlnx-iproute2",
                        "$openvswitch", "spdk",
                        "libpka", "mlxbf-bootctl", "mlxbf-bootimages", "bfscripts", "nvme-snap",
                        "multiperf", "multiperf-debuginfo",
                        "libusnic_verbs",
                        "mlnx-fw-updater",
                        "mlnx-tools",
                        "srp_daemon",
                        "libmlx5-1",
                        "mellanox-mlnxen",
                        "libiwpm",
                        );


my $bf_krpm_regex = "(gpio-mlxbf|i2c-mlx|mlxbf-livefish|mlx-bootctl|pka-mlxbf|tmfifo|rshim|mlx-trio|mlx-l3cache|mlx-pmc)";

my @distro_ofed_packages = (
                        "libamso", "libamso-devel", "dapl2", "dapl2-devel", "mvapich", "mvapich2", "mvapich2-devel",
                        "mvapich-devel", "libboost_mpi1_36_0", "libmthca-rdmav2", "libcxgb3-rdmav2", "libcxgb4-rdmav2",
                        "libmlx4-rdmav2", "libibmad1", "libibumad1", "libibcommon1", "libibdm1", "ofed", "ofa",
                        "libibumad3", "libibmad5",
                        "rdma-ofa-agent", "rdma", "rdma-core", "rdma-core-devel", "rsocket", "libosmcomp3",
                        );

my @mlnx_en_packages = (
                       "mlnx_en", "mlnx-en-devel", "mlnx_en-devel", "mlnx_en-doc", "mlnx-ofc", "mlnx-ofc-debuginfo"
                        );

# List of all available packages sorted following dependencies
if ($kmp) {
    system("rpm -qf $kernel_sources/scripts > /dev/null 2>&1");
    my $res = $? >> 8;
    my $sig = $? & 127;
    if ($sig or $res) {
        print_and_log("KMP is not supported for kernels which were not installed as RPM.\n", $verbose2);
        $kmp = 0;
    }
}

if ($kmp and ($DISTRO =~ m/XenServer|RHEL5.2|FC|SLES10|WINDRIVER6|POWERKVM|BLUENIX1/ or $kernel =~ /xs|fbk|fc|debug|lustre/)) {
    print_and_log_colored("KMP is not supported on $DISTRO. Switching to non-KMP mode", $verbose2, "RED");
    $kmp = 0;
}

# Disable KMP for kernels incompatible with the original Distro's kernel
if ($kmp) {
    # RHEL
    if (($DISTRO eq "EULEROS2.0SP2" and $kernel !~ /3.10.0-327.*$arch/) or
        ($DISTRO eq "EULEROS2.0SP3" and $kernel !~ /3.10.0-514.*$arch/) or
        ($DISTRO eq "RHEL7.0" and $kernel !~ /3.10.0-123.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.1" and $kernel !~ /3.10.0-2.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.2" and $kernel !~ /3.10.0-3.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.3" and $kernel !~ /3.10.0-.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.4" and $kernel !~ /3.10.0-.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.4ALTERNATE" and $kernel !~ /4.11.0-.*el7a.*$arch/) or
        ($DISTRO eq "RHEL7.5" and $kernel !~ /3.10.0-.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.5ALTERNATE" and $kernel !~ /4.14.0-.*el7a.*$arch/) or
        ($DISTRO eq "RHEL7.6" and $kernel !~ /3.10.0-.*el7.*$arch/) or
        ($DISTRO eq "RHEL7.6ALTERNATE" and $kernel !~ /4.14.0-.*el7a.*$arch/) or
        ($DISTRO eq "RHEL7.7" and $kernel !~ /3.10.0-.*el7.*$arch/) or
        ($DISTRO eq "RHEL6.9" and $kernel !~ /2.6.32-[0-9][0-9][0-9].*el6.*$arch/) or
        ($DISTRO eq "RHEL6.8" and $kernel !~ /2.6.32-6[0-9][0-9].*el6.*$arch/) or
        ($DISTRO eq "RHEL6.7" and $kernel !~ /2.6.32-[0-9][0-9][0-9].*el6.*$arch/) or
        ($DISTRO eq "RHEL6.6" and $kernel !~ /2.6.32-5[0-9][0-9].*el6.*$arch/) or
        ($DISTRO eq "RHEL6.5" and $kernel !~ /2.6.32-4[0-9][0-9].*el6.*$arch/) or
        ($DISTRO eq "RHEL6.4" and $kernel !~ /2.6.32-358.*el6.*$arch/) or
        ($DISTRO eq "RHEL6.3" and $kernel !~ /2.6.32-279.*el6.*$arch/) or
        ($DISTRO eq "RHEL6.2" and $kernel !~ /2.6.32-220.*el6.*$arch/) or
        ($DISTRO eq "RHEL6.1" and $kernel !~ /2.6.32-131.*el6.*$arch/)) {
        $kmp = 0;
    }
    # SLES
    if (($rpm_distro eq "sles12sp1" and $kernel !~ /3.12.[1-9]+-[0-9].*/) or
        ($rpm_distro eq "sles12sp2" and $kernel !~ /4.4.[1-9]+-[0-9].*/) or
        ($rpm_distro eq "sles12sp3" and $kernel !~ /4.4.[0-9]+-[0-9].*/) or
        ($rpm_distro eq "sles12sp4" and $kernel !~ /4.12.[0-9]+-[0-9].*/) or
        ($rpm_distro eq "sles12sp0" and $kernel !~ /3.12.[1-9][2-9]-[0-9].*/) or
        ($rpm_distro eq "sles15sp0" and $kernel !~ /4.12.[1-9][2-9]-[0-9].*/) or
        ($rpm_distro eq "sles15sp1" and $kernel !~ /4.12.14-[0-9].*/) or
        ($rpm_distro eq "sles11sp4" and $kernel !~ /3.0.[1-9][0-9][0-9]-[0-9][0-9]|3.0.101.*-[0-9][0-9]/) or
        ($rpm_distro eq "sles11sp3" and $kernel !~ /3.0.7[6-9]-[0-9].[0-9]*|3.0.[8-9][0-9]-[0-9].[0-9]*|3.0.[1-9][0-9][0-9]-[0-9].[0-9]/) or
        ($rpm_distro eq "sles11sp2" and $kernel !~ /3\.0\.(1[3-9]|[2-8][0-9])-0\.([0-9]|27)/) or #3.0.[13-80]-0.[0-9].[1-9]
        ($rpm_distro eq "sles11sp1") ) {
        $kmp = 0;
    }
    # OpenSUSE
    if (($DISTRO eq "openSUSE12.1" and $kernel !~ /3\.1\.[0-9]/) or
        ($DISTRO eq "openSUSE_TUMBLEWEED" and $kernel !~ /4\.3\.0/)) {
        $kmp = 0;
    }
    # Oracle
    if (($DISTRO =~ /^(OL7\.[016-9] | OL6\.[1-6] | OL5\..*)$/x)
        or ($DISTRO eq "OL6.7" and $kernel !~ /3\.8\.13-68\..*el6uek/)
        or ($DISTRO eq "OL6.8" and $kernel !~ /4\.1\.12-37\..*el6uek/)
        or ($DISTRO eq "OL6.9" and $kernel !~ /4\.1\.12-61\..*el6uek/)
        or ($DISTRO eq "OL6.10" and $kernel !~ /4\.1\.12-124\..*el6uek/)
        or ($DISTRO eq "OL7.2" and $kernel !~ /3\.8\.13-92\..*el7uek/)
        or ($DISTRO eq "OL7.3" and $kernel !~ /4\.1\.12-61\..*el7uek/)
        or ($DISTRO eq "OL7.4" and $kernel !~ /4\.1\.12-94\..*el7uek/)
        or ($DISTRO eq "OL7.5" and $kernel !~ /4\.14\.35-1818\..*el7uek/)
       ) {
        $kmp = 0;
    }
}

# $speed_up_kmp is supported on RHEL only
if ($DISTRO !~ /RHEL/ or not $kmp) {
    print_and_log("WARNING: Speed up kmp is supported on RHEL only with in-box the kernel. Turning off...\n") if ($speed_up_kmp);
    $speed_up_kmp = 0;
}

# set which rpm to use for those rpms that support KMP
my $kernel_rpm;
my $knem_rpm = "knem";
my $knem_mods = "knem-modules";
my $kernel_mft_rpm;
my $ummunotify_rpm;
my $en_kernel_rpm;

if ($kmp) {
    $kernel_rpm = "mlnx-ofa_kernel";
    $knem_mods = ""; # we have KMPs instead
    $kernel_mft_rpm = "kernel-mft-mlnx";
    $ummunotify_rpm = "ummunotify-mlnx";
    $en_kernel_rpm = "mlnx-en";
} else {
    $kernel_rpm = "mlnx-ofa_kernel-modules";
    $kernel_mft_rpm = "kernel-mft";
    $ummunotify_rpm = "ummunotify";
    $en_kernel_rpm = "mlnx_en";
    # disable --bump-kmp-version flag when KMP=0
    $kmp_build_num = "";
}

# upstream vs. legacy user-space
my $dep_on_rdma_core = "";
my $COMMON_DIR = "COMMON";
my $MLNX_LIBS_DIR = "MLNX_LIBS";
my $UPSTREAM_LIBS_DIR = "UPSTREAM_LIBS";

my $infiniband_diags_parent = "infiniband-diags";

my $libibverbs_parent = "libibverbs";
my $libibverbs_devel = "libibverbs-devel";
my $libibverbs_devel_static = "libibverbs-devel-static";
my $libibverbs_debuginfo = "libibverbs-debuginfo";

my $libmlx4 = "libmlx4";
my $libmlx4_devel = "libmlx4-devel";
my $libmlx4_debuginfo = "libmlx4-debuginfo";

my $libmlx5 = "libmlx5";
my $libmlx5_devel = "libmlx5-devel";
my $libmlx5_debuginfo = "libmlx5-debuginfo";

my $librxe = "librxe";
my $librxe_devel_static = "librxe-devel-static";
my $librxe_debuginfo = "librxe-debuginfo";

my $ibacm_parent = "ibacm";

my $libibcm_parent = "libibcm";
my $libibcm_devel = "libibcm-devel";
my $libibcm_debuginfo = "libibcm-debuginfo";

my $libibmad_parent = "libibmad";
my $libibmad = "libibmad";
my $libibmad_devel = "libibmad-devel";
my $libibmad_static = "libibmad-static";
my $libibmad_debuginfo = "libibmad-debuginfo";

my $libibumad_parent = "libibumad";
my $libibumad_devel = "libibumad-devel";
my $libibumad_static = "libibumad-static";
my $libibumad_debuginfo = "libibumad-debuginfo";

my $librdmacm_parent = "librdmacm";
my $librdmacm_devel = "librdmacm-devel";
my $librdmacm_debuginfo = "librdmacm-debuginfo";

my $srptools = "srptools";

mkpath(["$RPMS/$COMMON_DIR"]);

if ($use_upstream_libs) {
    mkpath(["$RPMS/$UPSTREAM_LIBS_DIR"]);
    $dep_on_rdma_core = "rdma-core";

    $libibverbs_parent = "rdma-core";
    $libibverbs_devel = "rdma-core-devel";
    $libibverbs_devel_static = "rdma-core-devel";
    $libibverbs_debuginfo = "rdma-core-debuginfo";

    $libmlx4 = "libibverbs";
    $libmlx4_devel = "rdma-core-devel";
    $libmlx4_debuginfo = "rdma-core-debuginfo";

    $libmlx5 = "libibverbs";
    $libmlx5_devel = "rdma-core-devel";
    $libmlx5_debuginfo = "rdma-core-debuginfo";

    $librxe = "libibverbs";
    $librxe_devel_static = "rdma-core-devel";
    $librxe_debuginfo = "rdma-core-debuginfo";

    $ibacm_parent = "rdma-core";

    $libibmad_parent = "rdma-core";
    $libibmad = "rdma-core-devel";
    $libibmad_devel = "rdma-core-devel";
    $libibmad_static = "rdma-core-static";
    $libibmad_debuginfo = "rdma-core-debuginfo";

    $libibumad_parent = "rdma-core";
    $libibumad_devel = "rdma-core-devel";
    $libibumad_static = "rdma-core-static";
    $libibumad_debuginfo = "rdma-core-debuginfo";

    $librdmacm_parent = "rdma-core";
    $librdmacm_devel = "rdma-core-devel";
    $librdmacm_debuginfo = "rdma-core-debuginfo";

    $srptools = "srp_daemon";

    $infiniband_diags_parent = "rdma-core";
    $infiniband_diags_compat = 'infiniband-diags';
    $infiniband_diags_guest = 'infiniband-diags';
} else {
    mkpath(["$RPMS/$MLNX_LIBS_DIR"]);
}

my @bf_only_kernel_packages = ("gpio-mlxbf", "i2c-mlx", "mlxbf-livefish", "mlx-bootctl", "pka-mlxbf", "tmfifo", "mlx-trio", "mlx-l3cache", "mlx-pmc");
my @kernel_packages = ($kernel_rpm, "mlnx-ofa_kernel-devel", $knem_rpm, $knem_mods, "ib-bonding", "ib-bonding-debuginfo", $kernel_mft_rpm, "mlx4_accl_sys", "mlx4_accl", $ummunotify_rpm, 'iser', 'srp', 'isert', 'mlnx-sdp', 'mlnx-rds', 'mlnx-nfsrdma', 'mlnx-nvme', 'mlnx-rdma-rxe', @bf_only_kernel_packages, "rshim");
my @basic_kernel_modules = ("core", "mlxfw", "mthca", "mlx4", "mlx4_en", "mlx4_vnic", "mlx4_fc", "mlx5", "ipoib", "mlx5_fpga_tools", "mdev");
my @ulp_modules = ("sdp", "srp", "srpt", "rds", "iser", "e_ipoib", "nfsrdma", 'isert');

# kernel modules in "technology preview" status can be installed by
# adding "module=y" to the ofed.conf file in unattended installation mode
# or by selecting the module in custom installation mode during interactive installation
my @tech_preview;

my @kernel_modules = (@basic_kernel_modules, @ulp_modules);

my $kernel_configure_options = '';
my $user_configure_options = '';

my @misc_packages = ("ofed-docs", "ofed-scripts");

# The entries will be added later in add_new_mpitests_pkg function.
my @mpitests_packages = ();

my @mpi_packages = ( "mpi-selector",
                     "mvapich2",
                     "openmpi",
                     "openshmem",
                     @mpitests_packages
                    );

my @rds_packages = ( "rds-tools", "rds-devel", "rnfs-utils"
                    );

my @user_packages = ("libibverbs", "$libibverbs_devel", "$libibverbs_devel_static",
                     "libibverbs-utils", "$libibverbs_debuginfo",
                     "libmthca", "libmthca-devel-static", "libmthca-debuginfo",
                     "$libmlx4", "$libmlx4_devel", "$libmlx4_debuginfo",
                     "$libmlx5", "$libmlx5_devel", "$libmlx5_debuginfo", "libmlx5-rdmav2",
                     "$librxe", "$librxe_devel_static", "$librxe_debuginfo",
                     "libehca", "libehca-devel-static", "libehca-debuginfo",
                     "libcxgb3", "libcxgb3-devel", "libcxgb3-debuginfo",
                     "libcxgb4", "libcxgb4-devel", "libcxgb4-debuginfo",
                     "libnes", "libnes-devel-static", "libnes-debuginfo",
                     "libipathverbs", "libipathverbs-devel", "libipathverbs-debuginfo",
                     "libibcm", "$libibcm_devel", "$libibcm_debuginfo",
                     "libibumad", "$libibumad_devel", "$libibumad_static", "$libibumad_debuginfo",
                     "$libibmad", "$libibmad_devel", "$libibmad_static", "$libibmad_debuginfo",
                     "ibsim", "ibsim-debuginfo", "ibacm",
                     "librdmacm", "librdmacm-utils", "$librdmacm_devel", "$librdmacm_debuginfo",
                     "libsdp", "libsdp-devel", "libsdp-debuginfo",
                     "opensm", "opensm-libs", "opensm-devel", "opensm-debuginfo", "opensm-static",
                     "libopensmssa", "libopensmssa-debuginfo", "ibssa", "ibssa-debuginfo", "ibacm_ssa", "ibacm_ssa-devel","ibacm_ssa-debuginfo",
                     "dapl", "dapl-devel", "dapl-devel-static", "dapl-utils", "dapl-debuginfo",
                     "perftest", "multiperf", "multiperf-debuginfo", "mstflint",
                     "qlvnictools", "sdpnetstat", "sdpnetstat-debuginfo", "$srptools", @rds_packages,
                     "ibutils2", "ibutils", "cc_mgr", "dump_pr", "ar_mgr", "ibdump",
                     "infiniband-diags", "$infiniband_diags_compat", "qperf", "qperf-debuginfo", "libibnetdisc5",
                     "ofed-docs", "ofed-scripts",
                     "fca", "mxm", "bupc", "sharp", "ucx", "ucx-devel", "ucx-static",
                     "ucx-cma", "ucx-ib", "ucx-ib-cm", "ucx-rdmacm", "ucx-cuda", "ucx-gdrcopy", "ucx-knem",
                     "infinipath-psm", "infinipath-psm-devel", @mpi_packages, "libibprof", "hcoll",
                     "libvma", "libvma-utils", "libvma-devel", "libvma-debuginfo",
                     "sockperf", "sockperf-debuginfo",
                     "fabric-collector", "fabric-collector-debuginfo",
                     "mlnx-ethtool", "mlnx-ethtool-debuginfo",
                     "mlnx-iproute2",
                     "$openvswitch", "spdk",
                     "libpka", "mlxbf-bootctl", "mlxbf-bootimages", "bfscripts", "nvme-snap",
                     "libdisni", "libdisni-devel", "libdisni-debuginfo",
                     );

# List of packages that were included in the previous OFED releases
# for uninstall purpose

my @mft_packages = (
                   "mft-int", "kernel-mft", "mft-compat", "mft-oem"
                   );

my @basic_kernel_packages = ($kernel_rpm, "mlnx-ofa_kernel-devel", $kernel_mft_rpm, 'iser', 'srp', 'isert', 'mlnx-sdp', 'mlnx-rds', 'mlnx-nfsrdma', 'mlnx-nvme', 'mlnx-rdma-rxe', 'rshim');
my @basic_user_packages = ("libibverbs", "libibverbs-utils", "libmthca", "$libmlx4", "$libmlx5", "$librxe",
                            "libehca", "libcxgb3", "libcxgb4", "libnes", "libipathverbs", "librdmacm", "librdmacm-utils",
                            "mstflint", @misc_packages, "mlnx-ethtool", "mlnx-iproute2");

my @bluefield_kernel_packages = ();
if ($is_bf) {
	push(@basic_kernel_packages, @bf_only_kernel_packages);
	@bluefield_kernel_packages = (@basic_kernel_packages);
} else {
	@bluefield_kernel_packages = (@basic_kernel_packages, @bf_only_kernel_packages);
}

my @bluefield_kernel_modules = ("core", "mlxfw", "mlx5", "ipoib", "iser", "isert", "mdev");
my @bluefield_user_packages = ("libibverbs", "$libibverbs_devel", "$libibverbs_devel_static", "$libmlx5", "$libmlx5_devel", "libibverbs-utils", "librdmacm", "$librdmacm_devel", "librdmacm-utils", "ibacm", "perftest","mstflint", "infiniband-diags", "$infiniband_diags_compat", "opensm", "opensm-libs", "opensm-devel", "opensm-static", "mft", "ibutils2", "ibutils", "mlnx-ethtool", "mlnx-iproute2", "openvswitch", "libpka", "mlxbf-bootctl", "mlxbf-bootimages", "bfscripts", "nvme-snap");

my @hpc_kernel_packages = (@basic_kernel_packages, $knem_rpm, $knem_mods, "ib-bonding", "mlx4_accl_sys", "mlx4_accl", $ummunotify_rpm);
my @hpc_kernel_modules = (@basic_kernel_modules);
my @hpc_user_packages = (@basic_user_packages, "fca", "mxm", "ucx", "ucx-devel", "ucx-static", "bupc" ,"ibacm", "librdmacm",
                        "librdmacm-utils", "dapl", "dapl-devel", "dapl-devel-static", "dapl-utils",
                        "infiniband-diags", "$infiniband_diags_compat", "ibutils2", "ibutils", "cc_mgr", "dump_pr", "ar_mgr", "ibdump", "qperf", "mstflint", "perftest", "multiperf", @rds_packages, @mpi_packages, "libibprof", "hcoll", "sharp");

my @vma_kernel_packages = (@basic_kernel_packages, "ib-bonding");
my @vma_kernel_modules = (@basic_kernel_modules);
my @vmavpi_user_packages = ("libibverbs", "$libibverbs_devel", "$libibverbs_devel_static", "libibverbs-utils", "$libmlx4", "$libmlx4_devel", "$libmlx5", "$libmlx5_devel", "$librxe", "$librxe_devel_static",
                            "ibacm", "librdmacm", "$librdmacm_devel", "librdmacm-utils", "perftest", "multiperf", "mstflint", "infiniband-diags", "$infiniband_diags_compat",
                            "opensm", "opensm-libs", "opensm-devel", "opensm-static", "mft", "ibutils2", "ibutils", "ibdump", @misc_packages, "libvma", "libvma-utils", "libvma-devel", "sockperf", "mlnx-ethtool",
                            "mlnx-iproute2",
                            "libopensmssa", "ibssa", "ibacm_ssa", "ibacm_ssa-devel");
my @vma_user_packages = (@vmavpi_user_packages);
my @vmaeth_user_packages = ("libibverbs", "$libibverbs_devel", "$libibverbs_devel_static", "libibverbs-utils", "$libmlx4", "$libmlx4_devel", "$libmlx5", "$libmlx5_devel", "$librxe", "$librxe_devel_static",
                            "ibacm", "librdmacm", "$librdmacm_devel", "librdmacm-utils", "perftest", "multiperf", "mstflint", "mft", "ibutils2", "ibutils",
                            @misc_packages, "libvma", "libvma-utils", "libvma-devel", "sockperf", "mlnx-ethtool", "mlnx-iproute2");

my @hypervisor_kernel_packages = (@basic_kernel_packages);
my @guest_kernel_packages = (@basic_kernel_packages);
my @guest_kernel_modules = ("core","mlxfw","mlx5","mlx4","mlx4_en","ipoib","srp","iser", 'isert', 'mlnx-sdp', 'mlnx-rds', 'mlnx-nfsrdma', "mlx5_fpga_tools","mdev");
my @hypervisor_kernel_modules = ("core","mlxfw","mlx4","mlx4_en","mlx4_vnic","mlx5","ipoib","srp","iser", 'isert', 'mlnx-sdp', 'mlnx-rds', 'mlnx-nfsrdma', "mlx5_fpga_tools", "mdev");

my @sroiv_common_user_packages = ("udapl","ofed-scripts","libibcm","$libibcm_devel",
					"ibacm","librdmacm","librdmacm-utils","$librdmacm_devel",
					"libibverbs","$libibverbs_devel","$libibverbs_devel_static","libibverbs-utils",
					"$libmlx4","$libmlx4_devel","$libmlx5","$libmlx5_devel","libibumad","$libibumad_devel","$libibumad_static",
					"$libibmad","$libibmad_devel","$libibmad_static","perftest", "multiperf",
					"$srptools","qperf", @rds_packages, "mlnx-ethtool", "$librxe", "$librxe_devel_static");

my @hypervisor_user_packages = (@sroiv_common_user_packages,"infiniband-diags","$infiniband_diags_compat","osm","mstflint","ofed-docs",
					"dapl","dapl-devel","dapl-devel-static","dapl-utils",
					"opensm","opensm-libs","opensm-devel","opensm-static","ibutils2","ibutils",
					"libopensmssa", "ibssa", "ibacm_ssa", "ibacm_ssa-devel");

my @guest_user_packages = (@sroiv_common_user_packages,"$infiniband_diags_guest", @mpi_packages);

my @eth_kernel_packages = ($en_kernel_rpm, "mlnx-en-utils", "mlnx-en-sources", "mlnx-en-doc");
my @eth_kernel_modules = ("core", "mlxfw", "mlx4", "mlx4_en", "mlx5", "mdev");
my @eth_user_packages = ("mstflint");

my @dpdk_kernel_packages = ($kernel_rpm, "mlnx-ofa_kernel-devel");
if ($is_bf) {
	push(@dpdk_kernel_packages, @bf_only_kernel_packages);
}
my @dpdk_kernel_modules = (@kernel_modules);
my @dpdk_user_packages = ("libibverbs", "$libibverbs_devel", "$libibverbs_devel_static", "libibverbs-utils", "$libmlx4", "$libmlx4_devel", "$libmlx5", "$libmlx5_devel", "librdmacm", "$librdmacm_devel", "librdmacm-utils", "ibacm", "mstflint", "mlnx-ethtool", "mlnx-iproute2");

# all_packages is required to save ordered (following dependencies) list of
# packages. Hash does not saves the order
my @all_packages = (@kernel_packages, @user_packages);

# which modules are required for the standalone module rpms
my %standalone_kernel_modules_info = (
        'iser' => ["core", "ipoib"],
        'isert' => ["core", "ipoib"],
        'srp' => ["core", "ipoib"],
        'mlnx-sdp' => ["core"],
        'mlnx-rds' => ["core"],
        'mlnx-nfsrdma' => ["core"],
        'mlnx-nvme' => ["core"],
        'mlnx-rdma-rxe' => ["core"],
);

my @ucx_dist_build_req = (
    "$pkgconfig", "$libstdc_devel", "$gcc_cpp", "binutils-devel", "$libstdc"
);
my @ucx_ofa_build_req = ("$libibverbs_devel", "$libibcm_devel");

my %kernel_modules_info = (
        'core' =>
            { name => "core", available => 1, selected => 0,
            included_in_rpm => 0, requires => [], },
        'mlxfw' =>
            { name => "mlxfw", available => 1, selected => 0,
            included_in_rpm => 0, requires => [], },
        'mthca' =>
            { name => "mthca", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'mlx4' =>
            { name => "mlx4", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'mlx5' =>
            { name => "mlx5", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'mlx4_en' =>
            { name => "mlx4_en", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core","mlx4"], },
        'mlx4_vnic' =>
            { name => "mlx4_vnic", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core","mlx4"], },
        'mlx4_fc' =>
            { name => "mlx4_fc", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core","mlx4_en"], },
        'ipoib' =>
            { name => "ipoib", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'sdp' =>
            { name => "sdp", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], },
        'srp' =>
            { name => "srp", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], },
        'srpt' =>
            { name => "srpt", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'rds' =>
            { name => "rds", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], },
        'e_ipoib' =>
            { name => "e_ipoib", available => 0, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], },
        'iser' =>
            { name => "iser", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], ofa_req_inst => [] },
        'isert' =>
            { name => "isert", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], ofa_req_inst => [] },
        'nfsrdma' =>
            { name => "nfsrdma", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core", "ipoib"], },
        'mlx5_fpga_tools' =>
            { name => "mlx5_fpga_tools", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["core"], },
        'mdev' =>
            { name => "mdev", available => 1, selected => 0,
            included_in_rpm => 0, requires => ["mlx5"], },
        );

my %packages_info = (
        # Kernel packages
        'mlnx-ofa_kernel' =>
           { name => "mlnx-ofa_kernel", parent => "mlnx-ofa_kernel",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel", dist_req_build => ["make", "$gcc", "$kernel_req"],
           dist_req_inst => ["ethtool", "lsof", "pciutils","$python"],ubuntu_dist_req_build => ["make","$gcc"],ubuntu_dist_req_inst => ["pciutils","$python"],
           ofa_req_build => [], ofa_req_inst => ["ofed-scripts"],
           soft_req => ["ofed-scripts"],
           configure_options => '' },
        'mlnx-ofa_kernel-devel' =>
           { name => "mlnx-ofa_kernel-devel", parent => "mlnx-ofa_kernel",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel", dist_req_build => [],
           dist_req_inst => ["make"], ofa_req_build => [], ofa_req_inst => ["ofed-scripts", 'mlnx-ofa_kernel'], configure_options => '' },
        'mlnx-ofa_kernel-modules' =>
            { name => "mlnx-ofa_kernel-modules", parent => "mlnx-ofa_kernel",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["lsof","pciutils"],ubuntu_dist_req_build => ["make","$gcc"],ubuntu_dist_req_inst => ["pciutils"],
            ofa_req_build => [], ofa_req_inst => ["mlnx-ofa_kernel", "ofed-scripts"],
            soft_req => ["ofed-scripts"] },
        'ib-bonding' =>
            { name => "ib-bonding", parent => "ib-bonding",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], configure_options => '' },
        'ib-bonding-debuginfo' =>
            { name => "ib-bonding-debuginfo", parent => "ib-bonding",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], },
        'kernel-mft' =>
            { name => "kernel-mft", parent => "kernel-mft",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => ["ofed-scripts"], configure_options => '' },
        'kernel-mft-mlnx' =>
            { name => "kernel-mft-mlnx", parent => "kernel-mft",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => ["ofed-scripts"], configure_options => '' },
        'mlx4_accl_sys' =>
            { name => "mlx4_accl_sys", parent => "mlx4_accl_sys",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => ["ofed-scripts"], configure_options => '' },
        'mlx4_accl' =>
            { name => "mlx4_accl", parent => "mlx4_accl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["mlx4_accl_sys"], ofa_req_inst => ["ofed-scripts","mlx4_accl_sys"], configure_options => '' },
        'knem' =>
            { name => "knem", parent => "knem",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], configure_options => '' },
        # this one is used when KMP is disabled to proivde the kernel modules only
        'knem-modules' =>
            { name => "knem-modules", parent => "knem",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["knem"],
            ofa_req_inst => ["knem"],
            configure_options => '' },
        'ummunotify' =>
            { name => "ummunotify", parent => "ummunotify",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], configure_options => '' },
        'ummunotify-mlnx' =>
            { name => "ummunotify-mlnx", parent => "ummunotify",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], configure_options => '' },

        'mlnx-en' =>
           { name => "mlnx-en", parent => "mlnx-en",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel",
           dist_req_build => ["make", "$gcc", "$kernel_req"],
           dist_req_inst => ["ethtool", "lsof", "pciutils","$python"],
           ofa_req_build => [],
           ofa_req_inst => ['mlnx-en-utils'],
           configure_options => '' },
        'mlnx_en' =>
           { name => "mlnx_en", parent => "mlnx-en",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel",
           dist_req_build => ["make", "$gcc", "$kernel_req"],
           dist_req_inst => ["ethtool", "lsof", "pciutils","$python"],
           ofa_req_build => [],
           ofa_req_inst => ['mlnx-en-utils'],
           configure_options => '' },
        'mlnx-en-utils' =>
           { name => "mlnx-en-utils", parent => "mlnx-en",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel",
           dist_req_build => [],
           dist_req_inst => [],
           ofa_req_build => [],
           ofa_req_inst => ['ofed-scripts'],
           configure_options => '' },
        'mlnx-en-sources' =>
           { name => "mlnx-en-sources", parent => "mlnx-en",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel",
           dist_req_build => [],
           dist_req_inst => [],
           ofa_req_build => [],
           ofa_req_inst => [],
           configure_options => '' },
        'mlnx-en-doc' =>
           { name => "mlnx-en-doc", parent => "mlnx-en",
           selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
           available => 1, mode => "kernel",
           dist_req_build => [],
           dist_req_inst => [],
           ofa_req_build => [],
           ofa_req_inst => [],
           configure_options => '' },

        # User space libraries
        'libibverbs' =>
            { name => "libibverbs", parent => "$libibverbs_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build =>
            ($build32 == 1 )?["$pkgconfig", "$valgrind_devel", "$gcc", "$glibc_devel$suffix_64bit","$glibc_devel$suffix_32bit","$libgcc","$libgcc" . (($DISTRO eq "SLES10")?".$target_cpu32":"$suffix_32bit"), "$libnl_devel"."$suffix_64bit", ($DISTRO =~ /SUSE/)?"$libnl_devel"."$suffix_32bit":(($arch =~ /ppc/)?"$libnl_devel":"$libnl_devel.$target_cpu32")]:["$pkgconfig","$valgrind_devel", "$gcc", "$glibc_devel$suffix_64bit","$libgcc", "$libnl_devel"."$suffix_64bit"],
            dist_req_inst => ( $build32 == 1 )?["$pkgconfig","$libnl"."$suffix_64bit", ($dist_rpm !~ /sles-release-11.1/)?"$libnl"."$suffix_32bit":"$libnl.$target_cpu32"]:["$pkgconfig","$libnl"."$suffix_64bit"] ,
            ofa_req_build => [],
            ofa_req_inst => ["ofed-scripts", "$dep_on_rdma_core"],
            ubuntu_dist_req_build =>( $build32 == 1 )?["$gcc", "libc6-dev","libc6-dev-i386",
            "libgcc1","lib32gcc1"]:["$gcc", "libc6-dev","libgcc1"],
            ubuntu_dist_req_inst => [],install32 => 1, exception => 0, configure_options => '' },
        'libibverbs-devel' =>
            { name => "libibverbs-devel", parent => "libibverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0 },
        'libibverbs-devel-static' =>
            { name => "libibverbs-devel-static", parent => "libibverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0 },
        'libibverbs-utils' =>
            { name => "libibverbs-utils", parent => "$libibverbs_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libibverbs"],
            install32 => 0, exception => 0 },
        'libibverbs-debuginfo' =>
            { name => "libibverbs-debuginfo", parent => "libibverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libmthca' =>
            { name => "libmthca", parent => "libmthca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libmthca-devel-static' =>
            { name => "libmthca-devel-static", parent => "libmthca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libmthca"],
            install32 => 1, exception => 0 },
        'libmthca-debuginfo' =>
            { name => "libmthca-debuginfo", parent => "libmthca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libmlx4' =>
            { name => "libmlx4", parent => "libmlx4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$valgrind_devel"],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libmlx4-devel' =>
            { name => "libmlx4-devel", parent => "libmlx4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs","libmlx4"],
            install32 => 1, exception => 0 },
        'libmlx4-debuginfo' =>
            { name => "libmlx4-debuginfo", parent => "libmlx4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libmlx5' =>
            { name => "libmlx5", parent => "libmlx5",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$valgrind_devel"],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libmlx5-devel' =>
            { name => "libmlx5-devel", parent => "libmlx5",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs","libmlx5"],
            install32 => 1, exception => 0 },
        'libmlx5-debuginfo' =>
            { name => "libmlx5-debuginfo", parent => "libmlx5",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'librxe' =>
            { name => "librxe", parent => "librxe",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["$libibverbs_devel", "mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'librxe-devel-static' =>
            { name => "librxe-devel-static", parent => "librxe",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["libibverbs","$libibverbs_devel", "mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["libibverbs","$librxe"],
            install32 => 1, exception => 0 },
        'librxe-debuginfo' =>
            { name => "librxe-debuginfo", parent => "librxe",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["libibverbs","$libibverbs_devel", "mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["$librxe"],
            install32 => 0, exception => 0 },

        'libehca' =>
            { name => "libehca", parent => "libehca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libehca-devel-static' =>
            { name => "libehca-devel-static", parent => "libehca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libehca"],
            install32 => 1, exception => 0 },
        'libehca-debuginfo' =>
            { name => "libehca-debuginfo", parent => "libehca",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libcxgb3' =>
            { name => "libcxgb3", parent => "libcxgb3",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libcxgb3-devel' =>
            { name => "libcxgb3-devel", parent => "libcxgb3",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libcxgb3"],
            install32 => 1, exception => 0 },
        'libcxgb3-debuginfo' =>
            { name => "libcxgb3-debuginfo", parent => "libcxgb3",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libcxgb4' =>
            { name => "libcxgb4", parent => "libcxgb4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libcxgb4-devel' =>
            { name => "libcxgb4-devel", parent => "libcxgb4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libcxgb4"],
            install32 => 1, exception => 0 },
        'libcxgb4-debuginfo' =>
            { name => "libcxgb4-debuginfo", parent => "libcxgb4",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libnes' =>
            { name => "libnes", parent => "libnes",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libnes-devel-static' =>
            { name => "libnes-devel-static", parent => "libnes",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libnes"],
            install32 => 1, exception => 0 },
        'libnes-debuginfo' =>
            { name => "libnes-debuginfo", parent => "libnes",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libipathverbs' =>
            { name => "libipathverbs", parent => "libipathverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libipathverbs-devel' =>
            { name => "libipathverbs-devel", parent => "libipathverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "libipathverbs"],
            install32 => 1, exception => 0 },
        'libipathverbs-debuginfo' =>
            { name => "libipathverbs-debuginfo", parent => "libipathverbs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libibcm' =>
            { name => "libibcm", parent => "$libibcm_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$valgrind_devel"],
            dist_req_inst => [],
            ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs"],
            install32 => 1, exception => 0, configure_options => '' },
        'libibcm-devel' =>
            { name => "libibcm-devel", parent => "libibcm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "$libibverbs_devel", "libibcm"],
            install32 => 1, exception => 0 },
        'libibcm-debuginfo' =>
            { name => "libibcm-debuginfo", parent => "libibcm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },
        # Management
        'libibumad' =>
            { name => "libibumad", parent => "$libibumad_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["libtool"],
            dist_req_inst => [],ubuntu_dist_req_build => ["libtool"],ubuntu_dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$dep_on_rdma_core"],
            install32 => 1, exception => 0, configure_options => '' },
        'libibumad-devel' =>
            { name => "libibumad-devel", parent => "libibumad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libibumad"],
            install32 => 1, exception => 0 },
        'libibumad-static' =>
            { name => "libibumad-static", parent => "libibumad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libibumad"],
            install32 => 1, exception => 0 },
        'libibumad-debuginfo' =>
            { name => "libibumad-debuginfo", parent => "libibumad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libibmad' =>
            { name => "$libibmad", parent => "$libibmad_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["libtool"],
            dist_req_inst => [],ubuntu_dist_req_build => ["libtool"],ubuntu_dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["libibumad", "$dep_on_rdma_core"],
            install32 => 1, exception => 0, configure_options => '' },
        'libibmad-devel' =>
            { name => "libibmad-devel", parent => "libibmad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["libibmad", "$libibumad_devel"],
            install32 => 1, exception => 0 },
        'libibmad-static' =>
            { name => "libibmad-static", parent => "libibmad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["libibmad", "$libibumad_devel"],
            install32 => 1, exception => 0 },
        'libibmad-debuginfo' =>
            { name => "libibmad-debuginfo", parent => "libibmad",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'opensm' =>
            { name => "opensm", parent => "opensm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["bison", "flex"],
            dist_req_inst => [],ubuntu_dist_req_build => ["bison", "flex"],ubuntu_dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["opensm-libs"],
            install32 => 0, exception => 0, configure_options => '' },
        'opensm-devel' =>
            { name => "opensm-devel", parent => "opensm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["$libibumad_devel", "opensm-libs"],
            install32 => 0, exception => 0 },
        'opensm-libs' =>
            { name => "opensm-libs", parent => "opensm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["bison", "flex"],
            dist_req_inst => [],ubuntu_dist_req_build => ["bison", "flex"],ubuntu_dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["libibumad"],
            install32 => 0, exception => 0 },
        'opensm-static' =>
            { name => "opensm-static", parent => "opensm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["$libibumad_devel", "opensm-libs"],
            install32 => 0, exception => 0 },
        'opensm-debuginfo' =>
            { name => "opensm-debuginfo", parent => "opensm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ibsim' =>
            { name => "ibsim", parent => "ibsim",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel", "$libibmad_devel"],
            ofa_req_inst => ["libibumad", "$libibmad"],
            install32 => 0, exception => 0, configure_options => '' },
        'ibsim-debuginfo' =>
            { name => "ibsim-debuginfo", parent => "ibsim",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel", "$libibmad_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },

        'ibacm' =>
            { name => "ibacm", parent => "$ibacm_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["libibverbs", "libibumad", "$dep_on_rdma_core"],
            install32 => 0, exception => 0, configure_options => '' },
        'librdmacm' =>
            { name => "librdmacm", parent => "$librdmacm_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$valgrind_devel"],
            dist_req_inst => [],
            ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["libibverbs", "$dep_on_rdma_core"],
            install32 => 1, exception => 0, configure_options => '' },
        'librdmacm-devel' =>
            { name => "librdmacm-devel", parent => "librdmacm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["librdmacm", "$libibverbs_devel"],
            install32 => 1, exception => 0 },
        'librdmacm-utils' =>
            { name => "librdmacm-utils", parent => "$librdmacm_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => ["librdmacm", "$dep_on_rdma_core"],
            install32 => 0, exception => 0 },
        'librdmacm-debuginfo' =>
            { name => "librdmacm-debuginfo", parent => "librdmacm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'libsdp' =>
            { name => "libsdp", parent => "libsdp",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 1, exception => 0, configure_options => '' },
        'libsdp-devel' =>
            { name => "libsdp-devel", parent => "libsdp",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["libsdp"],
            install32 => 1, exception => 0 },
        'libsdp-debuginfo' =>
            { name => "libsdp-debuginfo", parent => "libsdp",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'perftest' =>
            { name => "perftest", parent => "perftest",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel", "librdmacm", "$librdmacm_devel", "$libibumad_devel"],
            ofa_req_inst => ["libibverbs", "librdmacm", "libibumad"],
            install32 => 0, exception => 0, configure_options => '' },
        'perftest-debuginfo' =>
            { name => "perftest-debuginfo", parent => "perftest",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'mft' =>
            { name => "mft", parent => "mft",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$libexpat", "$libexpat_devel", "tcl__8.4", "$tcl_devel" . "__8.4", "$tk", $libstdc_devel ],
            dist_req_inst => ["$libexpat", "tcl__8.4", "$tk", $libstdc],
            ubuntu_dist_req_build => ["libexpat1", "libexpat1-dev", "tcl8.5", "tcl8.5-dev", "$tk", "$libstdc_devel" ],
            ubuntu_dist_req_inst => ["$libexpat", "tcl8.5", "$tk", "$libstdc"],
            ofa_req_build => [], ofa_req_inst => [], configure_options => '' },
        'mft-debuginfo' =>
            { name => "mft-debuginfo", parent => "mft",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [], ofa_req_inst => [], },

        'mstflint' =>
            { name => "mstflint", parent => "mstflint",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => ["$zlib_devel$suffix_64bit", "$libstdc_devel$suffix_64bit", "$gcc_cpp", "$openssl_devel"],
            dist_req_inst => ["$openssl"], ofa_req_build => [],
            ubuntu_dist_req_build => ["zlib1g-dev", "$libstdc_devel", "$gcc","g++","byacc"],ubuntu_dist_req_inst => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'mstflint-debuginfo' =>
            { name => "mstflint-debuginfo", parent => "mstflint",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ibvexdmtools' =>
            { name => "ibvexdmtools", parent => "qlvnictools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["libibumad"],
            install32 => 0, exception => 0, configure_options => '' },
        'qlgc_vnic_daemon' =>
            { name => "qlgc_vnic_daemon", parent => "qlvnictools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'qlvnictools' =>
            { name => "qlvnictools", parent => "qlvnictools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => ["ibvexdmtools", "qlgc_vnic_daemon", "libibumad"],
            install32 => 0, exception => 0, configure_options => '' },
        'qlvnictools-debuginfo' =>
            { name => "qlvnictools-debuginfo", parent => "qlvnictools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'sdpnetstat' =>
            { name => "sdpnetstat", parent => "sdpnetstat",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'sdpnetstat-debuginfo' =>
            { name => "sdpnetstat-debuginfo", parent => "sdpnetstat",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'srptools' =>
            { name => "srptools", parent => "srptools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => ["$insserv_compat"],
            dist_req_inst => ["$insserv_compat"],
            ofa_req_build => ["$libibumad_devel", "$libibverbs_devel"],
            ofa_req_inst => ["libibumad", "libibverbs"],
            install32 => 0, exception => 0, configure_options => '' },
        'srptools-debuginfo' =>
            { name => "srptools-debuginfo", parent => "srptools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'dcbx' =>
            { name => "dcbx", parent => "dcbx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'dcbx-debuginfo' =>
            { name => "dcbx-debuginfo", parent => "dcbx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'rnfs-utils' =>
            { name => "rnfs-utils", parent => "rnfs-utils",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'rnfs-utils-debuginfo' =>
            { name => "rnfs-utils-debuginfo", parent => "rnfs-utils",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'rds-tools' =>
            { name => "rds-tools", parent => "rds-tools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },
        'rds-devel' =>
            { name => "rds-devel", parent => "rds-tools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => ["rds-tools"],
            install32 => 0, exception => 0, configure_options => '' },
        'rds-tools-debuginfo' =>
            { name => "rds-tools-debuginfo", parent => "rds-tools",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'qperf' =>
            { name => "qperf", parent => "qperf",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["$libibverbs_devel", "$librdmacm_devel"],
            ofa_req_inst => ["libibverbs", "librdmacm"],
            install32 => 0, exception => 0, configure_options => '' },
        'qperf-debuginfo' =>
            { name => "qperf-debuginfo", parent => "qperf",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ibutils' =>
            { name => "ibutils", parent => "ibutils",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["tcl__8.4", "$tcl_devel" . "__8.4", "$tk", "$libstdc_devel"],
            dist_req_inst => ["tcl__8.4", "$tk", "$libstdc"], ofa_req_build => ["$libibverbs_devel", "opensm-libs", "opensm-devel"],
            ofa_req_inst => ["libibumad", "opensm-libs"],
            ubuntu_dist_req_build => ["tcl8.5", "tcl8.5-dev", "$tk", "$libstdc_devel"],
            ubuntu_dist_req_inst => ["tcl8.5", "$tk", "$libstdc"],
            install32 => 0, exception => 0, configure_options => ' --with-tk-lib ' },
        'ibutils-debuginfo' =>
            { name => "ibutils-debuginfo", parent => "ibutils",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ibutils2' =>
            { name => "ibutils2", parent => "ibutils2",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 1, mode => "user", dist_req_build => ["tcl__8.4", "$tcl_devel" . "__8.4", "$libstdc_devel"],
            dist_req_inst => ["tcl__8.4", "$libstdc"], ofa_req_build => ["$libibumad_devel", "infiniband-diags"],
            ofa_req_inst => ["libibumad", "infiniband-diags"],
            ubuntu_dist_req_build => ["tcl8.5", "tcl8.5-dev", "$libstdc_devel"],
            ubuntu_dist_req_inst => ["tcl8.5", "$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },
        'ibutils2-debuginfo' =>
            { name => "ibutils2-debuginfo", parent => "ibutils2",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ar_mgr' =>
            { name => "ar_mgr", parent => "ar_mgr",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 1, mode => "user", dist_req_build => ["$libstdc_devel"],
            dist_req_inst => ["$libstdc"], ofa_req_build => ["opensm-libs", "opensm-devel", "ibutils2"],
            ofa_req_inst => ["opensm", "ibutils2"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },

        'cc_mgr' =>
            { name => "cc_mgr", parent => "cc_mgr",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 1, mode => "user", dist_req_build => ["$libstdc_devel"],
            dist_req_inst => ["$libstdc"], ofa_req_build => ["opensm-libs", "opensm-devel", "ibutils2"],
            ofa_req_inst => ["opensm", "ibutils2"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },

        'dump_pr' =>
            { name => "dump_pr", parent => "dump_pr",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 1, mode => "user", dist_req_build => ["$libstdc_devel"],
            dist_req_inst => ["$libstdc"], ofa_req_build => ["opensm-libs", "opensm-devel"],
            ofa_req_inst => ["opensm"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },

        'ibdump' =>
            { name => "ibdump", parent => "ibdump",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 0, mode => "user", dist_req_build => ["$libstdc_devel"],
            dist_req_inst => ["$libstdc"], ofa_req_build => ["$libibverbs_devel", "mstflint"],
            ofa_req_inst => ["libibverbs", "mstflint"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },
        'ibdump-debuginfo' =>
            { name => "ibdump-debuginfo", parent => "ibdump",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0, internal => 1,
            available => 0, mode => "user", dist_req_build => [],
            dist_req_inst => ['ibdump'], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'infiniband-diags' =>
            { name => "infiniband-diags", parent => "$infiniband_diags_parent",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$glib2_devel"],
            dist_req_inst => ["$glib2"], ofa_req_build => ["opensm-devel", "$libibmad_devel", "$libibumad_devel"],
            ofa_req_inst => ["libibumad", "$libibmad", "opensm-libs"],
            install32 => 0, exception => 0, configure_options => '' },
        'infiniband-diags-guest' =>
            { name => "infiniband-diags-guest", parent => "infiniband-diags",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$glib2_devel"],
            dist_req_inst => ["$glib2"], ofa_req_build => ["opensm-devel"],
            ofa_req_inst => ["infiniband-diags","opensm-libs"],
            install32 => 0, exception => 0 },
        'infiniband-diags-compat' =>
            { name => "infiniband-diags-compat", parent => "infiniband-diags",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$glib2_devel"],
            dist_req_inst => ["$glib2"], ofa_req_build => ["opensm-devel"],
            ofa_req_inst => ["infiniband-diags","opensm-libs"],
            install32 => 0, exception => 0 },
        'infiniband-diags-debuginfo' =>
            { name => "infiniband-diags-debuginfo", parent => "infiniband-diags",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$glib2_devel"],
            dist_req_inst => ["$glib2"], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'dapl' =>
            { name => "dapl", parent => "dapl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs", "$libibverbs_devel", "librdmacm", "$librdmacm_devel", "$libibmad_devel"],
            ofa_req_inst => ["libibverbs", "librdmacm"],
            install32 => 0, exception => 0, configure_options => '' },
        'dapl-devel' =>
            { name => "dapl-devel", parent => "dapl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel", "librdmacm", "$librdmacm_devel"],
            ofa_req_inst => ["dapl"],
            install32 => 0, exception => 0, configure_options => '' },
        'dapl-devel-static' =>
            { name => "dapl-devel-static", parent => "dapl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel", "librdmacm", "$librdmacm_devel"],
            ofa_req_inst => ["dapl"],
            install32 => 0, exception => 0, configure_options => '' },
        'dapl-utils' =>
            { name => "dapl-utils", parent => "dapl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel", "librdmacm", "$librdmacm_devel"],
            ofa_req_inst => ["dapl"],
            install32 => 0, exception => 0, configure_options => '' },
        'dapl-debuginfo' =>
            { name => "dapl-debuginfo", parent => "dapl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => ["libibverbs","$libibverbs_devel", "librdmacm", "$librdmacm_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'mxm' =>
            { name => "mxm", parent => "mxm",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$pkgconfig","$libstdc_devel","$gcc_cpp","binutils-devel","$libstdc","$valgrind_devel"],
            dist_req_inst => ["$pkgconfig","$libstdc", "$cairo", "$atk", "$gtk2"],
            ofa_req_build => ["$libibverbs_devel","$librdmacm_devel","$libibmad_devel","$libibumad_devel","$knem_rpm", "$knem_mods"],
            ofa_req_inst => ["libibumad", "libibverbs", "$knem_rpm", "$knem_mods"],
            soft_req => ["$knem_rpm", "$knem_mods"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },

        'ucx' =>
            { name => "ucx", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => ["$pkgconfig","$libstdc"],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => [],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-devel' =>
            { name => "ucx-devel", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => ["$pkgconfig","$libstdc"],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-static' =>
            { name => "ucx-static", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => ["$pkgconfig","$libstdc"],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-cma' =>
            { name => "ucx-cma", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => [],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-cuda' =>
            { name => "ucx-cma", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user",
            dist_req_build => [
                @ucx_dist_build_req, "cuda-libraries-$cuda_version",
                "cuda-cudart-dev-$cuda_version",
                "cuda-misc-headers-$cuda_version",
                "nvidia-driver-devel", "cuda-nvcc-$cuda_version",
            ],
            dist_req_inst => ["cuda-cudart-$cuda_version"],
            ofa_req_build => [@ucx_ofa_build_req],
            soft_req => ["$libibcm_devel"],
            ofa_req_inst => ['ucx'],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-gdrcopy' =>
            { name => "ucx-gdrcopy", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user",
            dist_req_build => [@ucx_dist_build_req, 'gdrcopy', 'gdrcopy-devel'],
            dist_req_inst => ['gdrcopy'],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-ib' =>
            { name => "ucx-ib", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => [],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx', 'libibverbs'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-ib-cm' =>
            { name => "ucx-ib-cm", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => [],
            ofa_req_build => [@ucx_ofa_build_req],
            ofa_req_inst => ['ucx', 'libibverbs', 'libibcm'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-knem' =>
            { name => "ucx-knem", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => [],
            ofa_req_build => [@ucx_ofa_build_req, 'knem'],
            ofa_req_inst => ['ucx', 'knem'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },
        'ucx-rdmacm' =>
            { name => "ucx-rdmacm", parent => "ucx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [@ucx_dist_build_req],
            dist_req_inst => [],
            ofa_req_build => [@ucx_ofa_build_req, 'librdmacm', 'librdmacm-devel'],
            ofa_req_inst => ['ucx', 'librdmacm'],
            soft_req => ["$libibcm_devel"],
            install32 => 0, exception => 0, configure_options => '' },

        'mpi-selector' =>
            { name => "mpi-selector", parent => "mpi-selector",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["tcsh"],
            dist_req_inst => ["tcsh"], ofa_req_build => [],
            ofa_req_inst => [],
            ubuntu_dist_req_build => ["tcsh"],ubuntu_dist_req_inst => ["tcsh"],
            install32 => 0, exception => 0, configure_options => '' },

        'mvapich' =>
            { name => "mvapich", parent => "mvapich",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => ["$libgfortran","$libstdc_devel"],
            dist_req_inst => ["$libstdc"], ofa_req_build => ["$libibumad_devel", "$libibverbs_devel"],
            ofa_req_inst => ["mpi-selector", "libibverbs", "libibumad"],
            soft_req => ["mpi-selector"],
            ubuntu_dist_req_build => ["$libstdc_devel"],
            ubuntu_dist_req_inst => [""],
            install32 => 0, exception => 0, configure_options => '' },

        'mvapich2' =>
            { name => "mvapich2", parent => "mvapich2",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$libgfortran", $sysfsutils_devel, "$libstdc_devel"],
            dist_req_inst => [$sysfsutils, "$libstdc"], ofa_req_build => ["$libibumad_devel", "$libibverbs_devel"],
            ofa_req_inst => ["mpi-selector", "librdmacm", "libibumad"],
            soft_req => ["mpi-selector"],
            install32 => 0, exception => 0, configure_options => '' },

        'openmpi' =>
            { name => "openmpi", parent => "openmpi",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$libgfortran","$libstdc_devel"],
            dist_req_inst => ["$libstdc"],
            ofa_req_build => ["$libibverbs_devel", "$librdmacm_devel", "$fca", "hcoll", "mxm", "ucx", "ucx-devel", "ucx-static", "$knem_rpm", "$knem_mods", "$libibmad_devel", "sharp"],
            ofa_req_inst => ["libibverbs", "librdmacm", "mpi-selector", "$fca", "hcoll", "mxm", "ucx", "$knem_rpm", "$knem_mods", "sharp"],
            soft_req => ["mpi-selector","$fca", "hcoll", "mxm", "ucx", "ucx-devel", "ucx-static", "$knem_rpm", "$knem_mods", "sharp"],
            ubuntu_dist_req_build => ["$libgfortran","$libstdc_devel"],
            ubuntu_dist_req_inst => ["$libstdc"],
            install32 => 0, exception => 0, configure_options => '' },

# Note: this node of 'mpitests' is a generic node, it should stay available=0.
# the real mpitests packages that will be installed are defined in function "add_new_mpitests_pkg".
# mpitests will be compiled with all available openmpi/mvapich versions.
        'mpitests' =>
            { name => "mpitests", parent => "mpitests",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "user", dist_req_build => ["$fortran"],
            dist_req_inst => [], ofa_req_build => ["$libibumad_devel", "$librdmacm_devel", "$libibmad_devel"],
            ofa_req_inst => [],
            install32 => 0, exception => 0, configure_options => '' },

        'ofed-docs' =>
            { name => "ofed-docs", parent => "ofed-docs",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => [],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },

        'ofed-scripts' =>
            { name => "ofed-scripts", parent => "ofed-scripts",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user", dist_req_build => ["$python_devel"],
            dist_req_inst => [], ofa_req_build => [],
            ofa_req_inst => [],
            install32 => 0, exception => 0 },
        'infinipath-psm' =>
            { name => "infinipath-psm", parent=> "infinipath-psm",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user", dist_req_build => [],
             dist_req_inst => [], ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },
        'infinipath-psm-devel' =>
            { name => "infinipath-psm-devel", parent=> "infinipath-psm",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user", dist_req_build => [],
             dist_req_inst => [], ofa_req_build => [],
             ofa_req_inst => ["infinipath-psm"], install32 => 0, exception => 0 },
        'openshmem' =>
            { name => "openshmem", parent=> "openshmem",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user", dist_req_build => [],
             dist_req_inst => [], ofa_req_build => ["$fca","opensm-devel","$knem_rpm", "$knem_mods","mxm", "$libibmad_devel", "$librdmacm_devel"],
             ofa_req_inst => ["$fca","mxm","opensm-libs","$knem_rpm", "$knem_mods"], install32 => 0, exception => 0 },
        'fca' =>
            { name => "fca", parent=> "fca",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user", dist_req_build => ["$gcc_cpp","$libstdc_devel","$curl_devel"],
             dist_req_inst => [],
             dist_req_build => ["$gcc_cpp","$libstdc_devel","$curl_devel"],
             dist_req_inst => [],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libibmad_devel","$libibumad_devel","opensm-devel",$infiniband_diags_compat],
             ofa_req_inst => [$infiniband_diags_compat,"librdmacm"], install32 => 0, exception => 0 },
        'bupc' =>
             { name => "bupc", parent=> "bupc",
              selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
              available => 1, mode => "user", dist_req_build => ["$gcc_cpp","$libstdc_devel"],
              dist_req_inst => ["$libstdc",], ofa_req_build => ["$libibverbs_devel","$fca","mxm","openmpi"],
              ofa_req_inst => ["libibverbs","$fca","mxm","openmpi"], install32 => 0, exception => 0 },
        'libibprof' =>
            { name => "libibprof", parent=> "libibprof",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$gcc_cpp","$libstdc_devel","$libstdc"],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "hcoll", "mxm"],
             ofa_req_inst => ["libibverbs", "hcoll", "mxm"], install32 => 0, exception => 0 },
        'hcoll' =>
            { name => "hcoll", parent=> "hcoll",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$gcc_cpp","$libstdc_devel","$libstdc", "$openssl_devel"],
             dist_req_inst => ["$openssl"],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libibmad_devel","$libibumad_devel", "sharp", "$libibcm_devel", "ucx"],
             ofa_req_inst => ["libibverbs", "librdmacm", "$libibmad", "libibumad", "sharp", "libibcm"], install32 => 0, exception => 0,
             soft_req => ["sharp"] },
        'sharp' =>
            { name => "sharp", parent=> "sharp",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$gcc_cpp","$libstdc_devel","$libstdc", "binutils-devel"],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libibmad_devel", "ucx", "ucx-devel", "ucx-static"],
             ofa_req_inst => ["libibverbs", "libibumad", "librdmacm", "$libibmad", "ucx"],
             soft_req => ["ucx", "ucx-devel", "ucx-static"],
			 install32 => 0, exception => 0 },

        'libvma' =>
            { name => "libvma", parent=> "libvma",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$libnl_devel"],
             dist_req_inst => ["$libnl"],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libmlx4_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "$libmlx4"], install32 => 0, exception => 0 },
        'libvma-utils' =>
            { name => "libvma-utils", parent=> "libvma",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$libnl_devel"],
             dist_req_inst => ["$libnl"],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libmlx4_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "$libmlx4", "libvma"], install32 => 0, exception => 0 },
        'libvma-devel' =>
            { name => "libvma-devel", parent=> "libvma",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$libnl_devel"],
             dist_req_inst => ["$libnl"],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libmlx4_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "$libmlx4", "libvma"], install32 => 0, exception => 0 },
        'libvma-debuginfo' =>
            { name => "libvma-debuginfo", parent=> "libvma",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$libnl_devel"],
             dist_req_inst => ["$libnl"],
             ofa_req_build => ["$librdmacm_devel","$libibverbs_devel","$libmlx4_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "$libmlx4", "libvma"], install32 => 0, exception => 0 },

        'sockperf' =>
            { name => "sockperf", parent=> "sockperf",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_build => ["doxygen"],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },
        'sockperf-debuginfo' =>
            { name => "sockperf-debuginfo", parent=> "sockperf",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_build => ["doxygen"],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => ['sockperf'], install32 => 0, exception => 0 },

        'fabric-collector' =>
            { name => "fabric-collector", parent=> "fabric-collector",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => ["$libcurl"],
             dist_req_build => ( $build32 == 1 )?["$glibc_devel$suffix_64bit","$glibc_devel$suffix_32bit", "$curl_devel", "$openssl_devel"]:["$glibc_devel$suffix_64bit", "$curl_devel", "$openssl_devel"],
             ofa_req_build => ["$libibmad_devel", "$libibumad_devel", "opensm-devel"],
             ofa_req_inst => ["$libibmad", "libibumad", "opensm-libs"], install32 => 0, exception => 0 },
        'fabric-collector-debuginfo' =>
            { name => "fabric-collector-debuginfo", parent=> "fabric-collector",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => ["$libcurl"],
             dist_req_build => ( $build32 == 1 )?["$glibc_devel$suffix_64bit","$glibc_devel$suffix_32bit", "$curl_devel", "$openssl_devel"]:["$glibc_devel$suffix_64bit", "$curl_devel", "$openssl_devel"],
             ofa_req_build => ["$libibmad_devel", "$libibumad_devel", "opensm-devel"],
             ofa_req_inst => ["$libibmad", "libibumad", "opensm-libs"], install32 => 0, exception => 0 },

        'iser' =>
            { name => "iser", parent => "iser",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'isert' =>
            { name => "isert", parent => "isert",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'srp' =>
            { name => "srp", parent => "srp",
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'mlnx-sdp' =>
            { name => "mlnx-sdp", parent => "mlnx-sdp",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'mlnx-rds' =>
            { name => "mlnx-rds", parent => "mlnx-rds",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 0, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'mlnx-nfsrdma' =>
            { name => "mlnx-nfsrdma", parent => "mlnx-nfsrdma",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'mlnx-nvme' =>
            { name => "mlnx-nvme", parent => "mlnx-nvme",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => ["pciutils","$python"],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'mlnx-rdma-rxe' =>
            { name => "mlnx-rdma-rxe", parent => "mlnx-rdma-rxe",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts","$kernel_rpm"], configure_options => '' },

        'gpio-mlxbf' =>
            { name => "gpio-mlxbf", parent => "gpio-mlxbf",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'i2c-mlx' =>
            { name => "i2c-mlx", parent => "i2c-mlx",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'mlxbf-livefish' =>
            { name => "mlxbf-livefish", parent => "mlxbf-livefish",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'mlx-bootctl' =>
            { name => "mlx-bootctl", parent => "mlx-bootctl",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'pka-mlxbf' =>
            { name => "pka-mlxbf", parent => "pka-mlxbf",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'tmfifo' =>
            { name => "tmfifo", parent => "tmfifo",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'rshim' =>
            { name => "rshim", parent => "rshim",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'mlx-trio' =>
            { name => "mlx-trio", parent => "mlx-trio",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'mlx-l3cache' =>
            { name => "mlx-l3cache", parent => "mlx-l3cache",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'mlx-pmc' =>
            { name => "mlx-pmc", parent => "mlx-pmc",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "kernel", dist_req_build => ["make", "$gcc"],
            dist_req_inst => [],
            ofa_req_build => [],
            ofa_req_inst => ["$kernel_rpm"], configure_options => '' },

        'libpka' =>
            { name => "libpka", parent=> "libpka",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$openssl_devel"],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'mlxbf-bootctl' =>
            { name => "mlxbf-bootctl", parent=> "mlxbf-bootctl",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'mlxbf-bootimages' =>
            { name => "mlxbf-bootimages", parent=> "mlxbf-bootimages",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'bfscripts' =>
            { name => "bfscripts", parent=> "bfscripts",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => ["mlxbf-bootctl", "mlxbf-bootimages"], install32 => 0, exception => 0 },

        'nvme-snap' =>
            { name => "nvme-snap", parent=> "nvme-snap",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["rdma-core-devel"],
             ofa_req_inst => ["rdma-core"], install32 => 0, exception => 0 },

        'openvswitch' =>
            { name => "openvswitch", parent=> "openvswitch",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["desktop-file-utils", "groff", "graphviz", "openssl-devel", "selinux-policy-devel", "python-sphinx", "python-twisted-core", "python-zope-interface", "libcap-ng-devel", "python-six", "unbound", "unbound-devel"],
             dist_req_inst => ["openssl", "unbound"],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'spdk' =>
            { name => "spdk", parent=> "spdk",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_build => ["CUnit-devel", "libaio-devel", "openssl-devel", "libuuid-devel", "libiscsi-devel", "python-pep8", "lcov", "clang-analyzer", "graphviz", "python-configshell"],
             dist_req_inst => ["python", "sg3_utils", "avahi"],
             ofa_req_build => ["libibverbs-devel", "librdmacm-devel"],
             ofa_req_inst => ["libibverbs", "librdmacm"], install32 => 0, exception => 0 },

        'mlnx-ethtool' =>
            { name => "mlnx-ethtool", parent=> "mlnx-ethtool",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },
        'mlnx-ethtool-debuginfo' =>
            { name => "mlnx-ethtool-debuginfo", parent=> "mlnx-ethtool",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => ["mlnx-ethtool"], install32 => 0, exception => 0 },
        'mlnx-iproute2' =>
            { name => "mlnx-iproute2", parent=> "mlnx-iproute2",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 1, mode => "user",
             dist_req_inst => [$libmnl],
             dist_req_build => [$iptables_devel, $elfutils_devel, "libmnl-devel", $libdb_devel, "libselinux-devel"],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },
        'libopensmssa' =>
            { name => "libopensmssa", parent=> "libopensmssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["opensm-devel", "$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["opensm-libs", "libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },
        'libopensmssa-debuginfo' =>
            { name => "libopensmssa-debuginfo", parent=> "libopensmssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["opensm-devel", "$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["libopensmssa", "opensm-libs", "libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },

        'ibssa' =>
            { name => "ibssa", parent=> "ibssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },
        'ibssa-debuginfo' =>
            { name => "ibssa-debuginfo", parent=> "ibssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_build => ["ibssa", "libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'ibacm_ssa' =>
            { name => "ibacm_ssa", parent=> "ibacm_ssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },
        'ibacm_ssa-devel' =>
            { name => "ibacm_ssa-devel", parent=> "ibacm_ssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["ibacm_ssa", "libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },
        'ibacm_ssa-debuginfo' =>
            { name => "ibacm_ssa-debuginfo", parent=> "ibacm_ssa",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel", "$libibumad_devel", "$librdmacm_devel", "$libmlx4_devel", "$libmlx5_devel"],
             ofa_req_inst => ["ibacm_ssa", "libibverbs", "libibumad", "librdmacm", "$libmlx4", "$libmlx5"], install32 => 0, exception => 0 },

        'multiperf' =>
            { name => "multiperf", parent=> "multiperf",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel"],
             ofa_req_inst => ["libibverbs"], install32 => 0, exception => 0 },
        'multiperf-debuginfo' =>
            { name => "multiperf-debuginfo", parent=> "multiperf",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => ["$libibverbs_devel"],
             ofa_req_inst => ["multiperf", "libibverbs"], install32 => 0, exception => 0 },

        # this package is listed here only for uninstall and --without.. flag support
        'mlnx-fw-updater' =>
            { name => "mlnx-fw-updater", parent=> "mlnx-fw-updater",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => [],
             dist_req_inst => [],
             ofa_req_build => [],
             ofa_req_inst => [], install32 => 0, exception => 0 },

        'rdma-core' =>
            { name => "rdma-core", parent => "rdma-core",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [
                "cmake__2.8.11", "$libudev_devel", "$pkgconfig",
                "$valgrind_devel", "$gcc", "$glibc_devel$suffix_64bit",
                "$libgcc", "$python_devel", "$python_cython",
                "$libnl3_devel"."$suffix_64bit",
                ($build32 == 1) ? (
                    "$glibc_devel$suffix_32bit",
                    "$libgcc" . (($DISTRO eq "SLES10") ? ".$target_cpu32" : "$suffix_32bit"),
                    ($DISTRO =~ /SUSE/) ? "$libnl3_devel"."$suffix_32bit" : (
                        ($arch =~ /ppc/) ? "$libnl3_devel" : "$libnl3_devel.$target_cpu32"
                    )
                ) : ()
            ],
            dist_req_inst => [
                "$pkgconfig", "$libudev", "$libnl3"."$suffix_64bit",
                ($build32 == 1) ? (
                    ($dist_rpm !~ /sles-release-11.1/)?"$libnl"."$suffix_32bit" :
                        "$libnl.$target_cpu32"
                ) : ()
            ] ,
            ofa_req_build => ["mlnx-ofa_kernel-devel"],
            ofa_req_inst => ["ofed-scripts"],
            install32 => 1, exception => 0, configure_options => '' },
        'rdma-core-devel' =>
            { name => "rdma-core-devel", parent => "rdma-core",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["rdma-core"],
            ofa_req_inst => ["rdma-core"],
            install32 => 1, exception => 0, configure_options => '' },
        'rdma-core-debuginfo' =>
            { name => "rdma-core-debuginfo", parent => "rdma-core",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["rdma-core"],
            ofa_req_inst => ["rdma-core"],
            install32 => 1, exception => 0, configure_options => '' },

        'srp_daemon' =>
            { name => "srp_daemon", parent => "rdma-core",
            selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
            available => 1, mode => "user",
            dist_req_build => [],
            dist_req_inst => [],
            ofa_req_build => ["rdma-core", "$libibumad_devel", "$libibverbs_devel"],
            ofa_req_inst => ["rdma-core", "libibumad", "libibverbs"],
            install32 => 0, exception => 0, configure_options => '' },
        'libdisni' =>
            { name => "libdisni", parent=> "libdisni",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$java_devel"],
             dist_req_inst => ["$java"],
             ofa_req_build => ["$libibverbs_devel", "$librdmacm_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm"], install32 => 0, exception => 0 },
        'libdisni-devel' =>
            { name => "libdisni-devel", parent=> "libdisni",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$java_devel"],
             dist_req_inst => ["$java"],
             ofa_req_build => ["$libibverbs_devel", "$librdmacm_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "libdisni"], install32 => 0, exception => 0 },
        'libdisni-debuginfo' =>
            { name => "libdisni-debuginfo", parent=> "libdisni",
             selected => 0, installed => 0, rpm_exist => 0, rpm_exist32 => 0,
             available => 0, mode => "user",
             dist_req_inst => [],
             dist_req_build => ["$java_devel"],
             dist_req_inst => ["$java"],
             ofa_req_build => ["$libibverbs_devel", "$librdmacm_devel"],
             ofa_req_inst => ["libibverbs", "librdmacm", "libdisni"], install32 => 0, exception => 0 },
);

foreach (keys %packages_info) {
    my $entry = $packages_info{$_};
    next unless ($entry->{'mode'} eq 'kernel');
    next unless ($DISTRO =~ /RHEL8 | OL8 | EULEROS2.0SP8 | FC29 | FC3./x);

    push @{$entry->{'dist_req_build'}}, 'gdb-headless';
}


my @hidden_packages = ();

my %MPI_SUPPORTED_COMPILERS = (gcc => 0, pgi => 0, intel => 0, pathscale => 0);

my %gcc = ('gcc' => 0, 'gfortran' => 0, 'g77' => 0, 'g++' => 0);
my %pathscale = ('pathcc' => 0, 'pathCC' => 0, 'pathf90' => 0);
my %pgi = ('pgf77' => 0, 'pgf90' => 0, 'pgCC' => 0);
my %intel = ('icc' => 0, 'icpc' => 0, 'ifort' => 0);

# mvapich2 environment
my $mvapich2_conf_impl = "ofa";
my $mvapich2_conf_romio = 1;
my $mvapich2_conf_shared_libs = 1;
my $mvapich2_conf_ckpt = 0;
my $mvapich2_conf_blcr_home;
my $mvapich2_conf_vcluster = "small";
my $mvapich2_conf_io_bus;
my $mvapich2_conf_link_speed;
my $mvapich2_conf_dapl_provider = "";
my $mvapich2_comp_env;
my $mvapich2_dat_lib;
my $mvapich2_dat_include;
my $mvapich2_conf_done = 0;

my $TOPDIR = $builddir . '/' . $PACKAGE . "_topdir";
chomp $TOPDIR;

rmtree ("$TOPDIR");
mkpath([$TOPDIR . '/BUILD' ,$TOPDIR . '/RPMS',$TOPDIR . '/SOURCES',$TOPDIR . '/SPECS',$TOPDIR . '/SRPMS']);

if ($config_given and $install_option) {
    print_and_log_colored("\nError: '-c' option can't be used with '--all|--hpc|--vma|--basic|--bluefield'", 1, "RED");
    exit 1;
}

if ($config_given and not -e $config) {
    print_and_log_colored("$config does not exist", 1, "RED");
    exit 1;
}

if (not $config_given and -e $config) {
    move($config, "$config.save");
}

if ($quiet) {
    $verbose = 0;
    $verbose2 = 0;
    $verbose3 = 0;
}

my %ifcfg = ();
if ($config_net_given and not -e $config_net) {
    print_and_log_colored("$config_net does not exist", 1, "RED");
    exit 1;
}

my $eth_dev;
if ($config_net_given) {
    open(NET, "$config_net") or die "Can't open $config_net: $!";
    while (<NET>) {
        my ($param, $value) = split('=');
        chomp $param;
        chomp $value;
        my $dev = $param;
        $dev =~ s/(.*)_(ib[0-9]+)/$2/;
        chomp $dev;

        if ($param =~ m/IPADDR/) {
            $ifcfg{$dev}{'IPADDR'} = $value;
        }
        elsif ($param =~ m/NETMASK/) {
            $ifcfg{$dev}{'NETMASK'} = $value;
        }
        elsif ($param =~ m/NETWORK/) {
            $ifcfg{$dev}{'NETWORK'} = $value;
        }
        elsif ($param =~ m/BROADCAST/) {
            $ifcfg{$dev}{'BROADCAST'} = $value;
        }
        elsif ($param =~ m/ONBOOT/) {
            $ifcfg{$dev}{'ONBOOT'} = $value;
        }
        elsif ($param =~ m/LAN_INTERFACE/) {
            $ifcfg{$dev}{'LAN_INTERFACE'} = $value;
        }
        else {
            print_and_log_colored("Unsupported parameter '$param' in $config_net\n", $verbose2, "RED");
        }
    }
    close(NET);
}

sub sig_handler
{
    exit $ERROR;
}

sub getch
{
        my $c;
        system("stty -echo raw");
        $c=getc(STDIN);
        system("stty echo -raw");
        # Exit on Ctrl+c or Esc
        if ($c eq "\cC" or $c eq "\e") {
            print "\n";
            exit $ERROR;
        }
        print "$c\n";
        return $c;
}

sub get_rpm_name_arch
{
    my $ret = `rpm --queryformat "[%{NAME}] [%{ARCH}]" -qp @_ 2>/dev/null | grep -v Freeing`;
    chomp $ret;
    return $ret;
}

sub get_rpm_ver
{
    my $ret = `rpm --queryformat "[%{VERSION}]\n" -qp @_ 2>/dev/null | uniq`;
    chomp $ret;
    return $ret;
}

sub get_rpm_rel
{
    my $ret = `rpm --queryformat "[%{RELEASE}]\n" -qp @_ 2>/dev/null | uniq`;
    chomp $ret;
    return $ret;
}

# Get the version (or first, if there are multiple ones)
# Returns an empty string on error
sub get_rpm_ver_one($) {
    my $package = shift;
    my $version = `rpm -q --queryformat "[%{VERSION}]\n" "$package" 2>/dev/null | head -1`;
    chomp $version;
    return $version;
}

# Get RPM name and version of the INSTALLED package
sub get_rpm_ver_inst
{
    my $ret;
    if ($DISTRO =~ /DEBIAN|UBUNTU/) {
        $ret = `dpkg-query -W -f='\${Version}\n' @_ | cut -d ':' -f 2 | uniq`;
    }
    else {
        $ret = `rpm --queryformat '[%{VERSION}]\n' -q @_ 2>/dev/null | uniq`;
    }
    chomp $ret;
    return $ret;
}

sub get_rpm_rel_inst
{
    my $ret = `rpm --queryformat "[%{RELEASE}]\n" -q @_ 2>/dev/null | uniq`;
    chomp $ret;
    return $ret;
}

sub get_rpm_info
{
    my $ret = `rpm --queryformat "[%{NAME}] [%{VERSION}] [%{RELEASE}] [%{DESCRIPTION}]" -qp @_ 2>/dev/null`;
    chomp $ret;
    return $ret;
}

sub supported32bit
{
    if ($arch =~ /i[0-9]86|ia64|ppc|arm|aarch/
			or $rpm_distro =~ /sles1[2-9]|sles11sp4|windriver6|xenserver|bluenix1/){
        print("Detected $rpm_distro $arch. Disabling buidling 32bit rpms...\n") if ($verbose);
        return 0;
    }

    return 1;
}

# Check whether compiler $1 exist
sub set_compilers
{
    if (`which gcc 2> /dev/null`) {
        $gcc{'gcc'} = 1;
    }
    if (`which g77 2> /dev/null`) {
        $gcc{'g77'} = 1;
    }
    if (`which g++ 2> /dev/null`) {
        $gcc{'g++'} = 1;
    }
    if (`which gfortran 2> /dev/null`) {
        $gcc{'gfortran'} = 1;
    }

    if (`which pathcc 2> /dev/null`) {
        $pathscale{'pathcc'} = 1;
    }
    if (`which pathCC 2> /dev/null`) {
        $pathscale{'pathCC'} = 1;
    }
    if (`which pathf90 2> /dev/null`) {
        $pathscale{'pathf90'} = 1;
    }

    if (`which pgcc 2> /dev/null`) {
        $pgi{'pgcc'} = 1;
    }
    if (`which pgCC 2> /dev/null`) {
        $pgi{'pgCC'} = 1;
    }
    if (`which pgf77 2> /dev/null`) {
        $pgi{'pgf77'} = 1;
    }
    if (`which pgf90 2> /dev/null`) {
        $pgi{'pgf90'} = 1;
    }

    if (`which icc 2> /dev/null`) {
        $intel{'icc'} = 1;
    }
    if (`which icpc 2> /dev/null`) {
        $intel{'icpc'} = 1;
    }
    if (`which ifort 2> /dev/null`) {
        $intel{'ifort'} = 1;
    }
}

sub set_cfg
{
    my $srpm_full_path = shift @_;

    my $info = get_rpm_info($srpm_full_path);
    my $name = (split(/ /,$info,4))[0];
    my $version = (split(/ /,$info,4))[1];

    ( $main_packages{$name}{$version}{'name'},
      $main_packages{$name}{$version}{'version'},
      $main_packages{$name}{$version}{'release'},
      $main_packages{$name}{$version}{'description'} ) = split(/ /,$info,4);
      $main_packages{$name}{$version}{'srpmpath'}   = $srpm_full_path;

    print_and_log("set_cfg: " .
             "name: $name, " .
             "original name: $main_packages{$name}{$version}{'name'}, " .
             "version: $main_packages{$name}{$version}{'version'}, " .
             "release: $main_packages{$name}{$version}{'release'}, " .
             "srpmpath: $main_packages{$name}{$version}{'srpmpath'}\n", $verbose3);

    # mpitests needs to be compiled with all available openmpi/mvapich versions.
    if ($name =~ /openmpi|mvapich/) {
        add_new_mpitests_pkg($name, $version);
    }
}

sub add_new_mpitests_pkg
{
    my $name = shift @_;
    my $version = shift @_;

    # clone mpitests node
    my $dlver = $version;
    $dlver =~ s/\./_/g;
    my $newName = "mpitests_$name";
    clone_pkg_info_node("mpitests", $newName);
    # enable it
    $packages_info{$newName}{'available'} = 1;
    $packages_info{$newName}{'base_mpi_version'} = "$version";
    # add requirements
    push(@{$packages_info{$newName}{'ofa_req_build'}}, $name);
    push(@{$packages_info{$newName}{'ofa_req_inst'}}, $name);
    # add it to relevant packages groups
    push(@user_packages, $newName);
    push(@all_packages, $newName);
    push(@hpc_user_packages, $newName);
    push(@guest_user_packages, $newName);
    push(@mpi_packages, $newName);
}

sub clone_pkg_info_node
{
    my $name = shift @_;
    my $new_name = shift @_;

    for my $key (keys %{$packages_info{$name}}) {
        if(ref($packages_info{$name}{$key}) eq 'ARRAY') {
            # copy array content, not ref
            @{$packages_info{$new_name}{$key}} = @{$packages_info{$name}{$key}};
        } else {
            $packages_info{$new_name}{$key} = $packages_info{$name}{$key};
        }
    }
}

# set a given property to a given value for all packages with name matching the given name.
sub set_property_for_packages_like
{
    my $name = shift @_;
    my $property = shift @_;
    my $value = shift @_;

    for my $key (keys %packages_info) {
        if ($key =~ /$name/) {
            $packages_info{$key}{$property} = $value;
        }
    }
}

sub disable_package
{
    my $key = shift;

    if (exists $packages_info{$key}) {
        $packages_info{$key}{'available'} = 0;
        for my $requester (@{$packages_deps{$key}{'required_by'}}) {
            disable_package($requester);
        }
    }
    # modules
    if (exists $kernel_modules_info{$key}) {
        $kernel_modules_info{$key}{'available'} = 0;
        for my $requester (@{$modules_deps{$key}{'required_by'}}) {
            disable_package($requester);
        }
    }

    if (not (exists $packages_info{$key} or exists $kernel_modules_info{$key})) {
        print_and_log_colored("Unsupported package: $key", (not $quiet), "YELLOW");
    }
}

# The subdirectory a package should reside in
sub package_subdir($) {
    my $rpm_name = shift;

    if ($packages_info{$rpm_name}{'mode'} ne "user" or
        $rpm_name eq "mlnx-ofa_kernel") { # to match set_availability
        return "COMMON"
    }
    if ($use_upstream_libs) {
        return "UPSTREAM_LIBS";
    } else {
        return "MLNX_LIBS";
    }
}

# used for blocking packages that are replaced with rdma-core and vice versa
sub block_package
{
    my $key = shift;

    if (exists $packages_info{$key}) {
        $packages_info{$key}{'available'} = 0;
        $packages_info{$key}{'disabled'} = 1;
    }
    # modules
    if (exists $kernel_modules_info{$key}) {
        $kernel_modules_info{$key}{'available'} = 0;
        $kernel_modules_info{$key}{'disabled'} = 1;
    }
}

sub enable_package
{
    my $key = shift;

    if (exists $packages_info{$key}) {
        $packages_info{$key}{'available'} = 1;
        for my $req ( @{ $packages_info{$key}{'ofa_req_inst'} } ) {
            enable_package($req);
        }
    }
}

sub enable_module
{
    my $key = shift;

    if (exists $kernel_modules_info{$key}) {
        $kernel_modules_info{$key}{'available'} = 1;
        for my $req ( @{ $kernel_modules_info{$key}{'requires'} } ) {
            enable_module($req);
        }
    }
}

sub add_enabled_pkgs_by_user
{
    ##############
    # handle with/enable flags
    for my $key ( keys %force_enable_packages ) {
        ### fix kernel package name
	# backward compatibility for old rpm name
        if ($key =~ /kernel-ib/) {
            $key =~ s/kernel-ib/mlnx-ofa_kernel/g;
        }
        # if kmp not supported
        if ($key eq "mlnx-ofa_kernel" and not $kmp) {
            $key =~ s/mlnx-ofa_kernel/mlnx-ofa_kernel-modules/;
        }
        if ($key =~ m/kernel-mft-mlnx|ummunotify-mlnx/ and not $kmp) {
            $key =~ s/-mlnx//;
        }
        if ($key eq "mlnx-en" and not $kmp) {
            $key = "mlnx_en";
        }
        if ($key eq "knem" and not $kmp) {
            # knem (user space) will be added automatically since knem-modules needs it
            $key = "knem-modules";
        }
        # if kmp supported
        if ($key eq "mlnx-ofa_kernel-modules" and $kmp) {
            $key =~ s/mlnx-ofa_kernel-modules/mlnx-ofa_kernel/;
        }
        if ($key =~ m/kernel-mft|ummunotify/ and $key !~ m/mlnx/ and $kmp) {
            $key .= "-mlnx";
        }
        if ($key eq "mlnx_en" and $kmp) {
            $key = "mlnx-en";
        }
        if ($key eq "knem-modules" and $kmp) {
            $key = "knem";
        }

        if (exists $packages_info{$key}) {
            next if ($packages_info{$key}{'disabled'});
            enable_package($key);
            push (@selected_by_user, $key);
        }
        if (exists $kernel_modules_info{$key}) {
            next if ($kernel_modules_info{$key}{'disabled'});
            enable_module($key);
            push (@selected_modules_by_user , $key);
        }

        if (not (exists $packages_info{$key} or exists $kernel_modules_info{$key})) {
            print_and_log_colored("Unsupported package: $key", (not $quiet), "YELLOW");
        }
    }
}

sub check_autofconf
{
    my $VAR = shift;

    my $value = `tac ${kernel_sources}/include/*/autoconf.h 2>/dev/null | grep -m1 ${VAR} 2>/dev/null | sed -ne 's/.*\\\([01]\\\)\$/\\1/gp' 2>/dev/null`;
    chomp $value;
    if ($value eq "") {
        $value = 0;
    }

    return $value;
}

# Set packages availability depending OS/Kernel/arch
sub set_availability
{
    set_compilers();

    if ($user_space_only) {
        $packages_info{"mlnx-ofa_kernel"}{"mode"} = "user";
    }

    if ($is_bf eq "1") {
        $packages_info{'rshim'}{'available'} = 0;
    }

    if ($DISTRO =~ /SLES11|XenServer6/) {
        $packages_info{'rshim'}{'available'} = 0;
    }

    if ($arch =~ m/aarch64/ and $DISTRO =~ /ALTERNATE/) {
        if ($with_bluefield) {
            # VMA is not suported on BF
            $packages_info{'libvma'}{'available'} = 0;
            $packages_info{'libvma-utils'}{'available'} = 0;
            $packages_info{'libvma-devel'}{'available'} = 0;
            $packages_info{'libvma-debuginfo'}{'available'} = 0;
            $packages_info{'sockperf'}{'available'} = 0;
            $packages_info{'sockperf-debuginfo'}{'available'} = 0;
        }
    } else {
        for my $package (@bf_only_kernel_packages) {
            $packages_info{$package}{'available'} = 0;
        }
        $packages_info{'libpka'}{'available'} = 0;
        $packages_info{'spdk'}{'available'} = 0;
        $packages_info{'mlxbf-bootctl'}{'available'} = 0;
        $packages_info{'mlxbf-bootimages'}{'available'} = 0;
        $packages_info{'bfscripts'}{'available'} = 0;
    }

    if ($arch =~ m/aarch64/ and $DISTRO =~ m/ALTERNATE/) {
        $packages_info{'nvme-snap'}{'available'} = 1;
    }

    if ($kernel =~ /^4\.5/) {
        $packages_info{'tmfifo'}{'available'} = 0;
    }

    if ($DISTRO !~ /RHEL7/) {
        $packages_info{'openvswitch'}{'available'} = 0;
    }

    # require numa stuff where supported inbox
    if ($DISTRO =~ /RHEL|OL|FC|POWERKVM|EULEROS/) {
        $have_numa_libs = 1;
        push(@{$packages_info{'openmpi'}{'dist_req_build'}}, 'numactl-devel');
        push(@{$packages_info{'ucx'}{'dist_req_build'}}, 'numactl-devel');
        push(@{$packages_info{'hcoll'}{'dist_req_build'}}, 'numactl-devel');
        push(@{$packages_info{"$libmlx5"}{'dist_req_build'}}, "numactl-devel$suffix_64bit");
        push(@{$packages_info{"$libmlx5"}{'dist_req_build'}}, "numactl-devel$suffix_32bit") if ($build32 == 1);

        my $numactl = "numactl";
        if ($DISTRO =~ /FC19|FC[2-9]|OL[7-9]|RHEL[7-9]|POWERKVM|EULEROS/) {
            $numactl = "numactl-libs";
        }
        push(@{$packages_info{'openmpi'}{'dist_req_inst'}}, "$numactl");
        push(@{$packages_info{'ucx'}{'dist_req_inst'}}, "$numactl");
        push(@{$packages_info{'hcoll'}{'dist_req_inst'}}, "$numactl");
        push(@{$packages_info{"$libmlx5"}{'dist_req_inst'}}, "${numactl}${suffix_64bit}");
        push(@{$packages_info{"$libmlx5"}{'dist_req_inst'}}, "${numactl}${suffix_32bit}") if ($build32 == 1);
    }

    # mvapich and openmpi
    if ($gcc{'gcc'}) {
        if ($gcc{'g77'} or $gcc{'gfortran'}) {
            $packages_info{'mvapich2'}{'available'} = 1;
            set_property_for_packages_like('mpitests_mvapich', 'available', 1);
        }
        $packages_info{'openmpi'}{'available'} = 1;
        set_property_for_packages_like('mpitests_openmpi', 'available', 1);
    }

    if ($arch !~ m/x86_64|ppc64le|aarch|arm/ or $DISTRO =~ /RHEL5|XenServer/) {
        for my $package (@mpi_packages) {
            $packages_info{$package}{'available'} = 0;
        }
        $packages_info{'mxm'}{'available'} = 0;
        $packages_info{'ucx'}{'available'} = 0;
        $packages_info{'ucx-devel'}{'available'} = 0;
        $packages_info{'ucx-static'}{'available'} = 0;
        $packages_info{'ucx-cma'}{'available'} = 0;
        $packages_info{'ucx-ib'}{'available'} = 0;
        $packages_info{'ucx-ib-cm'}{'available'} = 0;
        $packages_info{'ucx-rdmacm'}{'available'} = 0;
        $packages_info{'fca'}{'available'} = 0;
        $packages_info{"$knem_rpm"}{'available'} = 0;
        $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
        $packages_info{'openshmem'}{'available'} = 0;
        $packages_info{'bupc'}{'available'} = 0;
        $packages_info{"$ummunotify_rpm"}{'available'} = 0;
        $packages_info{'libibprof'}{'available'} = 0;
        $packages_info{'hcoll'}{'available'} = 0;
        $packages_info{'sharp'}{'available'} = 0;
    }

    # SRP Target
    if ($DISTRO =~ m/SLES10|SLES11|RHEL5.[34]/ or $kernel =~ m/2.6.2[7-9]|2.6.3[0-2]/) {
        $kernel_modules_info{'srpt'}{'available'} = 0;
    }

    if ($DISTRO =~ m/SLES10/) {
        $kernel_modules_info{'mthca'}{'available'} = 0;
        $kernel_modules_info{'mlx4_en'}{'available'} = 0;
        $kernel_modules_info{'mlx4_vnic'}{'available'} = 0;
        $kernel_modules_info{'e_ipoib'}{'available'} = 0;
        $kernel_modules_info{'nfsrdma'}{'available'} = 0;
        $kernel_modules_info{'srp'}{'available'} = 0;
        $kernel_modules_info{'iser'}{'available'} = 0;
        $kernel_modules_info{'isert'}{'available'} = 0;
        $kernel_modules_info{'rds'}{'available'} = 0;
        $kernel_modules_info{'sdp'}{'available'} = 0;
        $kernel_modules_info{'srpt'}{'available'} = 0;
        $packages_info{'knem'}{'available'} = 0;
        $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
        $packages_info{'ummunotify'}{'available'} = 0;
        $packages_info{'ummunotify-mlnx'}{'available'} = 0;
        $packages_info{'libvma'}{'available'} = 0;
        $packages_info{'libvma-utils'}{'available'} = 0;
        $packages_info{'libvma-devel'}{'available'} = 0;
        $packages_info{'libvma-debuginfo'}{'available'} = 0;
        $packages_info{'sockperf'}{'available'} = 0;
        $packages_info{'sockperf-debuginfo'}{'available'} = 0;
        $packages_info{"$srptools"}{'available'} = 0;
        $packages_info{'rds-tools'}{'available'} = 0;
        $packages_info{'rds-devel'}{'available'} = 0;
        $packages_info{'infinipath-psm'}{'available'} = 0;
        $packages_info{'infinipath-psm-devel'}{'available'} = 0;
        for my $package (@mpi_packages) {
            $packages_info{$package}{'available'} = 0;
        }
        $packages_info{'mxm'}{'available'} = 0;
        $packages_info{'ucx'}{'available'} = 0;
        $packages_info{'ucx-devel'}{'available'} = 0;
        $packages_info{'ucx-static'}{'available'} = 0;
        $packages_info{'ucx-cma'}{'available'} = 0;
        $packages_info{'ucx-ib'}{'available'} = 0;
        $packages_info{'ucx-ib-cm'}{'available'} = 0;
        $packages_info{'ucx-rdmacm'}{'available'} = 0;
        $packages_info{'fca'}{'available'} = 0;
        $packages_info{"$knem_rpm"}{'available'} = 0;
        $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
        $packages_info{'openshmem'}{'available'} = 0;
        $packages_info{'bupc'}{'available'} = 0;
        $packages_info{"$ummunotify_rpm"}{'available'} = 0;
        $packages_info{'libibprof'}{'available'} = 0;
        $packages_info{'hcoll'}{'available'} = 0;
        $packages_info{'sharp'}{'available'} = 0;
        $packages_info{'iser'}{'available'} = 0;
        $packages_info{'isert'}{'available'} = 0;
        $packages_info{'srp'}{'available'} = 0;
        $packages_info{'mlnx-sdp'}{'available'} = 0;
        $packages_info{'mlnx-rds'}{'available'} = 0;
        $packages_info{'mlnx-nfsrdma'}{'available'} = 0;
        $packages_info{'mlnx-nvme'}{'available'} = 0;
        $packages_info{'mlnx-rdma-rxe'}{'available'} = 0;
    }

    if ($DISTRO =~ m/WINDRIVER6/) {
        $kernel_modules_info{'mthca'}{'available'} = 0;
        $kernel_modules_info{'nfsrdma'}{'available'} = 0;
        $packages_info{'mlnx-nfsrdma'}{'available'} = 0;
        $packages_info{'mlnx-nvme'}{'available'} = 0;
        $packages_info{'mlnx-rdma-rxe'}{'available'} = 0;
        $kernel_modules_info{'rds'}{'available'} = 0;
        $packages_info{'mlnx-rds'}{'available'} = 0;
        $kernel_modules_info{'sdp'}{'available'} = 0;
        $packages_info{'mlnx-sdp'}{'available'} = 0;
        $kernel_modules_info{'srpt'}{'available'} = 0;
        $kernel_modules_info{'amso1100'}{'available'} = 0;
        $packages_info{'knem'}{'available'} = 0;
        $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
        $packages_info{'ummunotify'}{'available'} = 0;
        $packages_info{'ummunotify-mlnx'}{'available'} = 0;
        $packages_info{'ibutils'}{'available'} = 0;
        $packages_info{'rds-tools'}{'available'} = 0;
        $packages_info{'rds-devel'}{'available'} = 0;
        $packages_info{'infinipath-psm'}{'available'} = 0;
        $packages_info{'infinipath-psm-devel'}{'available'} = 0;
        for my $package (@mpi_packages) {
            $packages_info{$package}{'available'} = 0;
        }
        $packages_info{'mxm'}{'available'} = 0;
        $packages_info{'ucx'}{'available'} = 0;
        $packages_info{'ucx-devel'}{'available'} = 0;
        $packages_info{'ucx-static'}{'available'} = 0;
        $packages_info{'ucx-cma'}{'available'} = 0;
        $packages_info{'ucx-ib'}{'available'} = 0;
        $packages_info{'ucx-ib-cm'}{'available'} = 0;
        $packages_info{'ucx-rdmacm'}{'available'} = 0;
        $packages_info{'fca'}{'available'} = 0;
        $packages_info{"$knem_rpm"}{'available'} = 0;
        $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
        $packages_info{'openshmem'}{'available'} = 0;
        $packages_info{'bupc'}{'available'} = 0;
        $packages_info{"$ummunotify_rpm"}{'available'} = 0;
        $packages_info{'libibprof'}{'available'} = 0;
        $packages_info{'hcoll'}{'available'} = 0;
        $packages_info{'sharp'}{'available'} = 0;
    }

    if (is_installed("cuda-cudart-dev-$cuda_version")) {
        my $cuda_dir_name = $cuda_version;
        $cuda_dir_name =~ y/-/./;
        $cuda_top_dir = "/usr/local/cuda-$cuda_dir_name";
        $packages_info{'ucx-cuda'}{'available'} = 1;
    }
    if (is_installed("gdrcopy-devel")) {
        $packages_info{'ucx-gdrcopy'}{'available'} = 1;
    }

    # UBUNTU
    if ($DISTRO =~ m/UBUNTU/) {
        $packages_info{'ibutils2'}{'available'} = 0; #compilation failed
        $packages_info{'ibutils'}{'available'} = 0; #compilation failed
        $packages_info{'ar_mgr'}{'available'} = 0; #compilation failed
        $packages_info{'cc_mgr'}{'available'} = 0; #compilation failed
        $packages_info{'dump_pr'}{'available'} = 0; #compilation failed
    }

    if ( not $with_vma or ($arch !~ m/x86_64|ppc64/) or $DISTRO =~ /XenServer|WINDRIVER6/) {
       $packages_info{'libvma'}{'available'} = 0;
       $packages_info{'libvma-utils'}{'available'} = 0;
       $packages_info{'libvma-devel'}{'available'} = 0;
       $packages_info{'libvma-debuginfo'}{'available'} = 0;
       $packages_info{'sockperf'}{'available'} = 0;
       $packages_info{'sockperf-debuginfo'}{'available'} = 0;
    }

    # disable sockperf on SLES due to build issues
    if ($DISTRO =~ /POWERKVM/) {
       $packages_info{'sockperf'}{'available'} = 0;
       $packages_info{'sockperf-debuginfo'}{'available'} = 0;
    }

    # enable fabric-collector only if --with-fabric-collector was given and the OS is supported.
    if ( not ($with_fabric_collector and
             ($DISTRO =~ /RHEL6/ or
              $DISTRO =~ /RHEL7/ or
              $rpm_distro =~ /sles11sp/ or
              $rpm_distro =~ /sles12sp/)) ) {
       $packages_info{'fabric-collector'}{'available'} = 0;
       $packages_info{'fabric-collector-debuginfo'}{'available'} = 0;
       print_and_log_colored("Unsupported package: fabric-collector", (not $quiet), "YELLOW") if ($with_fabric_collector);
    }

    if ($arch =~ /arm|aarch/i) {
        $packages_info{'dapl'}{'available'} = 0;
        $packages_info{'dapl-devel'}{'available'} = 0;
        $packages_info{'dapl-devel-static'}{'available'} = 0;
        $packages_info{'dapl-utils'}{'available'} = 0;
        $packages_info{'dapl-debuginfo'}{'available'} = 0;
        $packages_info{'fca'}{'available'} = 0;
        $packages_info{'mxm'}{'available'} = 0;
    }

    if ($kernel =~ /fbk/ or $arch =~ /arm|aarch/) {
       $kernel_modules_info{'sdp'}{'available'} = 0;
       $packages_info{'libsdp'}{'available'} = 0;
       $packages_info{'libsdp-devel'}{'available'} = 0;
       $packages_info{'libsdp-debuginfo'}{'available'} = 0;
       $packages_info{'sdpnetstat'}{'available'} = 0;
       $packages_info{'sdpnetstat-debuginfo'}{'available'} = 0;
       $packages_info{'mlnx-sdp'}{'available'} = 0;
    }

    if ($kernel =~ /fbk36/) {
       $kernel_modules_info{'rds'}{'available'} = 0;
    }
    # turn on isert if we are on follow OS and arch
    if (not ($rpm_distro =~ /
            rhel7u[2-7] | rhel8u[0-1] |
            ol7u4 |
            sles11sp4 | sles12sp[1-5] | sles15sp[01] |
            fc2[789]
        /x and $kernel =~ /
            fbk16 | ^4\.[4-9] | ^4\.1[0-9]\. | ^4\.20 |
            ^4\.1\.12-94 |                                  # OL7.4
            3.10.0-.*el7 | 3.12.28-4 | 3.12.49- | 3.12.48- |
            4\.18\.0-.*el8
        /x
    )) {
       $kernel_modules_info{'isert'}{'available'} = 0;
       $packages_info{'isert'}{'available'} = 0;
    }

    if ($DISTRO =~ /SLES12/ and $arch =~ m/x86_64/) {
       $packages_info{'libopensmssa'}{'available'} = 1;
       $packages_info{'libopensmssa-debuginfo'}{'available'} = 1;
       $packages_info{'ibssa'}{'available'} = 1;
       $packages_info{'ibssa-debuginfo'}{'available'} = 1;
       $packages_info{'ibacm_ssa'}{'available'} = 1;
       $packages_info{'ibacm_ssa-devel'}{'available'} = 1;
       $packages_info{'ibacm_ssa-debuginfo'}{'available'} = 1;
    }

    if ($with_libdisni and $rpm_distro =~ /sles12sp2|sles12sp3|rhel7/ and $rpm_distro ne "rhel7u0") {
       $packages_info{'libdisni'}{'available'} = 1;
       $packages_info{'libdisni-devel'}{'available'} = 1;
       $packages_info{'libdisni-debuginfo'}{'available'} = 1;
    }

    if ($DISTRO =~ /RHEL6.4|RHEL6.5|RHEL7\.[0-5]/ and $arch =~ m/x86_64/) {
       $packages_info{'multiperf'}{'available'} = 1;
       $packages_info{'multiperf-debuginfo'}{'available'} = 1;
    }

    if (($arch ne 'x86_64') or ($kernel !~ /
              ^4\.12\.14-94 # SLES12 SP4
            | ^4\.12\.14-23 # SLES15 SP0
            | ^3\.10\.0-862 # RHEL 7.5
            | ^3\.10\.0-957 # RHEL 7.6
            /x) or
        $rpm_distro =~ /euleros/
    ) {
        $kernel_modules_info{'nfsrdma'}{'available'} = 0;
        $packages_info{'mlnx-nfsrdma'}{'available'} = 0;
    }

    if ($DISTRO =~ m/FC2[4-9] | SLES15 | RHEL8 | OL8 | EULEROS2.0SP8/x) {
        $packages_info{'ibutils'}{'available'} = 0; #compilation failed with GCC6
    }

    if ($DISTRO =~ m/FC29 | RHEL8 | OL8 | EULEROS2.0SP8/x) {
        $packages_info{'mxm'}{'available'} = 0; # deprecated
    }

    if ($DISTRO =~ m/XenServer6/) {
        $packages_info{'srptools'}{'available'} = 0; #compilation failed
    }

    if (
        ($kernel =~ /lustre/) or
        not (
            ($kernel =~ /^4\.[8-9]|^4\.[12][0-9]/) or
            ($rpm_distro =~ /sles12sp3/ and $kernel =~ /^4\.4/) or
            ($rpm_distro =~ /sles12sp4/ and $kernel =~ /^4\.12/) or
            ($DISTRO =~ /RHEL7.[2-7]|RHEL6.3/ and $kernel =~ /3.10.0/)
        )
    ) {
        $packages_info{'mlnx-nvme'}{'available'} = 0;
    }

    my $CONFIG_NET_UDP_TUNNEL = check_autofconf('CONFIG_NET_UDP_TUNNEL');
    if ($kernel !~ /^4\.[8-9]|^4\.1[0-9]\./ or $CONFIG_NET_UDP_TUNNEL ne "1") {
        $packages_info{'mlnx-rdma-rxe'}{'available'} = 0;
    }
    # turn off srp and iser if we are not on follow OS and arch
    if (not ($rpm_distro =~ /
            rhel6u[8-9] | rhel6u10 | rhel7u[1-7] | rhel8u[01] |
            ol6u9 | ol7u4 |
            sles11sp[3-4] | sles12sp[1-5] | sles15sp[01] |
            fc2[789]
        /x and $kernel =~ /
            ^4\.[0-9] | ^3.1[6-9] |
            3.10.0.*el7.* | 3.*-default | 2.6.32.*el6.*
        /x)
    ) {
        $kernel_modules_info{'srp'}{'available'} = 0;
        $packages_info{'srp'}{'available'} = 0;
        $kernel_modules_info{'iser'}{'available'} = 0;
        $packages_info{'iser'}{'available'} = 0;
    }

    # disable iproute2 for unsupported OSs
    if ($rpm_distro =~ /fc23|powerkvm|xenserver|windriver|euleros|sles11sp/) {
        $packages_info{'mlnx-iproute2'}{'available'} = 0;
    }

    if ($arch =~ /ppc64/ and $rpm_distro =~ /rhel7u[0-1]/) {
        $packages_info{'mlnx-iproute2'}{'available'} = 0;
    }

    # disable iproute2 for unsupported OSs
    if ($rpm_distro =~ /fc23|powerkvm|xenserver|windriver|euleros|sles11sp/) {
        $packages_info{'mlnx-iproute2'}{'available'} = 0;
    }

    if ($arch =~ /ppc64/ and $rpm_distro =~ /rhel7u[0-1]/) {
        $packages_info{'mlnx-iproute2'}{'available'} = 0;
    }

    if ($rpm_distro eq "sles11sp1") {
        $kernel_modules_info{'mlx4_en'}{'available'} = 0;
    }

    if (not ($kernel =~ /^4.[0-9]|^3.1[0-9]/)) {
        $kernel_modules_info{'mlx5_fpga_tools'}{'available'} = 0;
    }

    if ($DISTRO !~ m/RHEL7.[2-9]/ and $kernel !~ /^4\.|^5\./) {
        $kernel_modules_info{'mdev'}{'available'} = 0;
    }

    if ($DISTRO eq 'EULEROS2.0SP8') {
        block_package("openmpi");
        block_package("ucx");
    }

    # make sure user cannot force adding disabled package using --with flag
    if ($use_upstream_libs) {
        block_package("infiniband-diags-compat");
        block_package("infiniband-diags-guest");
        block_package("libibverbs-devel");
        block_package("libibverbs-devel-static");
        block_package("libibverbs-debuginfo");
        block_package("libmlx4");
        block_package("libmlx4-devel");
        block_package("libmlx4-debuginfo");
        block_package("libmlx5");
        block_package("libmlx5-devel");
        block_package("libmlx5-debuginfo");
        block_package("librxe");
        block_package("librxe-devel-static");
        block_package("librxe-debuginfo");
        block_package("libibcm");
        block_package("libibcm-devel");
        block_package("libibcm-debuginfo");
        block_package("libibumad-devel");
        block_package("libibumad-static");
        block_package("libibumad-debuginfo");
        block_package("libibmad");
        block_package("libibmad-devel");
        block_package("libibmad-static");
        block_package("libibmad-debuginfo");
        block_package("librdmacm-devel");
        block_package("librdmacm-debuginfo");
        block_package("srptools");
        block_package("ibsim");
        block_package("ibsim-debuginfo");
        block_package("multiperf");
        block_package("multiperf-debuginfo");
        block_package("openmpi");
        block_package("sharp");
        block_package("ucx-ib-cm");
    } else {
        block_package("rdma-core");
        block_package("rdma-core-devel");
        block_package("rdma-core-debuginfo");
        block_package("rdma-core-static");
        block_package("srp_daemon");
        block_package("nvme-snap");
    }

    ##############
    # handle without/disable flags
    if (keys %disabled_packages) {
        # build deps list
        for my $pkg (keys %packages_info) {
            for my $req ( @{ $packages_info{$pkg}{'ofa_req_inst'}} , @{ $packages_info{$pkg}{'ofa_req_build'}} ) {
                next if not $req;
                push (@{$packages_deps{$req}{'required_by'}}, $pkg);
            }
        }
        for my $mod (keys %kernel_modules_info) {
            for my $req ( @{ $kernel_modules_info{$mod}{'requires'} } ) {
                next if not $req;
                push (@{$modules_deps{$req}{'required_by'}}, $mod);
            }
        }
        # disable packages
        for my $key ( keys %disabled_packages ) {
            disable_package($key);
        }
    }
    # end of handle without/disable flags

    #
    # keep this at the end of the function.
    #
    # debuginfo RPM currently are not supported on SuSE and Ubuntu
    if ($DISTRO =~ m/SLES|DEBIAN|UBUNTU|SUSE|WINDRIVER6|POWERKVM/) {
        for my $package (@all_packages) {
            if ($package =~ m/-debuginfo/) {
                $packages_info{$package}{'available'} = 0;
            }
        }
    }

    my $glibc_ver_str = get_rpm_ver_one($glibc_devel);
    my @glibc_ver = split(/[.]/, $glibc_ver_str);
    if (($glibc_ver[0] < 2) or
        (($glibc_ver[0] == 2) and $glibc_ver[1] < 15)
    ) {
        $packages_info{'ucx-cma'}{'available'} = 0;
    }

    add_enabled_pkgs_by_user();
}

# Set rpm_exist parameter for existing RPMs
sub set_existing_rpms
{
    # Check if the ofed-scripts RPM exist and its prefix is the same as required one
    my $scr_rpm = '';
    my $arch = $target_cpu;
    my $subdir;

    $subdir = package_subdir('ofed-scripts');
    $scr_rpm = <$RPMS/$subdir/ofed-scripts-[0-9]*.$arch.rpm>;
    if ( -e $scr_rpm ) {
        my $current_prefix = `rpm -qlp $scr_rpm 2>/dev/null | grep ofed_info | sed -e "s@/bin/ofed_info@@"`;
        chomp $current_prefix;
        print_and_log("Found $scr_rpm. Its installation prefix: $current_prefix\n", $verbose2);
        if (not $current_prefix eq $prefix) {
            print_and_log("Required prefix is: $prefix\n", $verbose2);
            print_and_log("Going to rebuild RPMs from scratch\n", $verbose2);
            return;
        }
    }

    my $glob = "$RPMS/$COMMON_DIR/*.rpm";
    if ($use_upstream_libs) {
        $glob .= " $RPMS/$UPSTREAM_LIBS_DIR/*.rpm";
    } else {
        $glob .= " $RPMS/$MLNX_LIBS_DIR/*.rpm";
    }
    for my $binrpm (glob $glob) {
        my ($rpm_name, $rpm_arch) = (split ' ', get_rpm_name_arch($binrpm));
        my $ver = get_rpm_ver($binrpm);
        my $ver_no_rel = $ver; #version without kernel release
        $ver_no_rel =~ s/_.*//g;
        my $kernel_from_release = get_rpm_rel($binrpm);
        chomp $kernel_from_release;
        $kernel_from_release =~ s/.*\.kver\.//g;
        $kernel_from_release =~ s/_OFED.*//g;

        if ($DISTRO =~ /RHEL5|XenServer/ and $arch eq "i386" and $rpm_name =~ /ofa_kernel/) {
            $arch = 'i686';
        }
        if ($rpm_name =~ /$bf_krpm_regex|ib-bonding|knem-modules|kernel-mft|mlx4_accl|ummunotify$|iser|srp$|mlnx_en|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/ and
            $rpm_name !~ /kmp|kmod/) {
            if ($kmp) {
                print_and_log("KMP=1 -> ignoring $rpm_name $ver\n", $verbose2);
                next;
            }
            if (($rpm_arch eq $arch) and ("$kernel_from_release" eq "$kernel_rel")) {
                $main_packages{$rpm_name}{$ver}{'rpmpath'} = $binrpm;
                $packages_info{$rpm_name}{$ver}{'rpm_exist'} = 1;
                print_and_log("$rpm_name $ver RPM exist\n", $verbose2);
            }

        } elsif ($rpm_name =~ /mlnx-ofa_kernel-modules/) {
            if (($rpm_arch eq $arch) and ("$kernel_from_release" eq "$kernel_rel")) {
                $main_packages{$rpm_name}{$ver}{'rpmpath'} = $binrpm;
                $packages_info{$rpm_name}{$ver}{'rpm_exist'} = 1;
                print_and_log("$rpm_name $ver RPM exist\n", $verbose2);
            }

        # W/A for kmp packages that has only kmod and kmp rpms
        } elsif ($rpm_name =~ /kmp|kmod/ and
                 $rpm_name =~ /$bf_krpm_regex|kernel-mft-mlnx|iser|srp|mlnx-en|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/) {
                if (not $kmp) {
                    print_and_log("KMP=0 -> ignoring $rpm_name $ver\n", $verbose2);
                    next;
                }
                my $pkname = $rpm_name;
                $pkname =~ s/kmod-//g;
                $pkname =~ s/-kmp.*//g;
                $main_packages{$rpm_name}{$ver}{'rpmpath'} = $binrpm;
                $packages_info{"$rpm_name"}{$ver}{'rpm_exist'} = 1;
                $packages_info{"$pkname"}{$ver}{'rpm_exist'} = 1;
                $packages_info{"$pkname"}{$ver_no_rel}{'rpm_exist'} = 1;
                print_and_log("$rpm_name $ver ($pkname) RPM exist\n", $verbose2);
        } else {
            if ($rpm_arch eq $arch and
                 ($rpm_name !~ /$bf_krpm_regex|iser|srp$|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/)) {
                $main_packages{$rpm_name}{$ver}{'rpmpath'} = $binrpm;
                $packages_info{$rpm_name}{$ver}{'rpm_exist'} = 1;
                print_and_log("$rpm_name $ver RPM exist\n", $verbose2);
            }
            elsif ($rpm_arch eq $target_cpu32) {
                $main_packages{$rpm_name}{$ver}{'rpmpath'} = $binrpm;
                $packages_info{$rpm_name}{$ver}{'rpm_exist32'} = 1;
                print_and_log("$rpm_name $ver 32-bit RPM exist\n", $verbose2);
            }
        }
        $arch = $target_cpu;
    }
}

sub mvapich2_config
{
    my $ans;
    my $done;

    if ($mvapich2_conf_done) {
        return;
    }

    if (not $interactive) {
        $mvapich2_conf_done = 1;
        return;
    }

    print "\nPlease choose an implementation of MVAPICH2:\n\n";
    print "1) OFA (IB and iWARP)\n";
    print "2) uDAPL\n";
    $done = 0;

    while (not $done) {
        print "Implementation [1]: ";
        $ans = getch();

        if (ord($ans) == $KEY_ENTER or $ans eq "1") {
            $mvapich2_conf_impl = "ofa";
            $done = 1;
        }

        elsif ($ans eq "2") {
            $mvapich2_conf_impl = "udapl";
            $done = 1;
        }

        else {
            $done = 0;
        }
    }

    print "\nEnable ROMIO support [Y/n]: ";
    $ans = getch();

    if ($ans =~ m/Nn/) {
        $mvapich2_conf_romio = 0;
    }

    else {
        $mvapich2_conf_romio = 1;
    }

    print "\nEnable shared library support [Y/n]: ";
    $ans = getch();

    if ($ans =~ m/Nn/) {
        $mvapich2_conf_shared_libs = 0;
    }

    else {
        $mvapich2_conf_shared_libs = 1;
    }

    # OFA specific options.
    if ($mvapich2_conf_impl eq "ofa") {
        $done = 0;

        while (not $done) {
            print "\nEnable Checkpoint-Restart support [y/N]: ";
            $ans = getch();

            if ($ans =~ m/[Yy]/) {
                $mvapich2_conf_ckpt = 1;
                print "\nBLCR installation directory [or nothing if not installed]: ";
                my $tmp = <STDIN>;
                chomp $tmp;

                if (-d "$tmp") {
                    $mvapich2_conf_blcr_home = $tmp;
                    $done = 1;
                }

                else {
                    print RED "\nBLCR installation directory not found.", RESET "\n";
                }
            }

            else {
                $mvapich2_conf_ckpt = 0;
                $done = 1;
            }
        }
    }

    else {
        $mvapich2_conf_ckpt = 0;
    }

    # uDAPL specific options.
    if ($mvapich2_conf_impl eq "udapl") {
        print "\nCluster size:\n\n1) Small\n2) Medium\n3) Large\n";
        $done = 0;

        while (not $done) {
            print "Cluster size [1]: ";
            $ans = getch();

            if (ord($ans) == $KEY_ENTER or $ans eq "1") {
                $mvapich2_conf_vcluster = "small";
                $done = 1;
            }

            elsif ($ans eq "2") {
                $mvapich2_conf_vcluster = "medium";
                $done = 1;
            }

            elsif ($ans eq "3") {
                $mvapich2_conf_vcluster = "large";
                $done = 1;
            }
        }

        print "\nI/O Bus:\n\n1) PCI-Express\n2) PCI-X\n";
        $done = 0;

        while (not $done) {
            print "I/O Bus [1]: ";
            $ans = getch();

            if (ord($ans) == $KEY_ENTER or $ans eq "1") {
                $mvapich2_conf_io_bus = "PCI_EX";
                $done = 1;
            }

            elsif ($ans eq "2") {
                $mvapich2_conf_io_bus = "PCI_X";
                $done = 1;
            }
        }

        if ($mvapich2_conf_io_bus eq "PCI_EX") {
            print "\nLink Speed:\n\n1) SDR\n2) DDR\n";
            $done = 0;

            while (not $done) {
                print "Link Speed [1]: ";
                $ans = getch();

                if (ord($ans) == $KEY_ENTER or $ans eq "1") {
                    $mvapich2_conf_link_speed = "SDR";
                    $done = 1;
                }

                elsif ($ans eq "2") {
                    $mvapich2_conf_link_speed = "DDR";
                    $done = 1;
                }
            }
        }

        else {
            $mvapich2_conf_link_speed = "SDR";
        }

        print "\nDefault DAPL provider []: ";
        $ans = <STDIN>;
        chomp $ans;

        if ($ans) {
            $mvapich2_conf_dapl_provider = $ans;
        }
    }

    $mvapich2_conf_done = 1;

    open(CONFIG, ">>$config") || die "Can't open $config: $!";;
    flock CONFIG, $LOCK_EXCLUSIVE;

    print CONFIG "mvapich2_conf_impl=$mvapich2_conf_impl\n";
    print CONFIG "mvapich2_conf_romio=$mvapich2_conf_romio\n";
    print CONFIG "mvapich2_conf_shared_libs=$mvapich2_conf_shared_libs\n";
    print CONFIG "mvapich2_conf_ckpt=$mvapich2_conf_ckpt\n";
    print CONFIG "mvapich2_conf_blcr_home=$mvapich2_conf_blcr_home\n" if ($mvapich2_conf_blcr_home);
    print CONFIG "mvapich2_conf_vcluster=$mvapich2_conf_vcluster\n";
    print CONFIG "mvapich2_conf_io_bus=$mvapich2_conf_io_bus\n" if ($mvapich2_conf_io_bus);
    print CONFIG "mvapich2_conf_link_speed=$mvapich2_conf_link_speed\n" if ($mvapich2_conf_link_speed);
    print CONFIG "mvapich2_conf_dapl_provider=$mvapich2_conf_dapl_provider\n" if ($mvapich2_conf_dapl_provider);

    flock CONFIG, $UNLOCK;
    close(CONFIG);
}

sub show_menu
{
    my $menu = shift @_;
    my $max_inp;

    print $clear_string;
    if ($menu eq "main") {
        print "$PACKAGE Distribution Software Installation Menu\n\n";
        print "   1) View $PACKAGE Installation Guide\n";
        print "   2) Install $PACKAGE Software\n";
        print "   3) Show Installed Software\n";
        print "   4) Configure IPoIB\n";
        print "   5) Uninstall $PACKAGE Software\n";
#        print "   6) Generate Supporting Information for Problem Report\n";
        print "\n   Q) Exit\n";
        $max_inp=5;
        print "\nSelect Option [1-$max_inp]:"
    }
    elsif ($menu eq "select") {
        print "$PACKAGE Distribution Software Installation Menu\n\n";
        print "   1) Basic ($PACKAGE modules and basic user level libraries)\n";
        print "   2) HPC ($PACKAGE modules and libraries, MPI and diagnostic tools)\n";
        print "   3) All packages (all of Basic, HPC)\n";
        print "   4) Customize\n";
        print "   5) Packages required by VMA (IB and Eth)\n";
        print "   6) Packages required by VMA IB\n";
        print "   7) Packages required by VMA Eth\n";
        print "   8) Packages required by Guest OS\n";
        print "   9) Packages required by Hypervisor OS\n";
        print "   10) Packages required by Bluefield OS\n";
        print "\n   Q) Exit\n";
        $max_inp=10;
        print "\nSelect Option [1-$max_inp]:"
    }

    return $max_inp;
}

# Select package for installation
sub select_packages
{
    my $cnt = 0;
    if ($interactive) {
        open(CONFIG, ">$config") || die "Can't open $config: $!";;
        flock CONFIG, $LOCK_EXCLUSIVE;
        my $ok = 0;
        my $inp;
        my $max_inp;
        while (! $ok) {
            $max_inp = show_menu("select");
            $inp = getch();
            if ($inp =~ m/[qQ]/ || $inp =~ m/[Xx]/ ) {
                die "Exiting\n";
            }
            if (ord($inp) == $KEY_ENTER) {
                next;
            }
            if ($inp =~ m/[0123456789abcdefABCDEF]/)
            {
                $inp = hex($inp);
            }
            if ($inp < 1 || $inp > $max_inp)
            {
                print "Invalid choice...Try again\n";
                next;
            }
            $ok = 1;
        }
        if ($inp == $BASIC) {
            for my $package (@basic_user_packages, @basic_kernel_packages) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @basic_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $HPC) {
            for my $package ( @hpc_user_packages, @hpc_kernel_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @hpc_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $VMA) {
            for my $package ( @vma_user_packages, @vma_kernel_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @vma_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $VMAVPI) {
            for my $package ( @vmavpi_user_packages, @vma_kernel_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @vma_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $VMAETH) {
            for my $package ( @vmaeth_user_packages, @vma_kernel_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @vma_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $GUESTOS) {
            for my $package ( @guest_kernel_packages,@guest_user_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
        }
        elsif ($inp == $HYPERVISOROS) {
            for my $package ( @hypervisor_kernel_packages,@hypervisor_user_packages) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available('srpmpath'));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
        }
        elsif ($inp == $BLUEFIELD) {
            $packages_info{"$knem_rpm"}{'available'} = 0;
            $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
            for my $package ( @bluefield_kernel_packages,@bluefield_user_packages) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if ($kernel_only and $packages_info{$package}{'mode'} ne 'kernel');
                next if (not is_srpm_available('srpmpath'));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @bluefield_kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $ALL) {
            for my $package ( @all_packages, @hidden_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @kernel_modules ) {
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }
        elsif ($inp == $CUSTOM) {
            my $ans;
            for my $package ( @all_packages ) {
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if (not is_srpm_available($parent));
                print "Install $package? [y/N]:";
                $ans = getch();
                if ( $ans eq 'Y' or $ans eq 'y' ) {
                    print CONFIG "$package=y\n";
                    push (@selected_by_user, $package);
                    $cnt ++;

                    if ($package =~ /ofa_kernel/) {
                        # Select kernel modules to be installed
                        for my $module ( @kernel_modules, @tech_preview ) {
                            next if (not $kernel_modules_info{$module}{'available'});
                            print "Install $module module? [y/N]:";
                            $ans = getch();
                            if ( $ans eq 'Y' or $ans eq 'y' ) {
                                push (@selected_modules_by_user, $module);
                                print CONFIG "$module=y\n";
                            }
                        }
                    }
                }
                else {
                    print CONFIG "$package=n\n";
                }
            }
            if ($arch eq "x86_64" or $arch eq "ppc64") {
                if (supported32bit()) {
                    print "Install 32-bit packages? [y/N]:";
                    $ans = getch();
                    if ( $ans eq 'Y' or $ans eq 'y' ) {
                        $build32 = 1;
                        print CONFIG "build32=1\n";
                    }
                    else {
                        $build32 = 0;
                        print CONFIG "build32=0\n";
                    }
                }
                else {
                    $build32 = 0;
                    print CONFIG "build32=0\n";
                }
            }
            print "Please enter the $PACKAGE installation directory: [$prefix]:";
            $ans = <STDIN>;
            chomp $ans;
            if ($ans) {
                $prefix = $ans;
                $prefix =~ s/\/$//;
            }
            print CONFIG "prefix=$prefix\n";
        }
        flock CONFIG, $UNLOCK;
    }
    else {
        if ($config_given) {
            open(CONFIG, "$config") || die "Can't open $config: $!";;
            while(<CONFIG>) {
                next if (m@^\s+$|^#.*@);
                my ($package,$selected) = (split '=', $_);
                chomp $package;
                chomp $selected;

                ### fix kernel package name
                # backward compatibility for old rpm name
                if ($package =~ /kernel-ib/) {
                    $package =~ s/kernel-ib/mlnx-ofa_kernel/g;
                }
                # if kmp not supported
                if ($package eq "mlnx-ofa_kernel" and not $kmp) {
                    $package =~ s/mlnx-ofa_kernel/mlnx-ofa_kernel-modules/;
                }
                if ($package =~ m/kernel-mft-mlnx|ummunotify-mlnx/ and not $kmp) {
                    $package =~ s/-mlnx//;
                }
                if ($package eq "mlnx-en" and not $kmp) {
                    $package = "mlnx_en";
                }
                if ($package eq "knem" and not $kmp) {
                    # knem (user space) will be added automatically since knem-modules needs it
                    $package = "knem-modules";
                }
                # if kmp supported
                if ($package eq "mlnx-ofa_kernel-modules" and $kmp) {
                    $package =~ s/mlnx-ofa_kernel-modules/mlnx-ofa_kernel/;
                }
                if ($package =~ m/kernel-mft|ummunotify/ and $package !~ m/mlnx/ and $kmp) {
                    $package .= "-mlnx";
                }
                if ($package eq "mlnx_en" and $kmp) {
                    $package = "mlnx-en";
                }
                if ($package eq "knem-modules" and $kmp) {
                    $package = "knem";
                }

                print_and_log("$package=$selected\n", $verbose3);

                if ($package eq "build32") {
                    if (supported32bit()) {
                        $build32 = 1 if ($selected);
                    }
                    next;
                }

                if ($package eq "prefix") {
                    $prefix = $selected;
                    $prefix =~ s/\/$//;
                    next;
                }

                if ($package eq "bonding_force_all_os") {
                    if ($selected =~ m/[Yy]|[Yy][Ee][Ss]/) {
                        $bonding_force_all_os = 1;
                    }
                    next;
                }

		if (substr($package,0,length("vendor_config")) eq "vendor_config") {
		       next;
		}

                if ($package eq "vendor_pre_install") {
		    if ( -e $selected ) {
			$vendor_pre_install = dirname($selected) . '/' . basename($selected);
		    }
		    else {
			print_and_log_colored("\nVendor script $selected is not found", (not $quiet), "RED");
			exit 1
		    }
                    next;
                }

                if ($package eq "vendor_post_install") {
		    if ( -e $selected ) {
			$vendor_post_install = dirname($selected) . '/' . basename($selected);
		    }
		    else {
			print_and_log_colored("\nVendor script $selected is not found", (not $quiet), "RED");
			exit 1
		    }
                    next;
                }

                if ($package eq "vendor_pre_uninstall") {
		    if ( -e $selected ) {
			$vendor_pre_uninstall = dirname($selected) . '/' . basename($selected);
		    }
		    else {
			print_and_log_colored("\nVendor script $selected is not found", (not $quiet), "RED");
			exit 1
		    }
                    next;
                }

                if ($package eq "vendor_post_uninstall") {
		    if ( -e $selected ) {
			$vendor_post_uninstall = dirname($selected) . '/' . basename($selected);
		    }
		    else {
			print_and_log_colored("\nVendor script $selected is not found", (not $quiet), "RED");
			exit 1
		    }
                    next;
                }

                if ($package eq "kernel_configure_options" or $package eq "OFA_KERNEL_PARAMS") {
                    $kernel_configure_options = $selected;
                    next;
                }

                if ($package eq "user_configure_options") {
                    $user_configure_options = $selected;
                    next;
                }

                if ($package =~ m/configure_options/) {
                    my $pack_name = (split '_', $_)[0];
                    $packages_info{$pack_name}{'configure_options'} = $selected;
                    next;
                }

                # mvapich2 configuration environment
                if ($package eq "mvapich2_conf_impl") {
                    $mvapich2_conf_impl = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_romio") {
                    $mvapich2_conf_romio = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_shared_libs") {
                    $mvapich2_conf_shared_libs = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_ckpt") {
                    $mvapich2_conf_ckpt = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_blcr_home") {
                    $mvapich2_conf_blcr_home = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_vcluster") {
                    $mvapich2_conf_vcluster = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_io_bus") {
                    $mvapich2_conf_io_bus = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_link_speed") {
                    $mvapich2_conf_link_speed = $selected;
                    next;
                }

                elsif ($package eq "mvapich2_conf_dapl_provider") {
                    $mvapich2_conf_dapl_provider = $selected;
                    next;
                }

                if (not $packages_info{$package}{'parent'} or $package =~ /iser|srp$/) {
                    my $modules = "@kernel_modules @tech_preview";
                    chomp $modules;
                    $modules =~ s/ /|/g;
                    if ($package =~ m/$modules/) {
                        if ( $selected eq 'y' ) {
                            if (not $kernel_modules_info{$package}{'available'}) {
                                print_and_log("$package is not available on this platform\n", (not $quiet));
                            }
                            else {
                                push (@selected_modules_by_user, $package);
                            }
                            next if ($package !~ /iser|srp/);
                        }
                    }
                    else {
                       print_and_log("Unsupported package: $package\n", (not $quiet));
                       next;
                    }
                }

                if (not $packages_info{$package}{'available'} and $selected eq 'y') {
                    print_and_log("$package is not available on this platform\n", (not $quiet));
                    next;
                }

                if ( $selected eq 'y' ) {
                    my $parent = $packages_info{$package}{'parent'};
                    if (not is_srpm_available($parent)) {
                        print_and_log("Unsupported package: $package\n", (not $quiet));
                        next;
                    }
                    push (@selected_by_user, $package);
                    print_and_log("select_package: selected $package\n", $verbose2);
                    $cnt ++;
                }
            }
        }
        else {
            open(CONFIG, ">$config") || die "Can't open $config: $!";
            flock CONFIG, $LOCK_EXCLUSIVE;
            if ($install_option eq 'all') {
                for my $package ( @all_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'guest-os') {
                for my $package ( @guest_kernel_packages,@guest_user_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @guest_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'hypervisor-os') {
                for my $package ( @hypervisor_kernel_packages,@hypervisor_user_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @hypervisor_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'bluefield') {
                $packages_info{"$knem_rpm"}{'available'} = 0;
                $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
                for my $package ( @bluefield_user_packages, @bluefield_kernel_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if ($kernel_only and $packages_info{$package}{'mode'} ne 'kernel');
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @bluefield_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'hpc') {
                for my $package ( @hpc_user_packages, @hpc_kernel_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @hpc_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option =~ m/vma/) {
                my @list = ();
                if ($install_option eq 'vma') {
                    @list = (@vma_user_packages);
                } elsif ($install_option eq 'vmavpi') {
                    @list = (@vmavpi_user_packages);
                } elsif ($install_option eq 'vmaeth') {
                    @list = (@vmaeth_user_packages);
                }
                for my $package ( @list, @vma_kernel_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @vma_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'basic') {
                for my $package (@basic_user_packages, @basic_kernel_packages) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @basic_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'kernel-only') {
                for my $package ( @all_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    next if (not $packages_info{$package}{'mode'} eq 'kernel');
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option eq 'eth-only') {
                for my $package (@eth_user_packages, @eth_kernel_packages) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @basic_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            elsif ($install_option =~ m/dpdk/) {
                for my $package ( @dpdk_user_packages, @dpdk_kernel_packages ) {
                    next if (not $packages_info{$package}{'available'});
                    my $parent = $packages_info{$package}{'parent'};
                    next if (not is_srpm_available($parent));
                    push (@selected_by_user, $package);
                    print CONFIG "$package=y\n";
                    $cnt ++;
                }
                for my $module ( @dpdk_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    push (@selected_modules_by_user, $module);
                    print CONFIG "$module=y\n";
                }
            }
            else {
                print_and_log_colored("\nUnsupported installation option: $install_option", (not $quiet), "RED");
                exit 1;
            }
        }

        if ($with_bluefield and $install_option ne 'bluefield') {
            $packages_info{"$knem_rpm"}{'available'} = 0;
            $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
            for my $package ( @bluefield_user_packages, @bluefield_kernel_packages ) {
                next if (grep /^$package$/, @selected_by_user);
                next if (not $packages_info{$package}{'available'});
                my $parent = $packages_info{$package}{'parent'};
                next if ($kernel_only and $packages_info{$package}{'mode'} ne 'kernel');
                next if (not is_srpm_available($parent));
                push (@selected_by_user, $package);
                print CONFIG "$package=y\n";
                $cnt ++;
            }
            for my $module ( @bluefield_kernel_modules ) {
                next if (grep /^$module$/, @selected_modules_by_user);
                next if (not $kernel_modules_info{$module}{'available'});
                push (@selected_modules_by_user, $module);
                print CONFIG "$module=y\n";
            }
        }

        flock CONFIG, $UNLOCK;
    }
    close(CONFIG);


    return $cnt;
}

sub module_in_rpm
{
    my $name = shift @_;
    my $module = shift @_;
    my $ver = shift @_;
    my $ret = 1;
    my $package;
    my $common_dir = "$RPMS/$COMMON_DIR";

    my $version = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'version'};
    my $release = $kernel_rel;

    if ($name =~ /-modules/ or (not $kmp)) {
        $release = "$main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'}" . ".kver.$kernel_rel" ;
    }

    my $arch = $target_cpu;
    if ($DISTRO =~ /RHEL5|XenServer/ and $target_cpu eq "i386" and $name =~ /ofa_kernel/) {
        $arch = 'i686';
    }

    if ($name =~ /mlnx-ofa_kernel/) {
        $package = $main_packages{$name}{$ver}{'rpmpath'};
    } else {
        $package = "$common_dir/$name-$version-$release.$arch.rpm";
        if (not -e "$package" and -e "$RPMS/$name-$version-$kernel_rel.$arch.rpm") {
            $package = "$common_dir/$name-$version-$kernel_rel.$arch.rpm";
        }
    }
    chomp $package;

    if (not -e $package) {
        print_and_log("is_module_in_rpm: $package not found\n", $verbose);
        return 1;
    }

    if ($module eq "nfsrdma") {
        $module = "rpcrdma";
    } elsif ($module eq "e_ipoib") {
        $module = "eth_ipoib";
    } elsif ($module eq "amso1100") {
        $module = "iw_c2";
    }

    open(LIST, "rpm -qlp $package 2>/dev/null |") or die "Can't run 'rpm -qlp $package': $!\n";
    while (<LIST>) {
        if (/$module[a-z_]*.ko/) {
            print_and_log("is_module_in_rpm: $module $_\n", $verbose3);
            $ret = 0;
            last;
        }
    }
    close LIST;

    if ($ret) {
        print_and_log("$module not in $package\n", $verbose2);
    }

    return $ret;
}

sub mark_for_uninstall
{
    my $package = shift @_;
    if (not $selected_for_uninstall{$package}) {
        push (@dependant_packages_to_uninstall, "$package");
        $selected_for_uninstall{$package} = 1;
        my $pname = $package;
        $pname =~ s@-[0-9].*@@g;
        if (not (exists $packages_info{$pname} or $pname =~ /mlnx-ofed-/)) {
            $non_ofed_for_uninstall{$pname} = 1;
        }
    }
}

sub get_requires
{
    my $package = shift @_;

    # Strip RPM version
    my $pname = `rpm -q --queryformat "[%{NAME}]" $package 2>/dev/null`;
    chomp $pname;

    if ($pname eq "rdma") {
        # don't remove packages that needs rdma package
        return;
    }

    my @what_requires = `rpm -q --whatrequires $pname 2> /dev/null | grep -v "no package requires" 2> /dev/null`;

    for my $pack_req (@what_requires) {
        chomp $pack_req;
        print_and_log("get_requires: $pname is required by $pack_req\n", $verbose2);
        get_requires($pack_req);
        mark_for_uninstall($pack_req);
    }
}

# return 0 if pacakge not selected
# return 1 if pacakge selected
sub select_dependent
{
    my $package = shift @_;

    if ($user_space_only and ($packages_info{$package}{'mode'} eq 'kernel')) {
        print_and_log("select_dependent: in user-space-only mode, skipping kernel package: $package\n", $verbose2);
        return 0;
    }

    my $pname = $packages_info{$package}{'parent'};
    for my $ver (keys %{$main_packages{$pname}}) {
        # prevent loop
        if (not exists $packages_info{$package}{'entered_select_dependent'}) {
            $packages_info{$package}{'entered_select_dependent'}  = 1;
        } else {
            return 0 if (not $packages_info{$package}{'available'});
            my $parent = $packages_info{$package}{'parent'};
            return 0 if (not $main_packages{$parent}{$ver}{'srpmpath'});
            return 1;
        }

        if ( (not $packages_info{$package}{$ver}{'rpm_exist'}) or
             ($build32 and not $packages_info{$package}{$ver}{'rpm_exist32'}) ) {
            for my $req ( @{ $packages_info{$package}{'ofa_req_build'} } ) {
                next if not $req;
                # W/A for -p option and --user-space-only
                if ($req eq "mlnx-ofa_kernel-devel" and $print_available) {
                    next;
                }
                print_and_log("resolve_dependencies: $package requires $req for rpmbuild\n", $verbose2);
                my $req_selected = 0;
                if ($packages_info{$req}{'available'}) {
                    if (not $packages_info{$req}{'selected'}) {
                        $req_selected = select_dependent($req);
                    } else {
                        $req_selected = 1;
                    }
                }
                # Check if this is a strict requirment
                if (not $req_selected and not grep( /^$req$/, @{ $packages_info{$package}{'soft_req'} } )) {
                    print_and_log("select_dependent: $req requiement not satisfied for $package, skipping it\n", $verbose2);
                    $packages_info{$package}{'available'} = 0;
                    $packages_info{$pname}{'available'} = 0;
                    return 0;
                }
            }
        }

        for my $req ( @{ $packages_info{$package}{'ofa_req_inst'} } ) {
            next if not $req;
            print_and_log("resolve_dependencies: $package requires $req for rpm install\n", $verbose2);
            my $req_selected = 0;
            if ($packages_info{$req}{'available'}) {
                if (not $packages_info{$req}{'selected'}) {
                    $req_selected = select_dependent($req);
                } else {
                    $req_selected = 1;
                }
            }
            if (not $req_selected and not grep( /^$req$/, @{ $packages_info{$package}{'soft_req'} } )) {
                print_and_log("select_dependent: $req requiement not satisfied for $package, skipping it\n", $verbose2);
                $packages_info{$package}{'available'} = 0;
                $packages_info{$pname}{'available'} = 0;
                return 0;
            }
        }

        if (not $packages_info{$package}{'selected'}) {
            return 0 if (not $packages_info{$package}{'available'});
            my $parent = $packages_info{$package}{'parent'};
            return 0 if (not $main_packages{$parent}{$ver}{'srpmpath'});
            $packages_info{$package}{'selected'} = 1;
            push (@selected_packages, $package);
            print_and_log("select_dependent: Selected package $package\n", $verbose2);
            return 1;
        }
    }
    # if we get here, then nothing got selected.
    return 0;
}

sub select_dependent_module
{
    my $module = shift @_;

    if (not $kernel_modules_info{$module}{'available'}) {
        print_and_log("select_dependent_module: $module is not available, skipping it\n", $verbose2);
        return;
    }

    # prevent loop
    if (not exists $kernel_modules_info{$module}{'entered_select_dependent_module'}) {
        $kernel_modules_info{$module}{'entered_select_dependent_module'}  = 1;
    } else {
        return;
    }

    for my $req ( @{ $kernel_modules_info{$module}{'requires'} } ) {
        print_and_log("select_dependent_module: $module requires $req for rpmbuild\n", $verbose2);
        if (not $kernel_modules_info{$req}{'selected'}) {
            select_dependent_module($req);
        }
    }
    if (not $kernel_modules_info{$module}{'selected'}) {
        $kernel_modules_info{$module}{'selected'} = 1;
        push (@selected_kernel_modules, $module);
        print_and_log("select_dependent_module: Selected module $module\n", $verbose2);
    }
}

sub resolve_dependencies
{
    for my $package ( @selected_by_user ) {
            # Get the list of dependencies
            select_dependent($package);
            if (exists $standalone_kernel_modules_info{$package}) {
                for my $mod (@{$standalone_kernel_modules_info{$package}}) {
                    if ($kernel_modules_info{$mod}{'available'}) {
                        push (@selected_modules_by_user, $mod);
                    }
                }
            }

            if ($package =~ /mvapich2_*/ and not $print_available) {
                    mvapich2_config();
            }
        }

    for my $module ( @selected_modules_by_user ) {
        select_dependent_module($module);
    }

    my @kernel_rpms = qw(mlnx-ofa_kernel-modules kmod-mlnx-ofa_kernel mlnx-ofa_kernel-kmp-default);
    for my $kernel_rpm ( @kernel_rpms ) {
        my $pname = $packages_info{$kernel_rpm}{'parent'};
        if ( not $pname and $kernel_rpm =~ m/mlnx-ofa_kernel/ ) {
           $pname = "mlnx-ofa_kernel";
        }
        for my $ver (keys %{$main_packages{$pname}}) {
            if ($packages_info{$kernel_rpm}{$ver}{'rpm_exist'}) {
                for my $module (@selected_kernel_modules) {
                    if (module_in_rpm($kernel_rpm, $module, $ver)) {
                        $packages_info{$kernel_rpm}{$ver}{'rpm_exist'} = 0;
                        $packages_info{'mlnx-ofa_kernel'}{$ver}{'rpm_exist'} = 0;
                        last;
                    }
                }
                if ($with_memtrack) {
                    if (module_in_rpm($kernel_rpm, "memtrack", $ver)) {
                        $packages_info{$kernel_rpm}{$ver}{'rpm_exist'} = 0;
                        $packages_info{'mlnx-ofa_kernel'}{$ver}{'rpm_exist'} = 0;
                        last;
                    }
                }
            }
        }
    }
}

sub check_linux_dependencies
{
    my $err = 0;
    my $p1 = 0;
    my $gcc_32bit_printed = 0;
	my %missing_packages = ();
    if (! $check_linux_deps) {
        return 0;
    }
    my $dist_req_build = ($DISTRO =~ m/UBUNTU/)?'ubuntu_dist_req_build':'dist_req_build';
    for my $package ( @selected_packages ) {
        my $pname = $packages_info{$package}{'parent'};
        for my $ver (keys %{$main_packages{$pname}}) {
                # Check rpmbuild requirements
                if ($package =~ /ofa_kernel|ib-bonding|kernel-mft|mlx4_accl|knem|ummunotify|mlnx-en/) {
                    if (not $packages_info{$package}{$ver}{'rpm_exist'}) {
                        # kernel sources required
                        if (not exists $missing_packages{"$kernel_devel"}) {
                            if ( not -d "$kernel_sources/scripts" ) {
                                $missing_packages{"$kernel_devel"} = 1;
                                print_and_log_colored("$kernel_sources/scripts is required to build $package RPM.", 1, "RED");
                                print_and_log_colored("Please install the corresponding kernel-source or kernel-devel RPM.", 1, "RED");
                                $err++;
                            }
                        }
                        # from kernel 4.14 we need elf devel package when CONFIG_UNWINDER_ORC=y
                        if (not is_installed("$kernel_elfutils_devel") and not exists $missing_packages{"$kernel_elfutils_devel"}) {
                            if ( check_autofconf('CONFIG_STACK_VALIDATION') eq "1" and check_autofconf('CONFIG_UNWINDER_ORC') eq "1" and $kernel =~ /^4\.[1-9][4-9]\./) {
                                $missing_packages{"$kernel_elfutils_devel"} = 1;
                                print_and_log_colored("$kernel_elfutils_devel is required to build $package RPM.", $verbose2, "RED");
                                $err++;
                            }
                        }
                    }
                }

                if($DISTRO =~/UBUNTU/){
                    if(not is_installed_deb("rpm")){
                        print_and_log_colored("rpm is required to build OFED", $verbose2, "RED");
                        $missing_packages{"rpm"} = 1;
                    }
                }

                if ($DISTRO =~ m/RHEL|FC|POWERKVM|EULEROS/ or ($DISTRO =~ m/SLES12/) ) {
                    if (not is_installed("rpm-build")) {
                        print_and_log_colored("rpm-build is required to build OFED", $verbose2, "RED");
                        $missing_packages{"rpm-build"} = 1;
                        $err++;
                    }
                }

                if ($DISTRO !~ m/SLES|SUSE|WINDRIVER6|BLUENIX1/) {
                        if (not is_installed("$kernel_req")) {
                            print_and_log_colored("$kernel_req rpm is required to build $package", $verbose2, "RED");
                            $missing_packages{"$kernel_req"} = 1;
                            $err++;
                        }
                }

                if (not $packages_info{$package}{$ver}{'rpm_exist'}) {
                    for my $req ( @{ $packages_info{$package}{$dist_req_build} } ) {
                        my ($req_name, $req_version) = (split ('__',$req));
                        next if not $req_name;
                        print_and_log("check_linux_dependencies: $req_name  is required to build $package $ver\n", $verbose3);
                        my $is_installed_flag = ($DISTRO =~ m/UBUNTU/)?(is_installed_deb($req_name)):(is_installed($req_name));
                        if (not $is_installed_flag) {
                            print_and_log_colored("$req_name rpm is required to build $package $ver", $verbose2, "RED");
                            if ("$req_name" eq "cmake" and $req_version ne "") {
                                print_and_log_colored("$req_name >= $req_version is required to build $package", 1, "RED");
                            }
                            $missing_packages{"$req_name"} = 1;
                            $err++;
                        }
                        if ($req_version) {
                            my $inst_version = get_rpm_ver_inst($req_name);
                            if ("$req_name" eq "cmake" and ($inst_version lt $req_version or $inst_version =~ /not installed/)) {
                                $inst_version = `cmake --version 2>/dev/null | grep "cmake version" | sed -e "s/.*cmake version\\s*//g"`;
                                chomp $inst_version;
                            }
                            print_and_log("check_linux_dependencies: $req_name installed version $inst_version, required at least $req_version\n", $verbose3);
                            if ($inst_version lt $req_version) {
                                print_and_log_colored("$req_name-$req_version rpm is required to build $package $ver", $verbose2, "RED");
                                if ("$req_name" eq "cmake") {
                                    print_and_log_colored("$req_name >= $req_version is required to build $package", 1, "RED");
                                    $missing_packages{"$req_name"} = 1;
                                } else {
                                    $missing_packages{"$req_name-$req_version"} = 1;
                                }
                                $err++;
                            }
                        }
                    }
                    if ($build32) {
                        if (not -e "/usr/lib/crt1.o") {
                            if (! $p1) {
                                print_and_log_colored("$glibc_devel 32bit is required to build 32-bit libraries.", $verbose2, "RED");
                                $missing_packages{"$glibc_devel$suffix_32bit"} = 1;
                                $p1 = 1;
                                $err++;
                            }
                        }
                        if ($DISTRO eq "SLES11") {
                            if (not is_installed("gcc-32bit")) {
                                if (not $gcc_32bit_printed) {
                                    print_and_log_colored("gcc-32bit is required to build 32-bit libraries.", $verbose2, "RED");
                                    $missing_packages{"gcc-32bit"} = 1;
                                    $gcc_32bit_printed++;
                                    $err++;
                                }
                            }
                        }
                        if ($arch eq "ppc64") {
                            my @libstdc32 = </usr/lib/libstdc++.so.*>;
                            if ($package eq "mstflint") {
                                if (not scalar(@libstdc32)) {
                                    print_and_log_colored("$libstdc 32bit is required to build mstflint.", $verbose2, "RED");
                                    $missing_packages{"$libstdc$suffix_32bit"} = 1;
                                    $err++;
                                }
                            }
                            elsif ($package =~ /openmpi/) {
                                my @libsysfs = </usr/lib/libsysfs.so>;
                                if (not scalar(@libstdc32)) {
                                    print_and_log_colored("$libstdc_devel 32bit is required to build openmpi.", $verbose2, "RED");
                                    $missing_packages{"$libstdc_devel$suffix_32bit"} = 1;
                                    $err++;
                                }
                                if (not scalar(@libsysfs)) {
                                    print_and_log_colored("$sysfsutils_devel 32bit is required to build openmpi.", $verbose2, "RED");
                                    $missing_packages{"$sysfsutils_devel$suffix_32bit"} = 1;
                                    $err++;
                                }
                            }
                        }
                    }
                    if ($package eq "rnfs-utils") {
                        if (not is_installed("krb5-devel")) {
                            print_and_log_colored("krb5-devel is required to build rnfs-utils.", $verbose2, "RED");
                            $missing_packages{"krb5-devel"} = 1;
                            $err++;
                        }
                        if ($DISTRO =~ m/RHEL|FC|POWERKVM|EULEROS/) {
                            if (not is_installed("krb5-libs")) {
                                print_and_log_colored("krb5-libs is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"krb5-libs"} = 1;
                                $err++;
                            }
                            if (not is_installed("libevent-devel")) {
                                print_and_log_colored("libevent-devel is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"libevent-devel"} = 1;
                                $err++;
                            }
                            if (not is_installed("nfs-utils-lib-devel")) {
                                print_and_log_colored("nfs-utils-lib-devel is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"nfs-utils-lib-devel"} = 1;
                                $err++;
                            }
                            if (not is_installed("openldap-devel")) {
                                print_and_log_colored("openldap-devel is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"openldap-devel"} = 1;
                                $err++;
                            }
                        } else {
                            if ($DISTRO eq "SLES11") {
                                if (not is_installed("libevent-devel")) {
                                    print_and_log_colored("libevent-devel is required to build rnfs-utils.", $verbose2, "RED");
                                    $missing_packages{"libevent-devel"} = 1;
                                    $err++;
                                }
                                if (not is_installed("nfsidmap-devel")) {
                                    print_and_log_colored("nfsidmap-devel is required to build rnfs-utils.", $verbose2, "RED");
                                    $missing_packages{"nfsidmap-devel"} = 1;
                                    $err++;
                                }
                                if (not is_installed("libopenssl-devel")) {
                                    print_and_log_colored("libopenssl-devel is required to build rnfs-utils.", $verbose2, "RED");
                                    $missing_packages{"libopenssl-devel"} = 1;
                                    $err++;
                                }
                            } elsif ($DISTRO eq "SLES10") {
                                if (not is_installed("libevent")) {
                                    print_and_log_colored("libevent is required to build rnfs-utils.", $verbose2, "RED");
                                    $missing_packages{"libevent"} = 1;
                                    $err++;
                                }
                                if (not is_installed("nfsidmap")) {
                                    print_and_log_colored("nfsidmap is required to build rnfs-utils.", $verbose2, "RED");
                                    $missing_packages{"nfsidmap"} = 1;
                                    $err++;
                                }
                            }
                            if (not is_installed("krb5")) {
                                print_and_log_colored("krb5 is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"krb5"} = 1;
                                $err++;
                            }
                            if (not is_installed("openldap2-devel")) {
                                print_and_log_colored("openldap2-devel is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"openldap2-devel"} = 1;
                                $err++;
                            }
                            if (not is_installed("cyrus-sasl-devel")) {
                                print_and_log_colored("cyrus-sasl-devel is required to build rnfs-utils.", $verbose2, "RED");
                                $missing_packages{"cyrus-sasl-devel"} = 1;
                                $err++;
                            }
                        }

                        my $blkid_so = ($arch =~ m/x86_64/) ? "/usr/lib64/libblkid.so" : "/usr/lib/libblkid.so";
                        my $blkid_pkg = ($kernel =~ m/2.6.2[6-7]/ and $DISTRO =~ m/SLES/) ? "libblkid-devel" :
                                        "e2fsprogs-devel";
                        $blkid_pkg .= ($arch =~ m/powerpc|ppc64/) ? "-32bit" : "";

                        if (not -e $blkid_so) {
                            print_and_log_colored("$blkid_pkg is required to build rnfs-utils.", $verbose2, "RED");
                            $missing_packages{"$blkid_pkg"} = 1;
                            $err++;
                        }
                    }
                }

                if ((($DISTRO =~ /RHEL7\.6/) and ($arch eq 'x86_64'))  or
                    (($DISTRO =~ /RHEL7\.6ALTERNATE/) and ($arch eq 'ppc64le'))
                ) {
                    # The test for gdrcopy earlier on failed.
                    # We will try to install cuda packages explicitly.
                    if ($packages_info{'gdrcopy'}{'available'}) {
                        print_and_log("check_linux_dependencies: gdrcopy is required for ucx, but not installed.\n", $verbose2, "RED");
                        $err++;
                    }
                }
                my $dist_req_inst = ($DISTRO =~ m/UBUNTU/)?'ubuntu_dist_req_inst':'dist_req_inst';
                # Check installation requirements
                for my $req ( @{ $packages_info{$package}{$dist_req_inst} } ) {
                    my ($req_name, $req_version) = (split ('__',$req));
                    next if not $req_name;
                    my $is_installed_flag = ($DISTRO =~ m/UBUNTU/)?(is_installed_deb($req_name)):(is_installed($req_name));
                    if (not $is_installed_flag) {
                        print_and_log_colored("$req_name rpm is required to install $package $ver", $verbose2, "RED");
                        $missing_packages{"$req_name"} = 1;
                        $err++;
                    }
                    if ($req_version) {
                        my $inst_version = get_rpm_ver_inst($req_name);
                        print_and_log("check_linux_dependencies: $req_name installed version $inst_version, required $req_version\n", $verbose3);
                        if ($inst_version lt $req_version) {
                            print_and_log_colored("$req_name-$req_version rpm is required to install $package $ver", $verbose2, "RED");
                            $missing_packages{"$req_name-$req_version"} = 1;
                            $err++;
                        }
                    }
                }
                if ($build32) {
                    if (not -e "/usr/lib/crt1.o") {
                        if (! $p1) {
                            print_and_log_colored("$glibc_devel 32bit is required to install 32-bit libraries.", $verbose2, "RED");
                            $missing_packages{"$glibc_devel$suffix_32bit"} = 1;
                            $p1 = 1;
                            $err++;
                        }
                    }
                    if ($arch eq "ppc64") {
                        my @libstdc32 = </usr/lib/libstdc++.so.*>;
                        if ($package eq "mstflint") {
                            if (not scalar(@libstdc32)) {
                                print_and_log_colored("$libstdc 32bit is required to install mstflint.", $verbose2, "RED");
                                $missing_packages{"$libstdc$suffix_32bit"} = 1;
                                $err++;
                            }
                        }
                        elsif ($package =~ /openmpi/) {
                            my @libsysfs = </usr/lib/libsysfs.so.*>;
                            if (not scalar(@libstdc32)) {
                                print_and_log_colored("$libstdc 32bit is required to install openmpi.", $verbose2, "RED");
                                $missing_packages{"$libstdc$suffix_32bit"} = 1;
                                $err++;
                            }
                            if (not scalar(@libsysfs)) {
                                print_and_log_colored("$sysfsutils 32bit is required to install openmpi.", $verbose2, "RED");
                                $missing_packages{"$sysfsutils$suffix_32bit"} = 1;
                                $err++;
                            }
                        }
                    }
                }
        }
    }
    if ($err) {
        # display a summary of missing packages
        if (keys %missing_packages) {
            print_and_log_colored("\nError: One or more required packages for installing OFED-internal are missing.", 1, "RED");
            print_and_log_colored("Please install the missing packages using your Linux distribution Package Management tool.", 1, "RED");
            print_and_log("Run:\n$package_manager install " . join(' ', (keys %missing_packages)) . "\n", 1);
        }
        exit $PREREQUISIT;
    }

    if ($check_deps_only) {
        print_and_log("All required packages are installed, the system is ready for $PACKAGE installation.\n", 1);
        exit 0;
    }
}

# Print the list of selected packages
sub print_selected
{
    print_and_log_colored("\nBelow is the list of ${PACKAGE} packages that you have chosen
    \r(some may have been added by the installer due to package dependencies):\n", 1, "GREEN");
    for my $package ( @selected_packages ) {
        print_and_log("$package\n", 1);
    }
    if ($build32) {
        print_and_log("32-bit binaries/libraries will be created\n", 1);
    }
    print_and_log("\n", 1);
}

sub build_kernel_rpm
{
    my $name = shift @_;
    my $ver = shift @_;
    my $cmd;
    my $res = 0;
    my $sig = 0;
    my $TMPRPMS;

    $cmd = "rpmbuild --rebuild $rpmbuild_flags --define '_topdir $TOPDIR' --define '_sourcedir %{_topdir}/SOURCES' --define '_specdir %{_topdir}/SPECS' --define '_srcrpmdir %{_topdir}/SRPMS' --define '_rpmdir %{_topdir}/RPMS' ";

    my $orig_rel = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'};
    my $new_rel = "${orig_rel}.kver.${kernel_rel}";

    if ($name =~ /ofa_kernel/) {
        $kernel_configure_options .= " $packages_info{$name}{'configure_options'}";

        for my $module ( @selected_kernel_modules ) {
            if ($module eq "core") {
                $kernel_configure_options .= " --with-core-mod --with-user_mad-mod --with-user_access-mod --with-addr_trans-mod";
            }
            elsif ($module eq "ipath") {
                $kernel_configure_options .= " --with-ipath_inf-mod";
            }
            elsif ($module eq "qib") {
                $kernel_configure_options .= " --with-qib-mod";
            }
            elsif ($module eq "srpt") {
                $kernel_configure_options .= " --with-srp-target-mod";
            }
            elsif ($module eq "mlx5_fpga_tools") {
                # Innova/FPGA FLEX supported from kernel 3.10 and up
                $kernel_configure_options .= " --with-innova-flex";

                # Innova/FPGA IPSec supported only in MLNX_OFED, from kernel 4.13 and up
                # and it requires some kernel configs to be enabled
                if ($kernel =~ /^4\.1[3-9]\./) {
                    my $CONFIG_XFRM_OFFLOAD = check_autofconf('CONFIG_XFRM_OFFLOAD');
                    my $CONFIG_INET_ESP_OFFLOAD = check_autofconf('CONFIG_INET_ESP_OFFLOAD');
                    my $CONFIG_INET6_ESP_OFFLOAD = check_autofconf('CONFIG_INET6_ESP_OFFLOAD');

                    print_and_log("\n-W- CONFIG_XFRM_OFFLOAD is not enabled in the kernel, Cannot build mlx5_core with Innova support\n", $verbose) if ($CONFIG_XFRM_OFFLOAD ne "1");
                    print_and_log("\n-W- None of CONFIG_INET6_ESP_OFFLOAD and CONFIG_INET_ESP_OFFLOAD enabled in the kernel, Cannot build mlx5_core with Innova support\n", $verbose) if ($CONFIG_INET_ESP_OFFLOAD ne "1" and $CONFIG_INET6_ESP_OFFLOAD ne "1");

                    if ($CONFIG_XFRM_OFFLOAD eq "1" and
                        ($CONFIG_INET_ESP_OFFLOAD eq "1" or $CONFIG_INET6_ESP_OFFLOAD eq "1")) {
                        $kernel_configure_options .= " --with-innova-ipsec";
                    }
                }
            }
            else {
                $kernel_configure_options .= " --with-$module-mod";
            }
        }

        if ($arch =~ m/aarch64/ and $kernel =~ /^4\.20/) {
                $kernel_configure_options .= " --with-bf-power-failure-event";
                $kernel_configure_options .= " --with-mlx5-miniflow";
        }

        if ($DISTRO eq "DEBIAN") {
                $kernel_configure_options .= " --without-modprobe";
        }

        if ($with_memtrack) {
                $kernel_configure_options .= " --with-memtrack";
        }

        if ($DISTRO =~ /RHEL5|XenServer/ and $target_cpu eq "i386") {
            $cmd .= " --define '_target_cpu i686'";
        }
        $cmd .= " --nodeps";
        $cmd .= " --define '_dist .$rpm_distro'";
        $cmd .= " --define 'configure_options $kernel_configure_options'";
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
    }
    elsif ($name =~ /kernel-mft/) {
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";

        # for backward compatablilty check if the src.rpm does not support setting _release
        my $_release_supported = 1;
        mkpath([$TOPDIR . 'mft_check/BUILD' ,$TOPDIR . 'mft_check/RPMS',$TOPDIR . 'mft_check/SOURCES',$TOPDIR . 'mft_check/SPECS',$TOPDIR . 'mft_check/SRPMS']);
        system("rpm -ihv --nodeps --define '_topdir $TOPDIR/mft_check' --define '_sourcedir %{_topdir}/SOURCES' --define '_specdir %{_topdir}/SPECS' --define '_srcrpmdir %{_topdir}/SRPMS' --define '_rpmdir %{_topdir}/RPMS' $main_packages{$name}{$ver}{'srpmpath'} >/dev/null 2>&1");
        if (`grep -w _release $TOPDIR/mft_check/SPECS/*spec 2>/dev/null` eq "") {
            print_and_log("kernel-mft does not support setting _release\n", $verbose3);
            $_release_supported = 0;
        }
        system("rm -rf $TOPDIR/mft_check >/dev/null 2>&1");

        $cmd .= " --define 'source 1'" if ($_release_supported or $kmp);
        $cmd .= " --define '_release $new_rel'" if not $kmp;
        $cmd .= " --define 'debug_package %{nil}'";
        $cmd .= " --define '_dist .$rpm_distro'" if $kmp;
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
    }
    elsif ($name =~ /mlx4_accl/) {
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";
        $cmd .= " --define 'FLAVOR .$new_rel'";
        $cmd .= " --define 'debug_package %{nil}'";
    }
    elsif ($name eq 'ib-bonding') {
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define '_release $new_rel'";
        $cmd .= " --define 'force_all_os $bonding_force_all_os'";
    }
    elsif ($name =~ /knem/) {
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";
        $cmd .= " --define '_dist .$rpm_distro'";
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
    }
    elsif ($name =~ /ummunotify/) {
        $cmd .= " --define '_release $new_rel'" if not $kmp;
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";
        $cmd .= " --define '_dist .$rpm_distro'" if $kmp;
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
    }
    # Standalone module packages
    elsif ($name =~ /$bf_krpm_regex|iser|srp|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/) {
        $cmd .= " --define 'src_release $new_rel'" if not $kmp;
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'K_SRC $kernel_sources'";
        $cmd .= " --define '_dist .$rpm_distro'" if $kmp;
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
        if ($name =~ /mlnx-nvme/) {
            if (($DISTRO =~ /RHEL7.[2-3]|RHEL6.3/ and $kernel =~ /3.10.0/) or
                ($DISTRO =~ /RHEL7.[4-5]/ and $kernel =~ /
                    3.10.0-123 | 3.10.0-229 | 3.10.0-327| 3.10.0-514
                /x
            )) {
                $cmd .= " --define 'NVME_HOST_WITHOUT_FC 1'";
            }
        }
    }
    elsif ($name =~ /mlnx-en|mlnx_en/) {
        $cmd .= " --define '_dist .$rpm_distro'";
        $cmd .= " --define 'KVERSION $kernel'";
        $cmd .= " --define 'KSRC $kernel_sources'";
        $cmd .= " --define 'MEMTRACK $with_memtrack'";
        my $mlx4f = (grep( /^mlx4$/, @selected_kernel_modules )) ? "1" : "0";
        $cmd .= " --define 'MLX4 $mlx4f'";
        my $mlx5f = (grep( /^mlx5$/, @selected_kernel_modules )) ? "1" : "0";
        $cmd .= " --define 'MLX5 $mlx5f'";
        my $mlxfwf = (grep( /^mlxfw$/, @selected_kernel_modules )) ? "1" : "0";
        $cmd .= " --define 'MLXFW $mlxfwf'";
        $cmd .= " --define 'KMP 1'" if $kmp;
        $cmd .= " --define '_kmp_build_num .$kmp_build_num'" if ($kmp and $kmp_build_num ne "");
    }

    $cmd .= " --define '_prefix $prefix'";

    $cmd .= " $main_packages{$name}{$ver}{'srpmpath'}";

    if (exists $package_pre_build_script{$name}) {
        print_and_log("Running $name pre build script: $package_pre_build_script{$name}\n", $verbose);
        ex("$package_pre_build_script{$name}");
    }

    print_and_log("Running $cmd\n", $verbose);
    system("echo $cmd > $ofedlogs/$name-$ver.rpmbuild.log 2>&1");
    system("$cmd >> $ofedlogs/$name-$ver.rpmbuild.log 2>&1");
    $res = $? >> 8;
    $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Failed to build $name $ver RPM", 1, "RED");
        addSetupInfo ("$ofedlogs/$name-$ver.rpmbuild.log");
        print_and_log_colored("See $ofedlogs/$name-$ver.rpmbuild.log", 1, "RED");
        exit 1;
    }

    my $arch = $target_cpu;
    if ($DISTRO =~ /RHEL5|XenServer/ and $target_cpu eq "i386" and $name =~ /ofa_kernel/) {
        $arch = 'i686';
    }
    $TMPRPMS = "$TOPDIR/RPMS/$arch";
    chomp $TMPRPMS;

    print_and_log("TMPRPMS $TMPRPMS\n", $verbose2);

    for my $myrpm ( <$TMPRPMS/*.rpm> ) {
        print_and_log("Created $myrpm\n", $verbose2);
        if ($name =~ /ofa_kernel/) {
            system("rpm -qlp $myrpm 2>/dev/null | grep lib.modules | awk -F '/' '{print\$4}' | sort -u >> $RPMS/.supported_kernels");
        }
        if ($name =~ /knem/) {
            $knem_prefix = `rpm -qlp $myrpm 2>/dev/null | grep -w "sbin\$" 2>/dev/null | sed -e "s@/sbin@@"`;
            chomp $knem_prefix;
        }
        my ($myrpm_name, $myrpm_arch) = (split ' ', get_rpm_name_arch($myrpm));
        # W/A for kmp packages that has only kmod and kmp rpms
        if($kmp and $myrpm_name =~ /kmp|kmod/ and
           $myrpm_name =~ /$bf_krpm_regex|kernel-mft-mlnx|iser|srp|mlnx-en|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/) {
            $myrpm_name =~ s/kmod-//g;
            $myrpm_name =~ s/-kmp.*//g;
        }
        if ($build_only and $myrpm_name =~ /kernel.*devel/) {
            system("echo rpm -ihv --root $builddir $myrpm");
            system("mkdir -p $builddir/var/lib/rpm >/dev/null 2>&1");
            system("rpm -ihv --nodeps --root $builddir $myrpm");
            $ENV{"OFA_DIR"} = $builddir . "$prefix/src/ofa_kernel";
        }
        move($myrpm, "$RPMS/$COMMON_DIR");
        $packages_info{$myrpm_name}{$ver}{'rpm_exist'} = 1;
    }

    if (exists $package_post_build_script{$name}) {
        print_and_log("Running $name post build script: $package_post_build_script{$name}\n", $verbose);
        ex("$package_post_build_script{$name}");
    }
}

sub build_rpm_32
{
    my $name = shift @_;
    my $ver = shift @_;
    my $parent = $packages_info{$name}{'parent'};
    my $cmd;
    my $res = 0;
    my $sig = 0;
    my $TMPRPMS;

    my $pref_env32;
    my $ldflags32;
    my $cflags32;
    my $cppflags32;
    my $cxxflags32;
    my $fflags32;
    my $ldlibs32;

    $ldflags32    .= " -m32 -g -O2 -L/usr/lib";
    $cflags32     .= " -m32 -g -O2";
    $cppflags32   .= " -m32 -g -O2";
    $cxxflags32   .= " -m32 -g -O2";
    $fflags32     .= " -m32 -g -O2";
    $ldlibs32     .= " -m32 -g -O2 -L/usr/lib";

    if ($prefix ne $default_prefix) {
        $ldflags32 .= " -L$prefix/lib";
        $cflags32 .= " -I$prefix/include";
        $cppflags32 .= " -I$prefix/include";
    }

    if ($parent =~ m/libibverbs/ and $arch !~ /ppc/ and $DISTRO =~ /SLES/) {
        $cppflags32 .= " -march=i586 ";
    }

    $pref_env32 .= " LDFLAGS='$ldflags32'";
    $pref_env32 .= " CFLAGS='$cflags32'";
    $pref_env32 .= " CPPFLAGS='$cppflags32'";
    $pref_env32 .= " CXXFLAGS='$cxxflags32'";
    $pref_env32 .= " FFLAGS='$fflags32'";
    $pref_env32 .= " LDLIBS='$ldlibs32'";

    $cmd = "$pref_env32 rpmbuild --rebuild $rpmbuild_flags --define '_topdir $TOPDIR' --define '_sourcedir %{_topdir}/SOURCES' --define '_specdir %{_topdir}/SPECS' --define '_srcrpmdir %{_topdir}/SRPMS' --define '_rpmdir %{_topdir}/RPMS' ";
    $cmd .= " --target $target_cpu32";
    $cmd .= " --define '_prefix $prefix'";
    $cmd .= " --define 'dist %{nil}'";
    $cmd .= " --define '_exec_prefix $prefix'";
    $cmd .= " --define '_sysconfdir $sysconfdir'";
    $cmd .= " --define '_usr $prefix'";
    $cmd .= " --define '_lib lib'";
    $cmd .= " --define '__arch_install_post %{nil}'";

    if ($parent =~ m/dapl/) {
        my $def_doc_dir = `rpm --eval '%{_defaultdocdir}'`;
        chomp $def_doc_dir;
        $cmd .= " --define '_prefix $prefix'";
        $cmd .= " --define '_exec_prefix $prefix'";
        $cmd .= " --define '_sysconfdir $sysconfdir'";
        $cmd .= " --define '_defaultdocdir $def_doc_dir/$main_packages{$parent}{$ver}{'name'}-$main_packages{$parent}{$ver}{'version'}'";
        $cmd .= " --define '_usr $prefix'";
    }

    if ( $parent =~ m/libibverbs/ and ($rpm_distro =~ m/xenserver|sles10/) ) {
        $cmd .= " --define 'configure_options --without-resolve-neigh' ";
    }

    if ($parent =~ m/libibverbs|libmlx|librdmacm|libibcm/) {
        if ($with_valgrind) {
            $cmd .= " --define '_with_valgrind 1'";
        } else {
            if (($DISTRO !~ m/RHEL/) or $disable_valgrind) {
                $cmd .= " --define '_disable_valgrind 1'";
            }
        }
    }

    $cmd .= " $main_packages{$parent}{$ver}{'srpmpath'}";

    print_and_log("Running $cmd\n", $verbose);
    open(LOG, "+>$ofedlogs/$parent-$ver.rpmbuild32bit.log");
    print LOG "Running $cmd\n";
    close LOG;
    system("$cmd >> $ofedlogs/$parent-$ver.rpmbuild32bit.log 2>&1");
    $res = $? >> 8;
    $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Failed to build $parent $ver RPM", 1, "RED");
        addSetupInfo ("$ofedlogs/$parent-$ver.rpmbuild32bit.log");
        print_and_log_colored("See $ofedlogs/$parent-$ver.rpmbuild32bit.log", 1, "RED");
        exit $ERROR;
    }

    $TMPRPMS = "$TOPDIR/RPMS/$target_cpu32";
    chomp $TMPRPMS;
    for my $myrpm ( <$TMPRPMS/*.rpm> ) {
        print_and_log("Created $myrpm\n", $verbose2);
        my ($myrpm_name, $myrpm_arch) = (split ' ', get_rpm_name_arch($myrpm));
        my $subdir = package_subdir($myrpm_name);
        move($myrpm, "$RPMS/$subdir/");
        $packages_info{$myrpm_name}{$ver}{'rpm_exist32'} = 1;
    }
}

# Build RPM from source RPM
sub build_rpm
{
    my $name = shift @_;
    my $ver = shift @_;
    my $cmd;
    my $res = 0;
    my $sig = 0;
    my $TMPRPMS;

    my $ldflags;
    my $cflags;
    my $cppflags;
    my $cxxflags;
    my $fflags;
    my $ldlibs;
    my $openmpi_comp_env;
    my $parent = $packages_info{$name}{'parent'};
    my $srpmdir;
    my $srpmpath_for_distro;

    delete $ENV{"mellanox_autodetect"};

    print_and_log("Build $name $ver RPM\n", $verbose);

    my $pref_env = '';
    if ($prefix ne $default_prefix) {
        if ($parent ne "mvapich" and $parent ne "mvapich2" and $parent !~ /openmpi/ and $parent ne "infinipath-psm") {
            $ldflags .= "$optflags -L$prefix/lib64 -L$prefix/lib";
            $cflags .= "$optflags -I$prefix/include";
            $cppflags .= "$optflags -I$prefix/include";
        }
    }

    if (not $packages_info{$name}{$ver}{'rpm_exist'}) {

        if ($parent eq "ibacm") {
            if ($DISTRO eq "FC14") {
                $ldflags    = " -g -O2 -lpthread";
            }
            $pref_env .= "rdmascript=openibd"
        }

        if ($arch eq "ppc64") {
            if ($DISTRO =~ m/SLES/ and $dist_rpm_rel gt 15.2) {
                # SLES 10 SP1
                if ($parent eq "ibutils") {
                    $packages_info{'ibutils'}{'configure_options'} .= " LDFLAGS=-L/usr/lib/gcc/powerpc64-suse-linux/4.1.2/64";
                }
                if ($parent =~ /ibutils2|cc_mgr|ar_mgr/ and $DISTRO =~ m/SLES10/) {
                    $packages_info{'ibutils2'}{'configure_options'} .= " LDFLAGS=-L/usr/lib/gcc/powerpc64-suse-linux/4.1.2/64";
                    $ldflags    .= " $optflags -m64 -g -O2 -L/usr/lib64 -L/usr/lib/gcc/powerpc64-suse-linux/4.1.2/64";
                    $cflags     .= " $optflags -m64 -g -O2";
                    $cppflags   .= " $optflags -m64 -g -O2";
                    $cxxflags   .= " $optflags -m64 -g -O2";
                    $fflags     .= " $optflags -m64 -g -O2";
                    $ldlibs     .= " $optflags -m64 -g -O2 -L/usr/lib64";
                }
                if ($parent =~ /openmpi/) {
                    $openmpi_comp_env .= ' LDFLAGS="-m64 -O2 -L/usr/lib/gcc/powerpc64-suse-linux/4.1.2/64"';
                }
                if ($parent eq "sdpnetstat" or $parent eq "rds-tools" or $parent eq "rnfs-utils") {
                    $ldflags    = " -g -O2";
                    $cflags     = " -g -O2";
                    $cppflags   = " -g -O2";
                    $cxxflags   = " -g -O2";
                    $fflags     = " -g -O2";
                    $ldlibs     = " -g -O2";
                }
            }
            else {
                if ($parent =~ /sdpnetstat|rds-tools|rnfs-utils/) {
                    # Override compilation flags on RHEL 4.0 and 5.0 PPC64
                    $ldflags    = " -g -O2";
                    $cflags     = " -g -O2";
                    $cppflags   = " -g -O2";
                    $cxxflags   = " -g -O2";
                    $fflags     = " -g -O2";
                    $ldlibs     = " -g -O2";
                }
                elsif ($parent !~ /ibutils|ibdump/) {
                    $ldflags    .= " $optflags -m64 -g -O2 -L/usr/lib64";
                    $cflags     .= " $optflags -m64 -g -O2";
                    $cppflags   .= " $optflags -m64 -g -O2";
                    $cxxflags   .= " $optflags -m64 -g -O2";
                    $fflags     .= " $optflags -m64 -g -O2";
                    $ldlibs     .= " $optflags -m64 -g -O2 -L/usr/lib64";
                }
            }
        }

        if ($parent =~ /mxm/) {
            $ldflags .= " -lz ";
        }


        if ($parent =~ /^lib/ and $arch =~ /x86_64|ppc64/) {
            $ldflags    = " -g -O3";
            $cflags     = " -g -O3";
            $cppflags   = " -g -O3";
            $cxxflags   = " -g -O3";
            $fflags     = " -g -O3";
            $ldlibs     = " -g -O3";
        }

        if ($parent =~ /libopensmssa|ibssa|ibacm_ssa/) {
            $cflags    .= " -DREMOTE_FLAGS_MASK=0xE0";
        }

        if ( ($parent =~ /perftest|fca|openmpi/) and ($DISTRO =~ /FC2[3-9]/) ) {
            $ldflags    .= " -fPIC";
            $cflags     .= " -fPIC";
        }
        if ( ($parent =~ /mstflint/) and ($DISTRO =~ /FC2[3-9]/) ) {
                if (-e "/usr/lib/rpm/redhat/redhat-hardened-cc1") {
                        $cflags    .= " -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1";
                }
        }

        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'";
        }

        if ($parent =~ /openmpi/) {
            $pref_env   .= " mellanox_autodetect='yes'";
        }

        $cmd = "$pref_env rpmbuild --rebuild $rpmbuild_flags --define '_topdir $TOPDIR' --define '_sourcedir %{_topdir}/SOURCES' --define '_specdir %{_topdir}/SPECS' --define '_srcrpmdir %{_topdir}/SRPMS' --define '_rpmdir %{_topdir}/RPMS' ";
        $cmd .= " --define 'dist %{nil}'";
        # bug in RH 8.0 rpmbuild will not work with --target parameter
        if ( ($parent =~ /mstflint|openmpi/) and ($DISTRO =~ /RHEL8 | OL8/x) ) {
            $cmd .= "";
        } else {
            $cmd .= " --target $target_cpu";
        }

        # Prefix should be defined per package
        if ($parent eq "ibutils") {
            $packages_info{'ibutils'}{'configure_options'} .= " --with-osm=$prefix";
            if ($DISTRO =~ m/SLES12/) {
                my $tklib = `/bin/ls -1d /usr/lib*/tcl/tk8.6 2> /dev/null | head -1`;
                chomp $tklib;
                $packages_info{'ibutils'}{'configure_options'} .= " --with-tk-lib=$tklib" if ($tklib);
            }
            $cmd .= " --define '_prefix $ibutils_prefix'";
            $cmd .= " --define '_exec_prefix $ibutils_prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $ibutils_prefix'";
            $cmd .= " --define '_mandir $ibutils_prefix/share/man'";
            $cmd .= " --define 'build_ibmgtsim 1'";
            $cmd .= " --define '__arch_install_post %{nil}'";
        }
        elsif ($parent eq "ibutils2") {
            my $global_cflags = `rpm --eval '%{__global_cflags}'`;
            chomp $global_cflags;
            $cmd .= " --define '__global_cflags $global_cflags'";
            $cmd =~ s/-Wp,-D_FORTIFY_SOURCE=2//g;
            $cmd .= " --define '_prefix $ibutils2_prefix'";
            $cmd .= " --define '_with_umad $prefix'";
            $cmd .= " --define '__arch_install_post %{nil}'";
            $cmd .= " --define '_exec_prefix $ibutils2_prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $ibutils2_prefix'";
            $cmd .= " --define '_mandir $ibutils2_prefix/share/man'";
            if ($arch eq "ppc64" and $DISTRO =~ m/SLES10/) {
                $cmd .= " --define '__make make libibis_la_LIBADD=\"-libumad -L../../misc/tool_trace/ -ltt\"'";
            }
        }
        elsif ($parent eq "cc_mgr") {
            $packages_info{'cc_mgr'}{'configure_options'} .= " --with-ibutils2=$ibutils2_prefix";
            $packages_info{'cc_mgr'}{'configure_options'} .= " --with-osm=$prefix";
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define '__arch_install_post %{nil}'";
        }
        elsif ($parent eq "ar_mgr") {
            $packages_info{'ar_mgr'}{'configure_options'} .= " --with-ibutils2=$ibutils2_prefix";
            $packages_info{'ar_mgr'}{'configure_options'} .= " --with-osm=$prefix";
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define '__arch_install_post %{nil}'";
        }
        elsif ($parent eq "dump_pr") {
            $packages_info{'dump_pr'}{'configure_options'} .= " --with-osm=$prefix";
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define '__arch_install_post %{nil}'";
        }
        elsif ($parent =~ /mxm|fca|hcoll/) {
            $cmd =~ s/-Wp,-D_FORTIFY_SOURCE=2//g;
            $cmd =~ s/-D_FORTIFY_SOURCE=2//g;
            if ($parent =~ /hcoll/) {
                if (is_installed("sharp")) {
                    $cmd .= " --define 'configure_opts --with-sharp=/opt/mellanox/sharp'";
                }
            }
            $cmd .= " --define '__arch_install_post %{nil}'";
            $cmd .= " --nodeps ";
        }
        elsif ($parent =~ /openshmem/) {
            if (not $knem_prefix) {
                $knem_prefix = `rpm -ql $knem_rpm 2>/dev/null | grep -w "sbin\$" 2>/dev/null | sed -e "s@/sbin@@" | head -1`;
                chomp $knem_prefix;
            }

            my $fca_opt = '';
            if (is_installed("fca")) {
                $fca_opt = "--with-fca=$fca_prefix";
            } else {
                $fca_opt = "--without-fca";
            }

            my $mxm_opt = '';
            if (is_installed("mxm")) {
                $mxm_opt = "--with-mxm=$mxm_prefix";
            } else {
                $mxm_opt = "--without-mxm";
            }

            my $oshmem_opt = "--with-platform=contrib/platform/mellanox/optimized --with-oshmem --with-oshmem-test ";

            $cmd .= " --define 'configure_opts $fca_opt  $mxm_opt --with-knem=$knem_prefix $pmi_opt $oshmem_opt'";
            $cmd .= " --define '__arch_install_post %{nil}'";
            $cmd .= " --nodeps ";
        }
        elsif ($parent =~ /bupc/) {

            # Do not add _prefix for bupc as it is hardcoded in the bupc.spec
            # it's preferred to build bupc with openmpi 1.6
            my $MPI_CC = "";
            my $mpi_1_6 = "";
            for my $mpiver (keys %{$main_packages{'openmpi'}}){
                $MPI_CC = "MPI_CC=$prefix/mpi/gcc/openmpi-$mpiver/bin/mpicc";
                if ($mpiver lt "1.7") {
                    $mpi_1_6 = $mpiver;
                }
            }
            if ($mpi_1_6 ne "") {
                $MPI_CC = "MPI_CC=$prefix/mpi/gcc/openmpi-$mpi_1_6/bin/mpicc";
            }

            my $enable_mxm = '';
            if (is_installed("mxm")) {
                $enable_mxm = "--enable-mxm --with-mxmhome=$mxm_prefix";
            } else {
                $enable_mxm = "--disable-mxm";
            }
            my $enable_fca = '';
            if (is_installed("fca")) {
                $enable_fca = "--with-fca-enabled-by-default=0 --with-fca=$fca_prefix";
            } else {
                $enable_fca = "--disable-fca";
            }

            $cmd .= " --define 'configure_opts --disable-aligned-segments --enable-sptr-struct $enable_mxm $enable_fca --enable-mpi-compat $MPI_CC $pmi_opt'";
            $cmd .= " --define '__arch_install_post %{nil}'";
            $cmd .= " --nodeps ";
        }
        elsif ( $parent eq "mvapich") {
            $cmd .= " --define '_name $name'";
            $cmd .= " --define 'compiler $compiler'";
            $cmd .= " --define 'openib_prefix $prefix'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define 'use_mpi_selector 1'";
            $cmd .= " --define '__arch_install_post %{nil}'";
            if ($packages_info{'mvapich'}{'configure_options'}) {
                $cmd .= " --define 'configure_options $packages_info{'mvapich'}{'configure_options'}'";
            }
            $cmd .= " --define 'mpi_selector $prefix/bin/mpi-selector'";
            $cmd .= " --define '_prefix $prefix/mpi/$compiler/$parent-$main_packages{$parent}{$ver}{'version'}'";
        }
        elsif ($parent eq "mvapich2") {
            $cmd .= " --define '_name $name'";
            $cmd .= " --define 'impl $mvapich2_conf_impl'";

            if ($compiler eq "gcc") {
                if ($gcc{'gfortran'}) {
                    if ($arch eq "ppc64") {
                        $mvapich2_comp_env = 'CC="gcc -m64" CXX="g++ -m64" F77="gfortran -m64" FC="gfortran -m64"';
                    }

                    else {
                        $mvapich2_comp_env = "CC=gcc CXX=g++ F77=gfortran FC=gfortran";
                    }
                }

                elsif ($gcc{'g77'}) {
                    if ($arch eq "ppc64") {
                        $mvapich2_comp_env = 'CC="gcc -m64" CXX="g++ -m64" F77="g77 -m64" FC=/bin/false';
                    }

                    else {
                        $mvapich2_comp_env = "CC=gcc CXX=g++ F77=g77 FC=/bin/false";
                    }
                }

                else {
                    $mvapich2_comp_env .= " --disable-f77 --disable-fc";
                }
            }

            if ($mvapich2_conf_impl eq "ofa") {
                print_and_log("Building the MVAPICH2 RPM [OFA]...\n", $verbose);

                $cmd .= " --define 'rdma --with-rdma=gen2'";
                $cmd .= " --define 'ib_include --with-ib-include=$prefix/include'";
                $cmd .= " --define 'ib_libpath --with-ib-libpath=$prefix/lib";
                $cmd .= "64" if $arch =~ m/x86_64|ppc64/;
                $cmd .= "'";

                if ($mvapich2_conf_ckpt) {
                    $cmd .= " --define 'blcr 1'";
                    $cmd .= " --define 'blcr_include --with-blcr-include=$mvapich2_conf_blcr_home/include'";
                    $cmd .= " --define 'blcr_libpath --with-blcr-libpath=$mvapich2_conf_blcr_home/lib'";
                }
            }

            elsif ($mvapich2_conf_impl eq "udapl") {
                print_and_log("Building the MVAPICH2 RPM [uDAPL]...\n", $verbose);

                $cmd .= " --define 'rdma --with-rdma=udapl'";
                $cmd .= " --define 'dapl_include --with-dapl-include=$prefix/include'";
                $cmd .= " --define 'dapl_libpath --with-dapl-libpath=$prefix/lib";
                $cmd .= "64" if $arch =~ m/x86_64|ppc64/;
                $cmd .= "'";

                $cmd .= " --define 'cluster_size --with-cluster-size=$mvapich2_conf_vcluster'";
                $cmd .= " --define 'io_bus --with-io-bus=$mvapich2_conf_io_bus'";
                $cmd .= " --define 'link_speed --with-link=$mvapich2_conf_link_speed'";
                $cmd .= " --define 'dapl_provider --with-dapl-provider=$mvapich2_conf_dapl_provider'" if ($mvapich2_conf_dapl_provider);
            }

            if ($packages_info{'mvapich2'}{'configure_options'}) {
                $cmd .= " --define 'configure_options $packages_info{'mvapich2'}{'configure_options'}'";
            }

            $cmd .= " --define 'shared_libs 1'" if $mvapich2_conf_shared_libs;
            $cmd .= " --define 'romio 1'" if $mvapich2_conf_romio;
            $cmd .= " --define 'comp_env $mvapich2_comp_env'";
            $cmd .= " --define 'auto_req 0'";
            $cmd .= " --define 'mpi_selector $prefix/bin/mpi-selector'";
            $cmd .= " --define '_prefix $prefix/mpi/$compiler/$parent-$main_packages{$parent}{$ver}{'version'}'";
        }
        elsif ($parent =~ /openmpi/) {
            my $use_default_rpm_opt_flags = 1;
            my $openmpi_ldflags = '';
            my $openmpi_wrapper_cxx_flags;
            my $openmpi_lib;

            if ($arch =~ m/x86_64|ppc64/) {
                $openmpi_lib = 'lib64';
            }
            else {
                $openmpi_lib = 'lib';
            }

            if ($compiler eq "gcc") {
                if ($gcc{'g++'}) {
                }
                else {
                    $openmpi_comp_env .= " --disable-mpi-cxx";
                }
                if ($gcc{'gfortran'}) {
                }
                elsif ($gcc{'g77'}) {
                    $openmpi_comp_env .= " F77=g77 --disable-mpi-f90";
                }
                else {
                    $openmpi_comp_env .= " --disable-mpi-f77 --disable-mpi-f90";
                }
            }

            if ($arch eq "ppc64") {
                # In the ppc64 case, add -m64 to all the relevant
                # flags because it's not the default.  Also
                # unconditionally add $OMPI_RPATH because even if
                # it's blank, it's ok because there are other
                # options added into the ldflags so the overall
                # string won't be blank.
                $openmpi_comp_env .= ' CFLAGS="-m64 -O2" CXXFLAGS="-m64 -O2" FCFLAGS="-m64 -O2" FFLAGS="-m64 -O2"';
                $openmpi_comp_env .= ' --with-wrapper-ldflags="-g -O2 -m64 -L/usr/lib64" --with-wrapper-cflags=-m64';
                $openmpi_comp_env .= ' --with-wrapper-cxxflags=-m64 --with-wrapper-fflags=-m64 --with-wrapper-fcflags=-m64';
                $openmpi_wrapper_cxx_flags .= " -m64";
            }

            if ($openmpi_wrapper_cxx_flags) {
                $openmpi_comp_env .= " --with-wrapper-cxxflags=\"$openmpi_wrapper_cxx_flags\"";
            }

            $openmpi_comp_env .= " --with-platform=contrib/platform/mellanox/optimized $pmi_opt";

            # Let openmpi automatically find plugins and use them
            $ENV{"mellanox_autodetect"} = "yes";

            $cmd .= " --define '_name $name'";
            $cmd .= " --define 'mpi_selector $prefix/bin/mpi-selector'";
            $cmd .= " --define 'use_mpi_selector 1'";
            $cmd .= " --define 'install_shell_scripts 1'";
            $cmd .= " --define 'shell_scripts_basename mpivars'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define 'ofed 0'";
            $cmd .= " --define '_prefix $prefix/mpi/$compiler/$parent-$main_packages{$parent}{$ver}{'version'}'";
            $cmd .= " --define '_defaultdocdir $prefix/mpi/$compiler/$parent-$main_packages{$parent}{$ver}{'version'}'";
            $cmd .= " --define '_mandir %{_prefix}/share/man'";
            $cmd .= " --define '_datadir %{_prefix}/share'";
            $cmd .= " --define 'mflags -j 4'";
            $cmd .= " --define 'configure_options $packages_info{'openmpi'}{'configure_options'} $openmpi_ldflags $openmpi_comp_env '";
            $cmd .= " --define 'use_default_rpm_opt_flags $use_default_rpm_opt_flags'";

            if ($DISTRO =~ /RHEL8 | OL8 | EULEROS2.0SP8/x) {
                $cmd .= " --undefine _hardened_build";
            }
        }
        elsif ($parent eq "mpitests") {
            my $mpi = $name;
            $mpi =~ s/mpitests_//g;
            my $mpiVer = $packages_info{$name}{'base_mpi_version'};

            $cmd .= " --define '_name $name'";
            $cmd .= " --define 'root_path /'";
            $cmd .= " --define '_usr $prefix'";
            $cmd .= " --define 'path_to_mpihome $prefix/mpi/$compiler/$mpi-$mpiVer'";
        }
        elsif ($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'";
        }
        elsif ($parent =~ m/dapl/) {
            my $def_doc_dir = `rpm --eval '%{_defaultdocdir}'`;
            chomp $def_doc_dir;
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_defaultdocdir $def_doc_dir/$main_packages{$parent}{$ver}{'name'}-$main_packages{$parent}{$ver}{'version'}'";
            $cmd .= " --define '_usr $prefix'";
        }
        elsif ($parent =~ /libibprof/) {
            $cmd .= " --define 'configure_opts --with-ofed=$prefix'";
            $cmd .= " --nodeps ";
        }
        elsif ($parent =~ /fabric-collector/) {
            $cmd .= " --define '_prefix /opt/mellanox/fabric_collector'";
        }
        elsif ($parent =~ /mlnx-ethtool/) {
            $cmd .= " --define '_prefix $mlnx_ethtool_prefix'";
            $cmd .= " --define '_mandir $mlnx_ethtool_mandir'";
            $cmd .= " --define '_defaultdocdir $mlnx_ethtool_defaultdocdir'";
        }
        elsif ($parent =~ /libopensmssa/) {
            $cmd .= " --define '_includedir /usr/include'";
            $cmd .= " --define '_libdir /usr/lib'";
        }
        elsif ($parent =~ /ibssa/) {
            $cmd .= " --define '_includedir /usr/include'";
            $cmd .= " --define '_libdir /usr/lib'";
        }
        elsif ($parent =~ /ibacm_ssa/) {
            $cmd .= " --define '_usr /opt/mellanox/ssa'";
            $cmd .= " --define '_prefix /opt/mellanox/ssa'";
            $cmd .= " --define '_includedir /usr/include'";
            $cmd .= " --define '_libdir /usr/lib'";
            $cmd .= " --define '_sysconfdir /etc/ssa'";
        }
        elsif ($parent =~ /libdisni/) {
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
            my $jdk_home = `readlink -f /usr/bin/java | sed -e "s@/jre/bin/java@@"`;
            $packages_info{'libdisni'}{'configure_options'} .= " --with-jdk=$jdk_home";
        }
        elsif ($parent eq 'rdma-core') {
            if ($libudev_devel eq "") {
                # FIXME: XenServer et al. don't have udev at all.
                # The rdma-core will build fine without it, but not
                # having it probably breaks an assumption or two in the
                # pacaging. Add an option to build the package --without
                # udev to rdma-core and replace this with '--without udev'
                $cmd .= " --nodeps";
            }
            if ($DISTRO =~ /RHEL8 | OL8 | FC2[6-9]/x) {
                # Due to rdma-core dependencies it requires with_pyverbs to be
                # enabled on RHEL8
                $cmd .= " --define '_with_pyverbs 1'";
            }
        }
        else {
            $cmd .= " --define '_prefix $prefix'";
            $cmd .= " --define '_exec_prefix $prefix'";
            $cmd .= " --define '_sysconfdir $sysconfdir'";
            $cmd .= " --define '_usr $prefix'";
        }

        if ($parent =~ /mstflint/) {
            $cmd .= " --define 'noinband 1'";
            my $openssl_version = `/usr/bin/openssl version 2> /dev/null | cut -d ' ' -f 2`;
            chomp $openssl_version;
            my $nopenssl = 1;
            if ($openssl_version =~ /^1.*/) {
                $nopenssl = 0;
            }
            $cmd .= " --define 'nopenssl $nopenssl'";
            $cmd .= " --define 'ibmadlib %{nil}'";
            if ($DISTRO =~ /RHEL8 | OL8 | EULEROS2.0SP8/x) {
                # Work around overriding of %optflags in the rpm spec:
                $cmd .= " --undefine _hardened_build";
            }
        }

        if ($parent eq "mft") {
            $cmd .= " --define 'nodevmon 1'";
        }

        if ($parent eq "librdmacm") {
            if ( $packages_info{'ibacm'}{'selected'}) {
                $packages_info{'librdmacm'}{'configure_options'} .= " --with-ib_acm";
            }
        }

        if ($parent =~ /sharp/) {
            $cmd .= " --nodeps ";
        }

        if ($packages_info{$parent}{'configure_options'} or $user_configure_options) {
            $cmd .= " --define 'configure_options $packages_info{$parent}{'configure_options'} $user_configure_options'";
        }

        if ( $parent =~ m/libibverbs/ and ($rpm_distro =~ m/xenserver|sles10/) ) {
            $cmd .= " --define 'configure_options --without-resolve-neigh' ";
        }

        if ($parent =~ m/libibverbs|libmlx|librdmacm|libibcm/) {
            if ($with_valgrind) {
                $cmd .= " --define '_with_valgrind 1'";
            } else {
                if (($DISTRO !~ m/RHEL/) or $disable_valgrind) {
                    $cmd .= " --define '_disable_valgrind 1'";
                }
            }
        }
        if ($parent =~ /mxm|ucx/) {
            if ($with_valgrind or (($DISTRO =~ m/RHEL/) and (not $disable_valgrind))) {
                $cmd .= " --with valgrind ";
            }
        }
        if ($parent =~ /ucx/) {
            if (not $have_numa_libs) {
                $cmd .= " --define 'configure_options --disable-numa' ";
            }
            $cmd .= " --nodeps ";
            if ($cuda_top_dir) {
                $cmd .= " --with cuda";
                $cmd .= " --define 'configure_options --with-cuda=$cuda_top_dir'";
            }
            if ($packages_info{'ucx-gdrcopy'}{'available'}) {
                $cmd .= " --with gdrcopy";
            }
            if ($packages_info{'ucx-knem'}{'available'}) {
                $cmd .= " --with knem";
            }
            if (not $packages_info{'ucx-cma'}{'available'}) {
                $cmd .= " --without cma";
            }
            if ($packages_info{'ucx-ib-cm'}{'available'}) {
                $cmd .= " --with ib_cm";
            } else {
                $cmd .= " --without ib_cm";
            }
        }
        if ($parent =~ /openvswitch/) {
            $cmd .= " --without check ";
        }

        $cmd .= " $main_packages{$parent}{$ver}{'srpmpath'}";

        if (exists $package_pre_build_script{$name}) {
            print_and_log("Running $name pre build script: $package_pre_build_script{$name}\n", $verbose);
            ex("$package_pre_build_script{$name}");
        }

        print_and_log("Running $cmd\n", $verbose);
        open(LOG, "+>$ofedlogs/$parent-$ver.rpmbuild.log");
        print LOG "Running $cmd\n";
        close LOG;
        system("$cmd >> $ofedlogs/$parent-$ver.rpmbuild.log 2>&1");
        $res = $? >> 8;
        $sig = $? & 127;
        if ($sig or $res) {
            print_and_log_colored("Failed to build $parent $ver RPM", 1, "RED");
            addSetupInfo ("$ofedlogs/$parent-$ver.rpmbuild.log");
            print_and_log_colored("See $ofedlogs/$parent-$ver.rpmbuild.log", 1, "RED");
            exit 1;
        }

        $TMPRPMS = "$TOPDIR/RPMS/$target_cpu";
        chomp $TMPRPMS;

        print_and_log("TMPRPMS $TMPRPMS\n", $verbose2);

        for my $myrpm ( <$TMPRPMS/*.rpm> ) {
            print_and_log("Created $myrpm\n", $verbose2);
            my ($myrpm_name, $myrpm_arch) = (split ' ', get_rpm_name_arch($myrpm));
            my $subdir = package_subdir($myrpm_name);
            move($myrpm, "$RPMS/$subdir/");
            $packages_info{$myrpm_name}{$ver}{'rpm_exist'} = 1;
        }
    }

    if ($build32 and $packages_info{$name}{'install32'} and
        not $packages_info{$name}{$ver}{'rpm_exist32'}) {
        build_rpm_32($name, $ver);
    }

    if (exists $package_post_build_script{$name}) {
        print_and_log("Running $name post build script: $package_post_build_script{$name}\n", $verbose);
        ex("$package_post_build_script{$name}");
    }
}

sub install_kernel_rpm
{
    my $name = shift @_;
    my $ver = shift @_;
    my $cmd;
    my $res = 0;
    my $sig = 0;

    my $version = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'version'};

    # release number is from source without kver
    my $release = "$main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'}";
    $release =~ s/\.$rpm_distro$//g;
    $release = "${release}.kver.${kernel_rel}";
    my $common_dir = "$RPMS/$COMMON_DIR";

    my $arch = $target_cpu;

    if (exists $package_pre_install_script{$name}) {
        print_and_log("Running $name pre install script: $package_pre_install_script{$name}\n", $verbose);
        ex("$package_pre_install_script{$name}");
    }

    # will enter this block if  KMP is enabled and this is a package that supports kmp
    if (($name =~ /ofa_kernel|$bf_krpm_regex|knem|kernel-mft-mlnx|ummunotify-mlnx|iser|srp|mlnx-en$|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/) and $kmp) {
        # WA required to get rpmpath for KMP RPMs
        set_existing_rpms();
        if ($DISTRO =~ /RHEL5|XenServer/ and $target_cpu eq "i386") {
            $arch = 'i686';
        }

        if ($DISTRO =~ /SLES/) {
            my $kver = get_rpm_ver_one('kernel-source');
            if ($name =~ /kmp/ and  $kver !~ /$kernel_rel/) {
                return;
            }

        }

        # KMP packages that have only kmod/kmp rpms
        if ($name !~ /$bf_krpm_regex|kernel-mft-mlnx|iser|srp|mlnx-en|mlnx-sdp|mlnx-rds|mlnx-nfsrdma|mlnx-nvme|mlnx-rdma-rxe/) {
            $cmd = "rpm $rpminstall_parameter -vh $rpminstall_flags";
            $cmd .= " --nodeps";
            $cmd .= " $main_packages{$name}{$ver}{'rpmpath'}";

            print_and_log("Installing $name $ver RPM\n", $verbose);
            print_and_log("cmd: $cmd\n", $verbose);
            print_and_log("Running $cmd\n", $verbose2);
            system("$cmd > $ofedlogs/$name-$ver.rpminstall.log 2>&1");
            $res = $? >> 8;
            $sig = $? & 127;
            if ($sig or $res) {
                print_and_log_colored("Failed to install $name $ver RPM", 1, "RED");
                addSetupInfo ("$ofedlogs/$name-$ver.rpminstall.log");
                print_and_log("See $ofedlogs/$name-$ver.rpminstall.log", 1, "RED");
                exit $ERROR;
            }
            system("cat $ofedlogs/$name-$ver.rpminstall.log") if (not $quiet);
            system("/sbin/depmod $kernel > /dev/null 2>&1");

            if ($name eq 'mlnx-ofa_kernel-devel') {
                if (exists $package_post_install_script{$name}) {
                    print_and_log("Running $name post install script: $package_post_install_script{$name}\n", $verbose);
                    ex("$package_post_install_script{$name}");
                }
                return;
            }
        }

        my @kmp_packages;
        if ($DISTRO =~ /SLES|SUSE/) {
            @kmp_packages = <$common_dir/$name-kmp*.$rpm_distro.$arch.rpm>;
        } else {
            @kmp_packages = <$common_dir/kmod*$name-*.$rpm_distro.$arch.rpm>;
        }
        if (not @kmp_packages) {
            print_and_log_colored("$name KMP rpms do not exist", 1, "RED");
            exit $ERROR;
        }

        # Install kernel-mft-mlnx-utils when available - relevant only when KMP=1
        if ($name =~ /kernel-mft-mlnx/) {
            my @mft_utils = <$common_dir/$name-utils*.$rpm_distro.$arch.rpm>;
            if (@mft_utils) {
                push(@kmp_packages, $mft_utils[0]);
            }
        }

        for my $kmp_package (@kmp_packages) {
            $cmd = "rpm $rpminstall_parameter -vh $rpminstall_flags";
            $cmd .= " --nodeps";
            if ($kmp_package =~ /rshim|tmfifo/) {
                # rshim conflicts with tmfifo.
                # Actually, they should not be installed on the same host
                # But this was done for the build purposes
                $cmd .= " --force";
            }
            if ($speed_up_kmp) {
                $cmd .= " --nopost";
                system("rpm -qpl $kmp_package | grep '\\.ko\$' >> $modules_list");
            }
            $cmd .= " $kmp_package";

            my $kmpname =`rpm -qp --queryformat "[%{NAME}]\n" $kmp_package 2>/dev/null`;
            chomp $kmpname;
            print_and_log("Installing $kmpname $ver RPM\n", $verbose);
            print_and_log("Running $cmd\n", $verbose2);
            system("$cmd > $ofedlogs/$kmpname-$ver.rpminstall.log 2>&1");
            $res = $? >> 8;
            $sig = $? & 127;
            if ($sig or $res) {
                print_and_log_colored("Failed to install $name $ver RPM", 1, "RED");
                addSetupInfo ("$ofedlogs/$kmpname-$ver.rpminstall.log");
                print_and_log_colored("See $ofedlogs/$kmpname-$ver.rpminstall.log", 1, "RED");
                exit $ERROR;
            }
            system("cat $ofedlogs/$kmpname-$ver.rpminstall.log") if (not $quiet);
            system("/sbin/depmod $kernel > /dev/null 2>&1");

            if (exists $package_post_install_script{$kmpname}) {
                print_and_log("Running $kmpname post install script: $package_post_install_script{$kmpname}\n", $verbose);
                ex("$package_post_install_script{$kmpname}");
            }
        }
        return;
    }

    if ($name =~ /mlx4_accl/) {
        $release = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'} . '.' . $release;
    }

    if (($name =~ /mlnx-ofa_kernel/ and $name ne "mlnx-ofa_kernel-modules") or
        ($name =~ /mlnx-en/) or
        ($name =~ /knem/ and $name ne "knem-modules")) {
        $release = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'} . ".$rpm_distro";
    }

    if ($name =~ /mlnx-ofa_kernel/ and $DISTRO =~ /RHEL5|XenServer/ and $target_cpu eq "i386") {
        $arch = 'i686';
    }
    my $package = "$common_dir/$name-$version-$release.$arch.rpm";

    if (not -e $package) {
        my $rpmrel_nodist = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'};
        $rpmrel_nodist =~ s/\.$rpm_distro\$//g;
        if (-e "$common_dir/$name-$version-$kernel_rel.$arch.rpm") {
            $package = "$common_dir/$name-$version-$kernel_rel.$arch.rpm";
        } elsif (-e "$common_dir/$name-$version-${kernel_rel}_$rpmrel_nodist.$arch.rpm") {
            $package = "$common_dir/$name-$version-${kernel_rel}_$rpmrel_nodist.$arch.rpm";
        } else {
            print_and_log_colored("$package does not exist", 1, "RED");
            exit $ERROR;
        }
    }

    $cmd = "rpm -iv $rpminstall_flags";
    $cmd .= " --nodeps";
    if ($package =~ /rshim|tmfifo/) {
        # rshim conflicts with tmfifo.
        # Actually, they should not be installed on the same host
        # But this was done for the build purposes
        $cmd .= " --force";
    }
    $cmd .= " $package";

    print_and_log("Running $cmd\n", $verbose);
    system("$cmd > $ofedlogs/$name-$ver.rpminstall.log 2>&1");
    $res = $? >> 8;
    $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Failed to install $name $ver RPM", 1, "RED");
        addSetupInfo ("$ofedlogs/$name-$ver.rpminstall.log");
        print_and_log_colored("See $ofedlogs/$name-$ver.rpminstall.log", 1, "RED");
        exit $ERROR;
    }

    if (exists $package_post_install_script{$name}) {
        print_and_log("Running $name post install script: $package_post_install_script{$name}\n", $verbose);
        ex("$package_post_install_script{$name}");
    }
}

sub install_rpm_32
{
    my $name = shift @_;
    my $ver = shift @_;
    my $cmd;
    my $res = 0;
    my $sig = 0;
    my $subdir;
    my $package;

    my $version = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'version'};
    my $release = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'};

    $subdir = package_subdir($name);
    $package = "$RPMS/$subdir/$name-$version-$release.$target_cpu32.rpm";

    if (not -e $package) {
        print_and_log_colored("$package does not exist", 1, "RED");
        # exit 1;
    }

    $cmd = "rpm $rpminstall_parameter -v $rpminstall_flags";
    if ($DISTRO =~ m/SLES|SUSE/) {
        $cmd .= " --force";
    }
    $cmd .= " $package";

    print_and_log("Running $cmd\n", $verbose);
    system("$cmd > $ofedlogs/$name-$ver.rpminstall.log 2>&1");
    $res = $? >> 8;
    $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Failed to install $name $ver RPM", 1, "RED");
        addSetupInfo ("$ofedlogs/$name-$ver.rpminstall.log");
        print_and_log_colored("See $ofedlogs/$name-$ver.rpminstall.log", 1, "RED");
        exit 1;
    }
}

# Install required RPM
sub install_rpm
{
    my $name = shift @_;
    my $ver = shift @_;
    my $tmp_name;
    my $cmd;
    my $res = 0;
    my $sig = 0;
    my $subdir;
    my $package;

    my $version = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'version'};
    my $release = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'};

    # user-space-only will get here
    if ($name eq "mlnx-ofa_kernel") {
        $release = $main_packages{$packages_info{$name}{'parent'}}{$ver}{'release'} . ".$rpm_distro";
    }

    $subdir = package_subdir($name);
    $package = "$RPMS/$subdir/$name-$version-$release.$target_cpu.rpm";

    if (not -e $package) {
        print_and_log_colored("$package does not exist", 1, "RED");
        exit $ERROR;
    }

    if ($name eq "mpi-selector") {
        $cmd = "rpm -Uv $rpminstall_flags --force";
    } elsif ($name =~ /openmpi|mvapich2/) {
        if (is_installed("$name-$version")) {
            system("rpm -e --nodeps $name-$version");
        }
        $cmd = "rpm -iv $rpminstall_flags --force";
    } else {
        if ($name eq "opensm" and $DISTRO eq "DEBIAN") {
            $rpminstall_flags .= " --nopost";
        }
        $cmd = "rpm $rpminstall_parameter -v $rpminstall_flags";
    }

    $cmd .= " --nodeps";

    if ($name =~ /ibacm/) {
        $cmd .= " --noscripts";
    }

    $cmd .= " $package";

    if (exists $package_pre_install_script{$name}) {
        print_and_log("Running $name pre install script: $package_pre_install_script{$name}\n", $verbose);
        ex("$package_pre_install_script{$name}");
    }

    print_and_log("Running $cmd\n", $verbose);
    system("$cmd > $ofedlogs/$name-$ver.rpminstall.log 2>&1");
    $res = $? >> 8;
    $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Failed to install $name $ver RPM", 1, "RED");
        addSetupInfo ("$ofedlogs/$name-$ver.rpminstall.log");
        print_and_log_colored("See $ofedlogs/$name-$ver.rpminstall.log", 1, "RED");
        exit $ERROR;
    }

    if ($build32 and $packages_info{$name}{'install32'}) {
        install_rpm_32($name, $ver);
    }

    if (exists $package_post_install_script{$name}) {
        print_and_log("Running $name post install script: $package_post_install_script{$name}\n", $verbose);
        ex("$package_post_install_script{$name}");
    }
}

sub print_package_info
{
    print_and_log("\n\nDate:" . localtime(time) . "\n", 1);
    for my $key ( keys %main_packages ) {
        print_and_log("$key:\n", 1);
        print_and_log("======================================\n", 1);
        for my $ver ( keys %{$main_packages{$key}} ) {
            print_and_log("-------------------------------\n", 1);
            my %pack = %{$main_packages{$key}{$ver}};
            for my $subkey ( keys %pack ) {
                print_and_log($subkey . ' = ' . $pack{$subkey} . "\n", 1);
            }
        }
        print_and_log("\n", 1);
    }
}

sub is_installed_deb
{
    my $res = 0;
    my $name = shift @_;
    my $result = `dpkg-query -W -f='\${version}' $name`;
    if (($result eq "") && ($? == 0) ){
        $res = 1;
    }
    return not $res;
}

sub is_installed
{
    my $res = 0;
    my $name = shift @_;

    if ($DISTRO eq "DEBIAN") {
        system("dpkg-query -W -f='\${Package} \${Version}\n' $name > /dev/null 2>&1");
    }
    else {
        system("rpm -q $name > /dev/null 2>&1");
    }
    $res = $? >> 8;

    if($res and $name eq "cmake") {
        system("which cmake > /dev/null 2>&1");
        $res = $? >> 8;
    }

    return not $res;
}

# Sets the global $rpm_macros_path
sub set_rpm_macros_path() {
    return unless ($add_debuginfo_macros);

    my $macros_path = `rpmbuild --showrc | awk '/^Macro path:/ {print \$3}'`;
    chomp $macros_path;
    $rpm_macros_file = File::Temp->new(DIR=>$TMPDIR, CLEANUP=>1);
    print $rpm_macros_file <<'EOF';
# rpmmacros snippet for enabling debug info in SLES
# Generated by install.pl .

%_enable_debug_packages 1
# Some extra features that could be handy:
%_include_minidebuginfo 1
# Seems to have extra dependencies:
#_include_gdb_index 1
# Terminate build on missing build ids:
%_missing_build_ids_terminate_build 1

# Add the macro debug_package right before the install section.
# But only if:
# * It was not added before explicitly (__debug_package not defined)
# * It has not been disabled (_enable_debug_packages set)
%install %{!?__debug_package:%{?_enable_debug_packages:%{debug_package}}}\
%%install\
%{nil}
EOF
    $rpm_macros_path = $rpm_macros_file->filename . ":$macros_path";
    system("cat ".  $rpm_macros_file->filename);
}

sub count_ports
{
    my $cnt = 0;
    open(LSPCI, "/sbin/lspci -n|");

    while (<LSPCI>) {
        if (/15b3:6282/) {
            $cnt += 2;  # infinihost iii ex mode
        }
        elsif (/15b3:5e8c|15b3:6274/) {
            $cnt ++;    # infinihost iii lx mode
        }
        elsif (/15b3:5a44|15b3:6278/) {
            $cnt += 2;  # infinihost mode
        }
        elsif (/15b3:6340|15b3:634a|15b3:6354|15b3:6732|15b3:673c|15b3:6746|15b3:6750|15b3:1003/) {
            $cnt += 2;  # connectx
        }
    }
    close (LSPCI);

    return $cnt;
}

sub is_valid_ipv4
{
    my $ipaddr = shift @_;

    if( $ipaddr =~ m/^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)/ ) {
        if($1 <= 255 && $2 <= 255 && $3 <= 255 && $4 <= 255) {
            return 0;
        }
    }
    return 1;
}

sub get_net_config
{
    my $interface = shift @_;

    open(IFCONFIG, "/sbin/ifconfig $interface |") or die "Failed to run /sbin/ifconfig $interface: $!";
    while (<IFCONFIG>) {
        next if (not m/inet addr:/);
        my $line = $_;
        chomp $line;
        $ifcfg{$interface}{'IPADDR'} = (split (' ', $line))[1];
        $ifcfg{$interface}{'IPADDR'} =~ s/addr://g;
        $ifcfg{$interface}{'BROADCAST'} = (split (' ', $line))[2];
        $ifcfg{$interface}{'BROADCAST'} =~ s/Bcast://g;
        $ifcfg{$interface}{'NETMASK'} = (split (' ', $line))[3];
        $ifcfg{$interface}{'NETMASK'} =~ s/Mask://g;
        if ($DISTRO =~ /RHEL6|RHEL7|POWERKVM|EULEROS2.0SP[235]/) {
            $ifcfg{$interface}{'NM_CONTROLLED'} = "yes";
            $ifcfg{$interface}{'TYPE'} = "InfiniBand";
        }
    }
    close(IFCONFIG);
}

sub is_carrier
{
    my $ifcheck = shift @_;
    open(IFSTATUS, "ip link show dev $ifcheck |");
    while ( <IFSTATUS> ) {
        next unless m@(\s$ifcheck).*@;
        if( m/NO-CARRIER/ or not m/UP/ ) {
            close(IFSTATUS);
            return 0;
        }
    }
    close(IFSTATUS);
    return 1;
}

sub config_interface
{
    my $interface = shift @_;
    my $ans;
    my $dev = "ib$interface";
    my $target = "$network_dir/ifcfg-$dev";
    my $ret;
    my $ip;
    my $nm;
    my $nw;
    my $bc;
    my $onboot = 1;
    my $found_eth_up = 0;

    if ($interactive) {
        print "\nDo you want to configure $dev? [Y/n]:";
        $ans = getch();
        if ($ans =~ m/[nN]/) {
            return;
        }
        if (-e $target) {
            print "\nThe current IPoIB configuration for $dev is:\n";
            open(IF,$target);
            while (<IF>) {
                print $_;
            }
            close(IF);
            print "\nDo you want to change this configuration? [y/N]:";
            $ans = getch();
            if ($ans !~ m/[yY]/) {
                return;
            }
        }
        print "\nEnter an IP Adress: ";
        $ip = <STDIN>;
        chomp $ip;
        $ret = is_valid_ipv4($ip);
        while ($ret) {
            print "\nEnter a valid IPv4 Adress: ";
            $ip = <STDIN>;
            chomp $ip;
            $ret = is_valid_ipv4($ip);
        }
        print "\nEnter the Netmask: ";
        $nm = <STDIN>;
        chomp $nm;
        $ret = is_valid_ipv4($nm);
        while ($ret) {
            print "\nEnter a valid Netmask: ";
            $nm = <STDIN>;
            chomp $nm;
            $ret = is_valid_ipv4($nm);
        }
        print "\nEnter the Network: ";
        $nw = <STDIN>;
        chomp $nw;
        $ret = is_valid_ipv4($nw);
        while ($ret) {
            print "\nEnter a valid Network: ";
            $nw = <STDIN>;
            chomp $nw;
            $ret = is_valid_ipv4($nw);
        }
        print "\nEnter the Broadcast Adress: ";
        $bc = <STDIN>;
        chomp $bc;
        $ret = is_valid_ipv4($bc);
        while ($ret) {
            print "\nEnter a valid Broadcast Adress: ";
            $bc = <STDIN>;
            chomp $bc;
            $ret = is_valid_ipv4($bc);
        }
        print "\nStart Device On Boot? [Y/n]:";
        $ans = getch();
        if ($ans =~ m/[nN]/) {
            $onboot = 0;
        }

        print GREEN "\nSelected configuration:\n";
        print "DEVICE=$dev\n";
        print "IPADDR=$ip\n";
        print "NETMASK=$nm\n";
        print "NETWORK=$nw\n";
        print "BROADCAST=$bc\n";
        if ($DISTRO =~ /RHEL6|RHEL7|POWERKVM|EULEROS2.0SP[235]/) {
            print "NM_CONTROLLED=yes\n";
            print "TYPE=InfiniBand\n";
        }
        if ($onboot) {
            print "ONBOOT=yes\n";
        }
        else {
            print "ONBOOT=no\n";
        }
        print "\nDo you want to save the selected configuration? [Y/n]:";
        $ans = getch();
        if ($ans =~ m/[nN]/) {
            return;
        }
    }
    else {
        if (not $config_net_given) {
            return;
        }
        print "Going to update $target\n" if ($verbose2);
        if ($ifcfg{$dev}{'LAN_INTERFACE'}) {
            $eth_dev = $ifcfg{$dev}{'LAN_INTERFACE'};
            if (not -e "/sys/class/net/$eth_dev") {
                print "Device $eth_dev is not present\n" if (not $quiet);
                return;
            }
            if ( is_carrier ($eth_dev) ) {
                $found_eth_up = 1;
            }
        }
        else {
            # Take the first existing Eth interface
            my @eth_devs = </sys/class/net/eth*>;
            for my $tmp_dev ( @eth_devs ) {
                $eth_dev = $tmp_dev;
                $eth_dev =~ s@/sys/class/net/@@g;
                if ( is_carrier ($eth_dev) ) {
                    $found_eth_up = 1;
                    last;
                }
            }
        }

        if ($found_eth_up) {
            get_net_config("$eth_dev");
        }

        if (not $ifcfg{$dev}{'IPADDR'}) {
            print "IP address is not defined for $dev\n" if ($verbose2);
            print "Skipping $dev configuration...\n" if ($verbose2);
            return;
        }
        if (not $ifcfg{$dev}{'NETMASK'}) {
            print "Netmask is not defined for $dev\n" if ($verbose2);
            print "Skipping $dev configuration...\n" if ($verbose2);
            return;
        }
        if (not $ifcfg{$dev}{'NETWORK'}) {
            print "Network is not defined for $dev\n" if ($verbose2);
            print "Skipping $dev configuration...\n" if ($verbose2);
            return;
        }
        if (not $ifcfg{$dev}{'BROADCAST'}) {
            print "Broadcast address is not defined for $dev\n" if ($verbose2);
            print "Skipping $dev configuration...\n" if ($verbose2);
            return;
        }

        my @ipib = (split('\.', $ifcfg{$dev}{'IPADDR'}));
        my @nmib = (split('\.', $ifcfg{$dev}{'NETMASK'}));
        my @nwib = (split('\.', $ifcfg{$dev}{'NETWORK'}));
        my @bcib = (split('\.', $ifcfg{$dev}{'BROADCAST'}));

        my @ipeth = (split('\.', $ifcfg{$eth_dev}{'IPADDR'}));
        my @nmeth = (split('\.', $ifcfg{$eth_dev}{'NETMASK'}));
        my @nweth = (split('\.', $ifcfg{$eth_dev}{'NETWORK'}));
        my @bceth = (split('\.', $ifcfg{$eth_dev}{'BROADCAST'}));

        for (my $i = 0; $i < 4 ; $i ++) {
            if ($ipib[$i] =~ m/\*/) {
                if ($ipeth[$i] =~ m/(\d\d?\d?)/) {
                    $ipib[$i] = $ipeth[$i];
                }
                else {
                    print "Cannot determine the IP address of the $dev interface\n" if (not $quiet);
                    return;
                }
            }
            if ($nmib[$i] =~ m/\*/) {
                if ($nmeth[$i] =~ m/(\d\d?\d?)/) {
                    $nmib[$i] = $nmeth[$i];
                }
                else {
                    print "Cannot determine the netmask of the $dev interface\n" if (not $quiet);
                    return;
                }
            }
            if ($bcib[$i] =~ m/\*/) {
                if ($bceth[$i] =~ m/(\d\d?\d?)/) {
                    $bcib[$i] = $bceth[$i];
                }
                else {
                    print "Cannot determine the broadcast address of the $dev interface\n" if (not $quiet);
                    return;
                }
            }
            if ($nwib[$i] !~ m/(\d\d?\d?)/) {
                $nwib[$i] = $nweth[$i];
            }
        }

        $ip = "$ipib[0].$ipib[1].$ipib[2].$ipib[3]";
        $nm = "$nmib[0].$nmib[1].$nmib[2].$nmib[3]";
        $nw = "$nwib[0].$nwib[1].$nwib[2].$nwib[3]";
        $bc = "$bcib[0].$bcib[1].$bcib[2].$bcib[3]";

        print GREEN "IPoIB configuration for $dev\n";
        print "DEVICE=$dev\n";
        print "IPADDR=$ip\n";
        print "NETMASK=$nm\n";
        print "NETWORK=$nw\n";
        print "BROADCAST=$bc\n";
        if ($onboot) {
            print "ONBOOT=yes\n";
        }
        else {
            print "ONBOOT=no\n";
        }
        print RESET "\n";
    }

    open(IF, ">$target") or die "Can't open $target: $!";
    if ($DISTRO =~ m/SLES|SUSE/) {
        print IF "BOOTPROTO='static'\n";
        print IF "IPADDR='$ip'\n";
        print IF "NETMASK='$nm'\n";
        print IF "NETWORK='$nw'\n";
        print IF "BROADCAST='$bc'\n";
        print IF "REMOTE_IPADDR=''\n";
        if ($onboot) {
            print IF "STARTMODE='onboot'\n";
        }
        else {
            print IF "STARTMODE='manual'\n";
        }
        print IF "WIRELESS=''\n";
    }
    else {
        print IF "DEVICE=$dev\n";
        print IF "BOOTPROTO=static\n";
        print IF "IPADDR=$ip\n";
        print IF "NETMASK=$nm\n";
        print IF "NETWORK=$nw\n";
        print IF "BROADCAST=$bc\n";
        if ($DISTRO =~ /RHEL6|RHEL7|POWERKVM|EULEROS2.0SP[235]/) {
            print IF "NM_CONTROLLED=yes\n";
            print IF "TYPE=InfiniBand\n";
        }
        if ($onboot) {
            print IF "ONBOOT=yes\n";
        }
        else {
            print IF "ONBOOT=no\n";
        }
    }
    close(IF);
}

sub ipoib_config
{
    if ($interactive) {
        print "\nThe default IPoIB interface configuration is based on DHCP.";
        print "\nNote that a special patch for DHCP is required for supporting IPoIB.";
        print "\nThe patch is available under docs/dhcp";
        print "\nIf you do not have DHCP, you must change this configuration in the following steps.\n";
    }

    my $ports_num = count_ports();
    for (my $i = 0; $i < $ports_num; $i++ ) {
        config_interface($i);
    }

    if ($interactive) {
        print GREEN "IPoIB interfaces configured successfully",RESET "\n";
        print "Press any key to continue ...";
        getch();
    }

    if (-e "/etc/sysconfig/network/config") {
        my $nm = `grep ^NETWORKMANAGER=yes /etc/sysconfig/network/config`;
        chomp $nm;
        if ($nm) {
            print RED "Please set NETWORKMANAGER=no in the /etc/sysconfig/network/config", RESET "\n";
        }
    }

}

sub uninstall_mlnx_en
{
    my $res = 0;
    my $sig = 0;
    my $cnt = 0;

    if ( -e "/sbin/mlnx_en_uninstall.sh" ) {
        print_and_log("Uninstalling MLNX_EN driver\n", (not $quiet));
        system("yes | /sbin/mlnx_en_uninstall.sh > $ofedlogs/mlnx_en_uninstall.log 2>&1");
        $res = $? >> 8;
        $sig = $? & 127;
        if ($sig or $res) {
            print_and_log_colored("Failed to uninstall MLNX_EN driver", 1, "RED");
            addSetupInfo ("$ofedlogs/mlnx_en_uninstall.log");
            print_and_log_colored("See $ofedlogs/mlnx_en_uninstall.log", 1, "RED");
            exit $ERROR;
        }
    }

    my $mlnx_en_cnt = 0;
    my $mlnx_en_rpms;
	# grep mlnx is required as a w/a on WR OS
    my @other_mlnx_en_rpms = `rpm -qa --queryformat "[%{NAME}]\n" 2> /dev/null | grep -E 'mlnx.en|mlx.*en' | grep -v '^kernel-module'`;
    for my $package (@mlnx_en_packages, @other_mlnx_en_rpms) {
        chomp $package;
        if (is_installed($package)) {
            $mlnx_en_rpms .= " $package";
            $mlnx_en_cnt ++;
        }
    }

    if ($mlnx_en_cnt) {
            my $cmd = "rpm -e --allmatches --nodeps";
            $cmd .= " $mlnx_en_rpms";
            print_and_log("Uninstalling MLNX_EN driver\n", (not $quiet));
            system("$cmd >> $ofedlogs/mlnx_en_uninstall.log 2>&1");
            $res = $? >> 8;
            $sig = $? & 127;
            if ($sig or $res) {
                print_and_log_colored("Failed to uninstall MLNX_EN driver", 1, "RED");
                addSetupInfo ("$ofedlogs/mlnx_en_uninstall.log");
                print_and_log("See $ofedlogs/mlnx_en_uninstall.log", 1, "RED");
                exit $ERROR;
            }
    }

}

sub uninstall_mft
{
    my $res = 0;
    my $sig = 0;
    my $cnt = 0;

    my $mft_rpms;
    for my $package (@mft_packages) {
        chomp $package;
        if (is_installed($package)) {
            $mft_rpms .= " $package";
            if (not $selected_for_uninstall{$package}) {
                push (@packages_to_uninstall, $package);
                $selected_for_uninstall{$package} = 1;
            }
        }
    }

    if (open (KMP_RPMS, 'rpm -qa --queryformat "[%{NAME}]\n" *kernel-mft* 2>/dev/null | grep kernel-mft |')) {
        my $kmp_cnt = 0;
        my $kmp_rpms;
        while(<KMP_RPMS>) {
            chomp $_;
            $kmp_rpms .= " $_";
            $kmp_cnt ++;
        }
        close KMP_RPMS;

	    if ($kmp_cnt) {
            system("rpm -e --allmatches --nodeps $kmp_rpms >> $ofedlogs/kmp_rpms_uninstall.log 2>&1");
            $res = $? >> 8;
            $sig = $? & 127;
            if ($sig or $res) {
                print_and_log("Failed to uninstall kernel-mft-mlnx KMP RPMs", 1, "RED");
                exit $ERROR;
            }
        }
    }
}

# Try to remove a package, if failed, retry with adding --noscripts flag
# Use it as W/A for known possible problematic packages
sub remove_od_noscripts
{
    my $pname = shift;

    my $cmd = "rpm -e --allmatches --nodeps $pname";
    print_and_log("\n$cmd\n", (not $quiet));
    open (LOG, "+>$ofedlogs/ofed_uninstall.log");
    print LOG "$cmd\n";
    close LOG;
    system("$cmd >> $ofedlogs/ofed_uninstall.log 2>&1");
    my $res = $? >> 8;
    my $sig = $? & 127;
    if ($sig or $res) {
        $cmd = "rpm -e --allmatches --nodeps --noscripts $pname";
        print_and_log("\n$cmd\n", (not $quiet));
        system("$cmd >> $ofedlogs/ofed_uninstall.log 2>&1");
        $res = $? >> 8;
        $sig = $? & 127;
        if ($sig or $res) {
            print_and_log_colored("Failed to uninstall $pname", 1, "RED");
            addSetupInfo ("$ofedlogs/ofed_uninstall.log");
            print_and_log_colored("See $ofedlogs/ofed_uninstall.log", 1, "RED");
            exit $ERROR;
        }
    }
}

sub force_uninstall
{
    my $res = 0;
    my $sig = 0;
    my $cnt = 0;
    my @other_ofed_rpms = `rpm -qa --queryformat "[%{NAME}]\n" 2> /dev/null | grep -wE "rdma|ofed|openib" | grep -vEw "glusterfs|kernel-module|^xen|ovsvf-config|opensmtpd"`;
    my $cmd = "rpm -e --allmatches --nodeps";

    for my $package (@all_packages, @hidden_packages, @prev_ofed_packages, @other_ofed_rpms, @distro_ofed_packages) {
        chomp $package;
        next if ($package eq "mpi-selector" or $package =~ /^kernel-module|glusterfs|^xen|ovsvf-config|opensmtpd/);
        if (is_installed($package)) {
            push (@packages_to_uninstall, $package);
            $selected_for_uninstall{$package} = 1;
        }
        if (is_installed("$package-static")) {
            push (@packages_to_uninstall, "$package-static");
            $selected_for_uninstall{$package} = 1;
        }
        if ($suffix_32bit and is_installed("$package$suffix_32bit")) {
            push (@packages_to_uninstall,"$package$suffix_32bit");
            $selected_for_uninstall{$package} = 1;
        }
        if ($suffix_64bit and is_installed("$package$suffix_64bit")) {
            push (@packages_to_uninstall,"$package$suffix_64bit");
            $selected_for_uninstall{$package} = 1;
        }
    }

    for my $package (@packages_to_uninstall) {
        get_requires($package);
    }

    if (not $force and keys %non_ofed_for_uninstall) {
        print_and_log("\nError: One or more packages depends on MLNX_OFED.\nThose packages should be removed before uninstalling MLNX_OFED:\n\n", 1);
        print_and_log(join(" ", (keys %non_ofed_for_uninstall)) . "\n\n", 1);
        print_and_log("To force uninstallation use '--force' flag.\n", 1);
        exit $NONOFEDRPMS;
    }

    for my $package (@packages_to_uninstall, @dependant_packages_to_uninstall) {
        if ("$package" eq "ofed" and is_installed("ofed")) {
            # W/A for SLES 10 SP4 in-box ofed RPM uninstall issue
            remove_od_noscripts("ofed");
            next;
        }
        if (is_installed("$package")) {
            $cmd .= " $package";
            $cnt ++;
        }
    }

    if ($cnt) {
        print_and_log("\n$cmd\n", (not $quiet));
        open (LOG, "+>$ofedlogs/ofed_uninstall.log");
        print LOG "$cmd\n";
        close LOG;
        system("$cmd >> $ofedlogs/ofed_uninstall.log 2>&1");
        $res = $? >> 8;
        $sig = $? & 127;
        if ($sig or $res) {
            print_and_log_colored("Failed to uninstall the previous installation", 1, "RED");
            addSetupInfo ("$ofedlogs/ofed_uninstall.log");
            print_and_log_colored("See $ofedlogs/ofed_uninstall.log", 1, "RED");
            exit $ERROR;
        }
    }
}

# if we install the drivers without KMP support, and then installed a new kernel
# it might still create weak-updates symlinks to our modules, and once we remove
# our rpms, no one will remove those links since our rpms do not know to run
# the systems tools that are responsible for removing the links.
# Note: if we have ofed kmp rpms installed, then we don't need to do anything here.
sub remove_weak_updates_symlinks
{
    my $ofed_kpkgs = "";
    my $got_kmps = 0;

    if ($DISTRO !~ /RHEL/) {
        return;
    }

    # get list of installed packages
    for my $package (qw(srp iser ofa_kernel knem ummunotify mlnx-sdp mlnx-rds mlnx-nfsrdma mlnx-nvme mlnx-rdma-rxe kernel-mft gpio-mlxbf i2c-mlx mlxbf-livefish mlx-bootctl pka-mlxbf tmfifo rshim mlx-trio mlx-l3cache mlx-pmc)) {
        my $regEx = "*$package*";
        if (open (OFED_KRPMS, "rpm -qa --queryformat \"[%{NAME}]\n\" $regEx | grep -E $regEx |")) {
            while(<OFED_KRPMS>) {
                chomp $_;
                if ($_ =~ /kmp|kmod/) {
                    $got_kmps = 1;
                    last;
                }
                $ofed_kpkgs .= " $_";
            }
            close OFED_KRPMS;
            if ($got_kmps) {
                last;
            }
        }
    }
    if ($got_kmps or $ofed_kpkgs eq "") {
        return;
    }

    # get list of KO files
    my $tmpfile = "/var/run/rpm_ofed_kernel_modules";
    system("rpm -ql $ofed_kpkgs | grep '\.ko\$' > $tmpfile");
    if (-z $tmpfile) {
        system("/bin/rm -f $tmpfile >/dev/null 2>&1");
        return;
    }

    # remove existing symlinks
    my $wm_tool = "/sbin/weak-modules";
    if (-e "$wm_tool") {
        system("cat $tmpfile | $wm_tool --remove-modules --no-initramfs --delete-modules >/dev/null 2>&1");
    }

    system("/bin/rm -f $tmpfile >/dev/null 2>&1");
}

sub uninstall
{
    my $res = 0;
    my $sig = 0;
    my $distro_rpms = '';

    return 0 if (not $uninstall);

    remove_weak_updates_symlinks();

    uninstall_mlnx_en();

    uninstall_mft();

    my $ofed_uninstall = `which ofed_uninstall.sh 2> /dev/null`;
    chomp $ofed_uninstall;
    if (-e "$ofed_uninstall") {
        print_and_log("Uninstalling the previous version of $PACKAGE\n", (not $quiet));
        if ($force) {
                system("yes | ofed_uninstall.sh --force >> $ofedlogs/ofed_uninstall.log 2>&1");
        } else {
                system("yes | ofed_uninstall.sh >> $ofedlogs/ofed_uninstall.log 2>&1");
        }
        $res = $? >> 8;
        $sig = $? & 127;
        if ($sig or $res) {
            if ($res == 174) {
                print_and_log("Error: One or more packages depends on MLNX_OFED.\nThese packages should be removed before uninstalling MLNX_OFED:\n", 1);
                system("cat $ofedlogs/ofed_uninstall.log | perl -ne '/Those packages should be/ && do {\$a=1; next}; /To force uninstallation use/ && do {\$a=0}; print if \$a'");
                print_and_log("To force uninstallation use '--force' flag.\n", 1);
                addSetupInfo ("$ofedlogs/ofed_uninstall.log");
                print_and_log_colored("See $ofedlogs/ofed_uninstall.log", 1, "RED");
                exit $NONOFEDRPMS;
            }
            print_and_log_colored("Failed to uninstall the previous installation", 1, "RED");
            addSetupInfo ("$ofedlogs/ofed_uninstall.log");
            print_and_log_colored("See $ofedlogs/ofed_uninstall.log", 1, "RED");
            exit $ERROR;
        }
    }

    # Uninstall leftovers and previous OFED packages
    force_uninstall();

    # uninstall KMP packages
    for my $package (qw(srp iser ofa_kernel knem ummunotify mlnx-sdp mlnx-rds mlnx-nfsrdma mlnx-nvme mlnx-rdma-rxe gpio-mlxbf i2c-mlx mlxbf-livefish mlx-bootctl pka-mlxbf tmfifo rshim mlx-trio mlx-l3cache mlx-pmc)) {
        my $regEx;
        if ($package !~ /$bf_krpm_regex|iser|srp$/) {
            $regEx = "*$package*";
        } else {
            $regEx = "\"kmod-$package*|$package-kmp*\"";
        }
        if (open (KMP_RPMS, "rpm -qa --queryformat \"[%{NAME}]\n\" $regEx 2>/dev/null | grep -E $regEx |")) {
            my $kmp_cnt = 0;
            my $kmp_rpms;
            while(<KMP_RPMS>) {
                chomp $_;
                next if ($_ eq "mlnx-ofa_kernel");
                $kmp_rpms .= " $_";
                $kmp_cnt ++;
            }
            close KMP_RPMS;

            if ($kmp_cnt) {
                if ($package eq "ofa_kernel") {
                    remove_od_noscripts("mlnx-ofa_kernel");
                }
                print_and_log("rpm -e --allmatches --nodeps $kmp_rpms\n", $verbose);
                system("rpm -e --allmatches --nodeps $kmp_rpms >> $ofedlogs/kmp_$package\_rpms_uninstall.log 2>&1");
                $res = $? >> 8;
                $sig = $? & 127;
                if ($sig or $res) {
                    print_and_log_colored("Failed to uninstall $package KMP RPMs", 1, "RED");
                    addSetupInfo ("$ofedlogs/kmp_$package\_rpms_uninstall.log");
                    print_and_log_colored("See $ofedlogs/kmp_$package\_rpms_uninstall.log", 1, "RED");
                    exit $ERROR;
                }
            }
        }
    }

    if ( -d "/lib/modules/$kernel/kernel/drivers/net/mtnic" ) {
        print_and_log("Uninstalling mtnic driver...\n", (not $quiet));
        system("/sbin/rmmod mtnic > /dev/null 2>&1");
        system("/bin/rm -rf /lib/modules/$kernel/kernel/drivers/net/mtnic");
        system("/sbin/depmod $kernel > /dev/null 2>&1");
    }

}

sub install
{
    # Build and install selected RPMs
    for my $package ( @selected_packages ) {
        if ($packages_info{$package}{'internal'}) {
            my $parent = $packages_info{$package}{'parent'};
            if (not is_srpm_available($parent)) {
                print_and_log_colored("$parent source RPM is not available", 1, "RED");
                next;
            }
        }
        my $pname = $packages_info{$package}{'parent'};
        for my $ver (keys %{$main_packages{$pname}}) {
            if ($packages_info{$package}{'mode'} eq "user") {
                if (not $packages_info{$package}{'exception'}) {
                    if ( (not $packages_info{$package}{$ver}{'rpm_exist'}) or
                         ($build32 and $packages_info{$package}{'install32'} and
                          not $packages_info{$package}{$ver}{'rpm_exist32'}) ) {
                        build_rpm($package, $ver);
                    }

                    if ( (not $packages_info{$package}{$ver}{'rpm_exist'}) or
                         ($build32 and $packages_info{$package}{'install32'} and
                          not $packages_info{$package}{$ver}{'rpm_exist32'}) ) {
                        print_and_log_colored("$package $ver was not created", 1, "RED");
                        exit $ERROR;
                    }
                    print_and_log("Install $package $ver RPM:\n", $verbose) if (not $build_only);
                    install_rpm($package, $ver) if (not $build_only);
                }
            }
            else {
                # kernel modules
                if ($package =~ m/kernel-mft-mlnx|ummunotify-mlnx/ and not $kmp) {
                    $package =~ s/-mlnx//;
                }
                if ($package eq "mlnx-en" and not $kmp) {
                    $package = "mlnx_en";
                }
                if (not $packages_info{$package}{$ver}{'rpm_exist'}) {
                    my $parent = $packages_info{$package}{'parent'};
                    print_and_log("Build $parent $ver RPM\n", $verbose);
                    build_kernel_rpm($parent, $ver);
                }
                if ($kmp and $package !~ /devel|debug/ and $package =~ m/ofa_kernel|knem|kernel-mft-mlnx|ummunotify-mlnx|mlnx-en$/) {
                    my @kmp_packages;
                    if ($DISTRO =~ /SLES|SUSE/) {
                        @kmp_packages = <$RPMS/$COMMON_DIR/$package-kmp*.$rpm_distro.$arch.rpm>;
                    } else {
                        @kmp_packages = <$RPMS/$COMMON_DIR/kmod*$package-*.$rpm_distro.$arch.rpm>;
                    }
                    if (not @kmp_packages) {
                        my $parent = $packages_info{$package}{'parent'};
                        print_and_log("Build $parent $ver RPM\n", $verbose);
                        build_kernel_rpm($parent, $ver);
                    }
                }
                if (not $packages_info{$package}{$ver}{'rpm_exist'}) {
                    next if ($package =~ /devel/);
                    print_and_log_colored("$package $ver was not created", 1, "RED");
                    exit $ERROR;
                }
                print_and_log("Install $package $ver RPM:\n", $verbose) if (not $build_only);
                install_kernel_rpm($package, $ver) if (not $build_only);
            }
        }
    }
    if ($speed_up_kmp) {
        if (-x "/sbin/weak-modules") {
            system("/sbin/depmod $kernel > /dev/null 2>&1");
            system("cat $modules_list | /sbin/weak-modules --add-modules");
            system("/bin/rm -f $modules_list");
        }
    }
}

sub is_srpm_available
{
    my $name = shift;

    for my $ver (keys %{$main_packages{$name}}) {
        if ($main_packages{$name}{$ver}{'srpmpath'}) {
            return 1;
        }
    }

    return 0;
}

sub addSetupInfo
{
    my $log = shift @_;

    print_and_log("Collecting debug info...\n", (not $quiet));

    if (not open (LOG, ">> $log")) {
        print_and_log("-E- Can't open $log for appending!\n", 1);
        return;
    }

    print LOG "\n\n\n---------------- START OF DEBUG INFO -------------------\n";
    print LOG "Install command: $CMD\n";

    print LOG "\nVars dump:\n";
    print LOG "- ofedlogs: $ofedlogs\n";
    print LOG "- DISTRO: $DISTRO\n";
    print LOG "- dist_rpm: $dist_rpm\n";
    print LOG "- rpm_distro: $rpm_distro\n";
    print LOG "- arch: $arch\n";
    print LOG "- kernel: $kernel\n";
    print LOG "- kmp: $kmp\n";
    print LOG "- config: $config\n";
    print LOG "- target_cpu: $target_cpu\n";
    print LOG "- update: $update\n";

    print LOG "\nSetup info:\n";
    print LOG "\n- uname -r: " . `uname -r 2>&1`;
    print LOG "\n- uname -m: " . `uname -m 2>&1`;
    print LOG "\n- rpm -qf /etc/issue: " . `rpm -qf /etc/issue 2>&1`;
    print LOG "\n- cat /etc/issue: " . `cat /etc/issue 2>&1`;
    print LOG "\n- rpm -qf /etc/os-release: " . `rpm -qf /etc/os-release 2>&1`;
    print LOG "\n- cat /etc/os-release: " . `cat /etc/os-release 2>&1`;
    print LOG "\n- cat /proc/version: " . `cat /proc/version 2>&1`;
    print LOG "\n- gcc --version: " . `gcc --version 2>&1`;
    print LOG "\n- lspci -n | grep 15b3: " . `lspci -n 2>&1 | grep 15b3`;
    print LOG "\n- rpm -qa: " . `rpm -qa 2>&1`;

    print LOG "---------------- END OF DEBUG INFO -------------------\n";
    close (LOG);
}

sub ex
{
    my $cmd = shift @_;

    system("$cmd");
    my $res = $? >> 8;
    my $sig = $? & 127;
    if ($sig or $res) {
        print_and_log_colored("Command execution failed: $cmd", 1, "RED");
        exit 1;
    }
}


### MAIN AREA ###
sub main
{
    if ($print_available) {
        my @list = ();

        for my $srcrpm ( <$SRPMS*> ) {
            set_cfg ($srcrpm);
        }
        set_availability();

        if (!$install_option) {
            $install_option = 'all';
        }

        $config = $conf_dir . "/ofed-$install_option.conf";
        chomp $config;
        if ($install_option eq 'all') {
            @list = (@all_packages, @hidden_packages);
        }
        elsif ($install_option eq 'bluefield') {
            $packages_info{"$knem_rpm"}{'available'} = 0;
            $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
            if ($kernel_only) {
                @list = (@bluefield_kernel_packages);
            } else {
                @list = (@bluefield_user_packages, @bluefield_kernel_packages);
            }
            @kernel_modules = (@bluefield_kernel_modules);
        }
        elsif ($install_option eq 'hpc') {
            @list = (@hpc_user_packages, @hpc_kernel_packages);
            @kernel_modules = (@hpc_kernel_modules);
        }
        elsif ($install_option eq 'hypervisor-os') {
            @list = (@hypervisor_user_packages, @hypervisor_kernel_packages);
            @kernel_modules = (@hypervisor_kernel_modules);
        }
        elsif ($install_option eq 'guest-os') {
            @list = (@guest_user_packages, @guest_kernel_packages);
            @kernel_modules = (@guest_kernel_modules);
        }
        elsif ($install_option =~ m/vma/) {
            if ($install_option eq 'vma') {
                @list = (@vma_user_packages, @vma_kernel_packages);
            } elsif ($install_option eq 'vmavpi') {
                @list = (@vmavpi_user_packages, @vma_kernel_packages);
            } elsif ($install_option eq 'vmaeth') {
                @list = (@vmaeth_user_packages, @vma_kernel_packages);
            }
            @kernel_modules = (@vma_kernel_modules);
        }
        elsif ($install_option eq 'basic') {
            @list = (@basic_user_packages, @basic_kernel_packages);
            @kernel_modules = (@basic_kernel_modules);
        }
        elsif ($install_option eq 'kernel-only') {
            for my $package ( @all_packages ) {
                next if (not $packages_info{$package}{'mode'} eq 'kernel');
                push (@list, $package);
            }
        }
        elsif ($install_option eq 'eth-only') {
            @list = (@eth_user_packages, @eth_kernel_packages);
            @kernel_modules = (@eth_kernel_modules);
        }
        elsif ($install_option =~ m/dpdk/) {
            @list = (@dpdk_user_packages, @dpdk_kernel_packages);
            @kernel_modules = (@dpdk_kernel_modules);
        }

        if ($with_bluefield and $install_option ne 'bluefield') {
            $packages_info{"$knem_rpm"}{'available'} = 0;
            $packages_info{"$knem_mods"}{'available'} = 0 if ($knem_mods ne "");
            for my $package ( @bluefield_user_packages, @bluefield_kernel_packages ) {
                next if (grep /^$package$/, @list);
                my $parent = $packages_info{$package}{'parent'};
                next if ($kernel_only and $packages_info{$package}{'mode'} ne 'kernel');
                push (@list, $package);
            }
            for my $module ( @bluefield_kernel_modules ) {
                next if (/^$module$/, @kernel_modules);
                push (@kernel_modules, $module);
            }
        }

        @selected_by_user = (@list);
        @selected_modules_by_user = (@kernel_modules);
        add_enabled_pkgs_by_user();
        resolve_dependencies();
        open(CONFIG, ">$config") || die "Can't open $config: $!";;
        flock CONFIG, $LOCK_EXCLUSIVE;
        print_and_log("\nOFED packages: ", 1);
        for my $package ( @selected_packages ) {
            my $parent = $packages_info{$package}{'parent'};
            next if (not $packages_info{$package}{'available'} or not is_srpm_available($parent));
            print_and_log("$package available: $packages_info{$package}{'available'}\n", $verbose2);
            if ($package =~ /ofa_kernel/ and $package !~ /devel/) {
                print_and_log("\nKernel modules: ", 1);
                for my $module ( @selected_kernel_modules ) {
                    next if (not $kernel_modules_info{$module}{'available'});
                    print_and_log($module . ' ', 1);
                    print CONFIG "$module=y\n";
                }
                print_and_log("\nRPMs: ", 1);
            }
            print_and_log($package . ' ', 1);
            print CONFIG "$package=y\n";
        }
        flock CONFIG, $UNLOCK;
        close(CONFIG);
        print_and_log("\n", 1);
        print_and_log_colored("Created $config", 1, "GREEN");
        exit $SUCCESS;
    }

    warn("Logs dir: $ofedlogs\n");
    warn("General log file: $glog\n");
    my $num_selected = 0;

    if ($interactive) {
        my $inp;
        my $ok = 0;
        my $max_inp;

        while (! $ok) {
            $max_inp = show_menu("main");
            $inp = getch();

            if ($inp =~ m/[qQ]/ || $inp =~ m/[Xx]/ ) {
                die "Exiting\n";
            }
            if (ord($inp) == $KEY_ENTER) {
                next;
            }
            if ($inp =~ m/[0123456789abcdefABCDEF]/)
            {
                $inp = hex($inp);
            }
            if ($inp < 1 || $inp > $max_inp)
            {
                print "Invalid choice...Try again\n";
                next;
            }
            $ok = 1;
        }

        if ($inp == 1) {
            if (-e "$CWD/docs/${PACKAGE}_Installation_Guide.txt") {
                system("less $CWD/docs/${PACKAGE}_Installation_Guide.txt");
            }
            elsif (-e "$CWD/README.txt") {
                system("less $CWD/README.txt");
            }
            else {
                print RED "$CWD/docs/${PACKAGE}_Installation_Guide.txt does not exist...", RESET;
            }

            return 0;
        }
        elsif ($inp == 2) {
            for my $srcrpm ( <$SRPMS*> ) {
                set_cfg ($srcrpm);
            }

            # Set RPMs info for available source RPMs
            set_availability();
            $num_selected = select_packages();
            set_existing_rpms();
            resolve_dependencies();
            check_linux_dependencies();
            if (not $quiet) {
                print_selected();
            }
        }
        elsif ($inp == 3) {
            my $cnt = 0;
            for my $package ( @all_packages, @hidden_packages) {
                if (is_installed($package)) {
                    print "$package\n";
                    $cnt ++;
                }
            }
            if (not $cnt) {
                print "\nThere is no $PACKAGE software installed\n";
            }
            print GREEN "\nPress any key to continue...", RESET;
            getch();
            return 0;
        }
        elsif ($inp == 4) {
            ipoib_config();
            return 0;
        }
        elsif ($inp == 5) {
            uninstall();
            exit 0;
        }

    }
    else {
        for my $srcrpm ( <$SRPMS*> ) {
            next if ($srcrpm =~ /KMP/);
            set_cfg ($srcrpm);
        }

        for my $srcrpm ( <$SRPMS/KMP/*> ) {
            set_cfg ($srcrpm);
        }

        # Set RPMs info for available source RPMs
        set_availability();
        $num_selected = select_packages();
        set_existing_rpms();
        resolve_dependencies();
        check_linux_dependencies();
        if (not $quiet) {
            print_selected();
        }
    }

    if (not $num_selected) {
        print_and_log_colored("$num_selected packages selected. Exiting...", 1, "RED");
        exit 1;
    }
    print_and_log("Detected Linux Distribution: $DISTRO\n", $verbose3);

    print_and_log("This program will install the $PACKAGE package on your machine.\n"
        . "Note that all other Mellanox, OEM, OFED, RDMA or Distribution IB packages will be removed.\n"
        . "Those packages are removed due to conflicts with $PACKAGE, do not reinstall them.\n\n", (not $quiet)) if (not $update);

    # Uninstall the previous installations
    uninstall();
    my $vendor_ret;
    if (length($vendor_pre_install) > 0) {
	    print_and_log("\nRunning vendor pre install script: $vendor_pre_install\n", (not $quiet));
	    $vendor_ret = system ( "$vendor_pre_install", "CONFIG=$config",
		"RPMS=$RPMS", "SRPMS=$SRPMS", "PREFIX=$prefix", "TOPDIR=$TOPDIR", "QUIET=$quiet" );
	    if ($vendor_ret != 0) {
		    print_and_log_colored("\nExecution of vendor pre install script failed.", (not $quiet), "RED");
		    exit 1;
	    }
    }
    install();

    system("/sbin/ldconfig > /dev/null 2>&1");

    if (-e "/etc/modprobe.conf.dist" and not $user_space_only) {
        open(MDIST, "/etc/modprobe.conf.dist") or die "Can't open /etc/modprobe.conf.dist: $!";
        my @mdist_lines;
        while (<MDIST>) {
            push @mdist_lines, $_;
        }
        close(MDIST);

        open(MDIST, ">/etc/modprobe.conf.dist") or die "Can't open /etc/modprobe.conf.dist: $!";
        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);
    }

    if (length($vendor_pre_uninstall) > 0) {
	    system "cp $vendor_pre_uninstall $prefix/sbin/vendor_pre_uninstall.sh";
    }
    if (length($vendor_post_uninstall) > 0) {
	    system "cp $vendor_post_uninstall $prefix/sbin/vendor_post_uninstall.sh";
    }
    if (length($vendor_post_install) > 0) {
	    print_and_log("\nRunning vendor post install script: $vendor_post_install\n", (not $quiet));
	    $vendor_ret = system ( "$vendor_post_install", "CONFIG=$config",
		"RPMS=$RPMS", "SRPMS=$SRPMS", "PREFIX=$prefix", "TOPDIR=$TOPDIR", "QUIET=$quiet");
	    if ($vendor_ret != 0) {
		    print_and_log_colored("\nExecution of vendor post install script failed.", (not $quiet), "RED");
		    exit 1;
	    }
    }

    if ($kernel_modules_info{'ipoib'}{'selected'} and not $user_space_only) {
        ipoib_config();

        # Decrease send/receive queue sizes on 32-bit arcitecture
        # BUG: https://bugs.openfabrics.org/show_bug.cgi?id=1420
        if ($arch =~ /i[3-6]86/) {
            if (-e "/etc/modprobe.d/ib_ipoib.conf") {
                open(MODPROBE_CONF, ">>/etc/modprobe.d/ib_ipoib.conf");
                print MODPROBE_CONF "options ib_ipoib send_queue_size=64 recv_queue_size=128\n";
                close MODPROBE_CONF;
            }
        }

        # BUG: https://bugs.openfabrics.org/show_bug.cgi?id=1449
        if (-e "/etc/modprobe.d/ipv6") {
            open(IPV6, "/etc/modprobe.d/ipv6") or die "Can't open /etc/modprobe.d/ipv6: $!";
            my @ipv6_lines;
            while (<IPV6>) {
                push @ipv6_lines, $_;
            }
            close(IPV6);

            open(IPV6, ">/etc/modprobe.d/ipv6") or die "Can't open /etc/modprobe.d/ipv6: $!";
            foreach my $line (@ipv6_lines) {
                chomp $line;
                if ($line =~ /^\s*install ipv6/) {
                    print IPV6 "# $line\n";
                } else {
                    print IPV6 "$line\n";
                }
            }
            close(IPV6);
        }
    }

    if ( not $quiet ) {
        check_pcie_link();
    }

    if ($umad_dev_rw or $umad_dev_na) {
        if (-e $ib_udev_rules) {
            open(IB_UDEV_RULES, $ib_udev_rules) or die "Can't open $ib_udev_rules: $!";
            my @ib_udev_rules_lines;
            while (<IB_UDEV_RULES>) {
                push @ib_udev_rules_lines, $_;
            }
            close(IB_UDEV_RULES);

            open(IB_UDEV_RULES, ">$ib_udev_rules") or die "Can't open $ib_udev_rules: $!";
            foreach my $line (@ib_udev_rules_lines) {
                chomp $line;
                if ($line =~ /umad/) {
                    if ($umad_dev_na) {
                        print IB_UDEV_RULES "KERNEL==\"umad*\", NAME=\"infiniband/%k\", MODE=\"0660\"\n";
                    } else {
                        print IB_UDEV_RULES "KERNEL==\"umad*\", NAME=\"infiniband/%k\", MODE=\"0666\"\n";
                    }
                } else {
                    print IB_UDEV_RULES "$line\n";
                }
            }
            close(IB_UDEV_RULES);
        }
    }

    my @openmpi_mca_params;
    # Openmpi post-install action
    if (-d "$prefix/mpi") {
        @openmpi_mca_params = `find $prefix/mpi -name openmpi-mca-params.conf 2> /dev/null`;
        for my $openmpi_conf (@openmpi_mca_params) {
            chomp $openmpi_conf;
            system("echo coll_fca_enable = 0 >> $openmpi_conf 2>&1");
            system("echo coll = ^ml >> $openmpi_conf");
        }
    }

    # Openshmem post-install action
    if (-d $openshmem_prefix) {
        @openmpi_mca_params = `find $openshmem_prefix -name openmpi-mca-params.conf 2> /dev/null`;
        for my $openmpi_conf (@openmpi_mca_params) {
            chomp $openmpi_conf;
            system("echo coll_fca_enable = 0 >> $openmpi_conf 2>&1");
            system("echo scoll_fca_enable = 0 >> $openmpi_conf 2>&1");
        }
    }

    if (-e "/etc/infiniband/openib.conf") {
        my @lines;
        open(FD, "/etc/infiniband/openib.conf");
        while (<FD>) {
            push @lines, $_;
        }
        close (FD);
        open(FD, ">/etc/infiniband/openib.conf");
        foreach my $line (@lines) {
            chomp $line;
            if ($line =~ m/(^SDP_LOAD=|^QIB_LOAD=).*/) {
                    print FD "${1}no\n";
            } elsif ($line =~ m/(^SET_IPOIB_CM=).*/ and $with_vma) {
                # Set IPoIB Datagram mode in case of VMA installation
                print FD "SET_IPOIB_CM=no\n";
            } else {
                    print FD "$line\n";
            }
        }
        close (FD);
    }

    if ($DISTRO =~ m/OL/ and $kernel =~ m/2.6.32-279.19.1.el6/) {
        my @lines;
        open(FD, "/etc/infiniband/openib.conf");
        while (<FD>) {
            push @lines, $_;
        }
        close (FD);

        open(FD, ">/etc/infiniband/openib.conf");
        foreach my $line (@lines) {
            chomp $line;
            if ($line =~ m/(^RUN_SYSCTL=).*/) {
                    print FD "${1}no\n";
            } else {
                    print FD "$line\n";
            }
        }
        close (FD);
    }

    # Enable/disable mlnx_tune
    if ( -e "/etc/infiniband/openib.conf") {
        my @lines;
        open(FD, "/etc/infiniband/openib.conf");
        while (<FD>) {
            push @lines, $_;
        }
        close (FD);

        open(FD, ">/etc/infiniband/openib.conf");
        foreach my $line (@lines) {
            chomp $line;
            if ($line =~ m/(^RUN_MLNX_TUNE=).*/) {
                if ($enable_mlnx_tune) {
                    print FD "${1}yes\n";
                } else {
                    print FD "${1}no\n";
                }
            } else {
                    print FD "$line\n";
            }
        }
        close (FD);
    }

    my $mlnx_conf = "/etc/modprobe.d/mlnx.conf";
    if ($with_vma and -e "$mlnx_conf" and not $user_space_only) {
        my @lines;
        open(FD, "$mlnx_conf");
        while (<FD>) {
            push @lines, $_;
        }
        close (FD);
        open(FD, ">$mlnx_conf");
        foreach my $line (@lines) {
            chomp $line;
            print FD "$line\n" unless ($line =~ /disable_raw_qp_enforcement|fast_drop|log_num_mgm_entry_size/);
        }
        print FD "options ib_uverbs disable_raw_qp_enforcement=1\n";
        print FD "options mlx4_core fast_drop=1\n";
        print FD "options mlx4_core log_num_mgm_entry_size=-1\n";
        close (FD);
    }

    if ($enable_opensm) {
        # Switch on opensmd service
        if (-e "/sbin/chkconfig") {
            system("/sbin/chkconfig --add opensmd > /dev/null 2>&1");
            system("/sbin/chkconfig --set opensmd on > /dev/null 2>&1");
            system("/sbin/chkconfig --level 345 opensmd on > /dev/null 2>&1");
        } elsif (-e "/usr/sbin/update-rc.d") {
            system("/usr/sbin/update-rc.d opensmd defaults > /dev/null 2>&1");
        } else {
            system("/usr/lib/lsb/install_initd /etc/init.d/opensmd > /dev/null 2>&1");
        }
    } else {
        # Switch off opensmd service
        if (-e "/sbin/chkconfig") {
            system("/sbin/chkconfig --del opensmd > /dev/null 2>&1");
            system("/sbin/chkconfig --set opensmd off > /dev/null 2>&1");
            system("/sbin/chkconfig opensmd off > /dev/null 2>&1");
        } elsif (-e "/usr/sbin/update-rc.d") {
            system("/usr/sbin/update-rc.d -f opensmd remove > /dev/null 2>&1");
        } else {
            system("/usr/lib/lsb/remove_initd /etc/init.d/opensmd > /dev/null 2>&1");
        }
    }

    if (is_installed("ibacm")) {
        # Disable ibacm daemon by default
        system("chkconfig --del ibacm > /dev/null 2>&1");
    }

    print_and_log_colored("\nInstallation finished successfully.", 1, "GREEN") if (not $build_only);
    if ($interactive) {
        print GREEN "\nPress any key to continue...", RESET;
        getch();
    }
    else {
        print "\n";
    }
}

while (1) {
    main();
    exit 0 if (not $interactive);
}
