#!/usr/bin/perl
#
# Name: set_parm
# Copyright: (c)Copyright 2008, 2009 Hewlett-Packard Development Company, L.P.
#
# Description: Sets driver parameters for lpfc and qla2xxx modules
#
# Modification History
# Shreya R C    02/24/12 Made chages in BrocadeSetParameters function as BCU has changed the way it displays its output 
# Chad Dupuis	01/16/08 Initial development
# Chad Dupuis	03/05/08 Add switch for MultiPath settings
# Chad Dupuis	03/25/08 Add -i flag to rebuild initrd
# Chad Dupuis	12/16/08 Add -s flag to force single path settings
# Marzieh Namazi12/17/08 Add --emulex_default and --qlogic_default 
# Chad Dupuis	09/22/09 Changed Emulex nodev timeout value to 14
# Cheryl DeLeo	10/27/09 Fixed newline appearing when modprobe.conf is manually edited causing modules to not load correctly.
# Chad Dupuis	12/16/09 Fixed typo in QlogicSetDefaultParameters function calls
# Keith Wortman 11/05/10 Added RHEL 6
# Satya Rao, KW 01/07/11 Fix, add a newline to modprobe.conf entries as needed 
# Keith Wortman	04/15/11 Added support for Brocade  
#
#
# Defines
#

if ((-e "/etc/modprobe.conf.local")) {
	$modconf = "/etc/modprobe.conf.local";
}
else {
	$modconf = "/etc/modprobe.conf";
}

if ((-e "/etc/modprobe.d/fc-hba.conf")) {
        $modconf = "/etc/modprobe.d/fc-hba.conf";
}


$TRUE = 1;
$FALSE = 0;
$GOOD = 0;
$FAIL = 1;
$qlogic_line = "options qla2xxx";
$emulex_line = "options lpfc";
$dolog = $FALSE;
$logger = "/opt/hp/hp-fc-enablement/logger.pl";
$set_multipath = $FALSE;
$set_singlepath = $FALSE;
$set_qlogic_default = $FALSE;
$set_emulex_default = $FALSE;
$remake_initrd = $FALSE;
$make_initrd = "/opt/hp/hp-fc-enablement/make_initrd";

# If the environmental variable HPFCHBAKITDEBUG is "y" then
# print debug statements

if ($ENV{HPFCHBAKITDEBUG} eq "y") {
	$debug = $TRUE;
}
else {
	$debug = $FALSE;
}

## KW debug
## $debug = $TRUE;


# Default parameters

%qlogic_param = ("ql2xmaxqdepth" => "16", "qlport_down_retry" => "64", "ql2xloginretrycount" => "30");
%emulex_param = ("lpfc_lun_queue_depth" => "16", "lpfc_nodev_tmo" => "30", "lpfc_discovery_threads" => "32");

#
# Functions
#

# Name: Debug
# Description: Prints a debug statement
# In: function - Name of the function that this statement is generated from
#     message - Message to print
# Out: None
# Returns: None
sub Debug {
	my $function = $_[0];
	my $message = $_[1];

	if ($debug) {	
		print $function."(): ".$message."\n";
	}
}

# Name: Log
# Description: Write a message out to the log file
# In: message - Message to print to logfile
# Out: None
# Returns: None
sub Log {
	my $message = $_[0];
	
	if ($dolog) {
		my $commandtorun = "$logger -m \"$message\"";
		Debug ("Log", "Command to run in \"$commandtorun\"");
		system ($commandtorun);
	} 
} 

# Name: PrintHelp
# Description: Prints the help message
# In: None
# Out: None
# Returns: None
sub PrintHelp {
	print "NAME\n\n";
	print "set_parm\n\n";
	print "DESCRIPTION\n\n";
	print "Utility to set Fibre Channel HBA driver parameters\n\n";
	print "OPTIONS\n\n";
	print "-l, --log                  - Log events during installation\n";
	print "-m, --multipath            - Set driver parameters for multipathing\n";
	print "-i, --initrd               - Remake the initrd\n";
	print "-s, --singlepath           - Set driver parameters for single path\n";
        print "--qlogic_default           - Set default Qlogic parameter\n";
	print "--qlogic_qdepth            - Sets the LUN queue depth of the qla2xxx driver\n";
	print "--qlogic_port_down_retry   - Sets the port down retry of the qla2xxx driver\n";
	print "--qlogic_login_retry       - Sets the login retry count of the qla2xxx driver\n";
        print "--emulex_default           - Set default Emulex parameters\n";
	print "--emulex_qdepth            - Sets the LUN queue depth of the lpfc driver\n";
	print "--emulex_nodev             - Sets the nodev timeout value of the lpfc driver\n";
	print "--emulex_discovery_threads - Sets the discovery threads in the lpfc driver\n";
	print "\nEx: set_parm --qlogic_qdepth=16\n";
	exit ($GOOD);
}

# Name: QlogicSetQueueDepth
# Description: Sets the queue depth parameter for QLogic adapters
# In: queue_depth - Queue depth number
# Out: qlogic_param{ql2xmaxqdepth} = queue_depth
# Returns: None
sub QlogicSetQueueDepth {
	my $queue_depth = $_[0];
	Debug ("QlogicSetQueueDepth", "Setting ql2xmaxqdepth to $queue_depth");
	$qlogic_param{"ql2xmaxqdepth"} = $queue_depth;
}

# Name: QlogicSetPortDownRetry
# Description: Sets the port down retry count parameter for QLogic adapters
# In: port_down_retry - Port down retry count number
# Out: qlogic_param{qlport_down_retry} = port_down_retry
# Returns: None
sub QlogicSetPortDownRetry {
	my $port_down_retry = $_[0];
	Debug ("QlogicSetPortDownRetry", "Setting qlport_down_retry to $port_down_retry");
	$qlogic_param{"qlport_down_retry"} = $port_down_retry;
}

# Name: QlogicSetLoginRetry
# Description: Sets the login retry count parameter for QLogic adapters
# In: login_retry - Login retry count number
# Out: qlogic_param{ql2xloginretrycount} = login_retry
# Returns: None
sub QlogicSetLoginRetry {
	my $login_retry = $_[0];
	Debug ("QlogicSetLoginRetry", "Setting ql2xloginretrycount to $login_retry");
	$qlogic_param{"ql2xloginretrycount"} = $login_retry;
}

# Name: EmulexSetQueueDepth
# Description: Sets the queue depth parameter for Emulex adapters
# In: queue_depth - Queue depth number
# Out: emulex_param{lpfc_lun_queue_depth} = queue_depth
# Returns: None
sub EmulexSetQueueDepth {
	my $queue_depth = $_[0];
	Debug ("EmulexSetQueueDepth", "Setting lpfc_lun_queue_depth to $queue_depth");
	$emulex_param{"lpfc_lun_queue_depth"} = $queue_depth;
}

# Name: EmulexSetNodevTimeout
# Description: Sets the nodev timeout parameter for Emulex adapters
# In: nodev_tmo - Nodev timeout number
# Out: emulex_param{lpfc_nodev_tmo} = nodev_depth
# Returns: None
sub EmulexSetNodevTimeout {
	my $nodev_tmo = $_[0];
	Debug ("EmulexSetNodevTimeout", "Setting lpfc_nodev_tmo to $nodev_tmo");
	$emulex_param{"lpfc_nodev_tmo"} = $nodev_tmo;
}

# Name: EmulexSetDiscoveryThreads
# Description: Sets the discovery threads paramter for Emulex adapters
# In: discovery_threads - Discovery threads number
# Out: emulex_param{lpfc_discovery_threads} = discovery_threads
# Returns: None
sub EmulexSetDiscoveryThreads {
	my $discovery_threads = $_[0];
	Debug ("EmulexSetDiscoveryThreads", "Setting lpfc_discovery_threads to $discover_threads");
	$emulex_param{"lpfc_discovery_threads"} = $discovery_threads;
}

# Name: QlogicSinglepathTransform
# Description: Transforms the base QLogic settings for Singlepath configs
# In: None
# Out: None
# Returns: None
sub QlogicSinglepathTransform {
	Debug ("QlogicSinglepathTransform", "Setting port down retry count to 10");
	QlogicSetPortDownRetry(64);
}

# Name: EmulexSinglepathTransform
# Description: Transforms the base Emulex settings for Singlepath configs
# In: None
# Out: None
# Returns: None
sub EmulexSinglepathTransform {
	Debug ("EmulexSinglepathTransform", "Setting nodev timeout to 28");
	EmulexSetNodevTimeout(30);
}

# Name: BrocadeSinglepathTransform
# Description: Transforms the base Brocade settings for Singlepath configs
# In: None
# Out: None
# Returns: None
sub BrocadeSinglepathTransform { 
        Debug ("BrocadeSinglepathTransform", "Setting pathtov=30");
 	BrocadeSetParameters(30); 
}

# Name: QlogicMultipathTransform
# Description: Transforms the base QLogic settings for Multipath configs
# In: None
# Out: None
# Returns: None
sub QlogicMultipathTransform {
	Debug ("QlogicMultipathTransform", "Setting port down retry count to 10");
	QlogicSetPortDownRetry(10);
}

# Name: EmulexMultipathTransform
# Description: Transforms the base Emulex settings for Multipath configs
# In: None
# Out: None
# Returns: None
sub EmulexMultipathTransform {
	Debug ("EmulexMultipathTransform", "Setting nodev timeout to 14");
	EmulexSetNodevTimeout(14);
}
 
# Name: BrocadeMultipathTransform
# Description: Transforms the base settings for Multipath configs
# In: None
# Out: None
# Returns: None
sub BrocadeMultipathTransform {
        Debug ("BrocadeMultipathTransform", "Setting pathtov=14");
        BrocadeSetParameters(14);
}

# Name:  QLogicSetDefaultParameters
# Description:  Will reset the QLogic parameters back to default
# In: None
# Out: qlogic_param{ql2xmaxqdepth} = 16 ;  
#      qlogic_param{qlport_down_retry} = 64 ; 
#      qlogic_param{ql2xloginretrycount} = 30
# Returns: None
sub QlogicSetDefaultParameters {
        my $queue_depth = 16;
        my $port_down_retry = 64;
        my $login_retry = 30;

	Debug ("QlogicSetDefaultParameters", "Setting default parameters for qla2xxx module");
        QlogicSetQueueDepth($queue_depth);        
	QlogicSetPortDownRetry($port_down_retry);
	QlogicSetLoginRetry($login_retry);
}

# Name: EmulexSetDefaultParameters
# Description:  Will reset the Emulex parameters back to default
# In: None
# Out: emulex_param{lpfc_lun_queue_depth} = 16 ;
#      emulex_param{lpfc_nodev_tmo} = 30 ; 
#      emulex_param{lpfc_discovery_threads} = 32
# Returns: None
sub EmulexSetDefaultParameters {
        my $queue_depth = 16;
        my $nodev_tmo = 30;
        my $discovery_threads = 32;
	
	Debug ("EmulexSetDefaultParameters", "Setting default parameters for lpfc module");
	EmulexSetQueueDepth ($queue_depth);
	EmulexSetNodevTimeout($nodev_tmo);
	EmulexSetDiscoveryThreads($discovery_threads);
}

# Name: GetParameterValue
# Description: Takes a parameter string and extracts the value
# In: parameterstr - Parameter string in the form name=value
# Out: None
# Returns: ParameterValue
sub GetParameterValue {
	my $parameterstr = $_[0];
	
	Debug ("GetParameterValue", "parameterstr is $parameterstr");
	my @tmparray = split (/=/, $parameterstr);
	
	Debug ("GetParameterValue", "Returning $tmparray[1]");
	return $tmparray[1];
}

# Name: ParseArgs
# Description: Parse all command line arguments and set the
#              appropriate flags 
# In: @paramters - command line arguments
# Out: None
# Returns: None
sub ParseArgs {
	@parameters = @_;
	my $size = @parameters;
	my $i = 0;

	Debug ("ParseArgs", "Number of parameters is $size");
	
	for ($i = 0; $i < $size; $i = $i + 1)  
	{
		my $arg = $parameters[$i];
		Debug ("ParseArgs", "Current paramter is $arg");
		
		if (($arg eq "-h") || ($arg eq "--help")) {
			PrintHelp();
		}
		elsif (($arg eq "-d") || ($arg eq "--debug")) {
			$debug = 1;
		}
		elsif (($arg eq "-i") || ($arg eq "--initrd")) {
			$remake_initrd = $TRUE;
		}
		elsif (($arg eq "-l") || ($arg eq "--log")) {
			$dolog = $TRUE;
		}
		elsif (($arg eq "-m") || ($arg eq "--multipath")) {
			$set_multipath = $TRUE;
			$set_singlepath = $FALSE;
		}
		elsif (($arg eq "-s") || ($arg eq "--singlepath")) {
			$set_multipath = $FALSE;
			$set_singlepath = $TRUE;
		}
		elsif ($arg =~ "--qlogic_qdepth") {
			QlogicSetQueueDepth(GetParameterValue($arg));
		}
		elsif ($arg =~ "--qlogic_port_down_retry") {
			QlogicSetPortDownRetry(GetParameterValue($arg));
		}
		elsif ($arg =~ "--qlogic_login_retry") {
			QlogicSetLoginRetry(GetParameterValue($arg));
		}
		elsif ($arg =~ "--emulex_qdepth") {
			EmulexSetQueueDepth(GetParameterValue($arg));
		}
		elsif ($arg =~ "--emulex_nodev") {
			EmulexSetNodevTimeout(GetParameterValue($arg));
		}
		elsif ($arg =~ "--emulex_discovery_threads") {
			EmulexSetDiscoveryThreads(GetParameterValue($arg));
		}
		elsif ($arg =~ "--qlogic_default") {
			$set_qlogic_default = $TRUE;			
		}
		elsif ($arg =~ "--emulex_default") {
			$set_emulex_default = $TRUE;
		}
		else {
			print "$arg is an invalid flag\n";
			exit ($FAIL);
		}
	}
	
	# Argument post processing

	if (($set_singlepath == $TRUE) && ($set_multipath == $TRUE)) {
		print "Cannot specify both single path and multipath settings at the same time\n";
		exit ($FAIL);
	}

	if (($set_qlogic_default == $TRUE) && ($set_singlepath == $TRUE || $set_multipath == $TRUE)) {
		print "Cannot set values back to default and specify single or multipath settings\n";
		exit ($FAIL);
	}

	if (($set_emulex_default == $TRUE) && ($set_singlepath == $TRUE || $set_multipath == $TRUE)) {
		print "Cannot set values back to default and specify single or multipath settings\n";
		exit ($FAIL);
	}
}

# Name: QlogicHasOptionLine
# Description: Returns whether modprobe.conf contains an option line for qla2xxx
# In: None
# Out: None
# Returns: TRUE if the line exists, FALSE otherwise
sub QlogicHasOptionLine {
	# Open file and Slurp in contents
	
	Debug ("QlogicHasOptionLine", "modconf is $modconf");
	open (MODCONF, $modconf) or die "Could not open $modconf\n";
	my @contents = <MODCONF>;
	close (MODCONF);
	
	# Grep to see if the options qla2xxx line exists
	
	my @grep_results = grep (/$qlogic_line/, @contents); 
	my $num_of_results = @grep_results;
	Debug ("QlogicHasOptionLine", "num_of_results is $num_of_results");
	
	if ($num_of_results > 0) {
		Debug ("QlogicHasOptionLine", "Returning TRUE");
		return ($TRUE);
	}
	else {
		Debug ("QlogicHasOptionLine", "Returning FALSE");
		return ($FALSE);
	}
}

# Name: EmulexHasOptionLine
# Description: Returns whether modprobe.conf contains an option line for lpfc
# In: None
# Out: None
# Returns: TRUE if the line exists, FALSE otherwise
sub EmulexHasOptionLine {
	# Open file and slurp in contents
	
	Debug ("EmulexHasOptionLine", "modconf is $modconf");
	open (MODCONF, $modconf) or die "Could not open $modconf\n";
	my @contents = <MODCONF>;
	close (MODCONF);
	
	# Grep to see if the options qla2xxx line exists
	
	my @grep_results = grep (/$emulex_line/, @contents); 
	my $num_of_results = @grep_results;
	Debug ("EmulexHasOptionLine", "num_of_results is $num_of_results");

	
	if ($num_of_results > 0) {
		Debug ("EmulexHasOptionLine", "Returning TRUE");
		return ($TRUE);
	}
	else {
		Debug ("EmulexHasOptionLine", "Returning FALSE");
		return ($FALSE);
	}
}

# Name: Move
# Description: Moves a file from one place to another
# In: f1 - source file
#     f2 - destination file
# Out: None
# Returns: None
sub Move {
        my $source = $_[0];
        my $dest = $_[1];

        # Execute copy command
        Debug ("Move", "Command to execute is \"mv -f $source $dest\"");
        system ("mv -f $source $dest");
}

# Name: QlogicCreateDriverParameterStr
# Descriptions: Creates the driver parameter string for modprobe.conf
# In:  newline - Whether to add a newline at the end of the string
# Out: None
# Returns: Driver parameter string for modprobe.conf
sub QlogicCreateDriverParameterStr {
	my $newline = $_[0];
	my $tmpstr = "$qlogic_line";

	foreach $parameter (keys %qlogic_param) {
		Debug ("QlogicCreateDriverParameterStr", "parameter is $parameter");
		$tmpstr = $tmpstr." $parameter=$qlogic_param{$parameter}";
		chomp $tmpstr;
		Debug ("QlogicCreateDriverParameterStr", "string is $tmpstr");
	}

	if ($newline) {
		$tmpstr = $tmpstr."\n";
	}
	
	Debug ("QloigcCreateDriverParameterStr", "Returning $tmpstr");
	return ($tmpstr);
}

# Name: EmulexCreateDriverParameterStr
# Descriptions: Creates the driver parameter string for modprobe.conf
# In:  newline - Whether to add a newline at the end of the string
# Out: None
# Returns: Driver parameter string for modprobe.conf
sub EmulexCreateDriverParameterStr {
	my $newline = $_[0];
	my $tmpstr = "$emulex_line";

	foreach $parameter (keys %emulex_param) {
		$tmpstr = $tmpstr." $parameter=$emulex_param{$parameter}";
		chomp $tmpstr;
	}

	if ($newline) {
		$tmpstr = $tmpstr."\n";
	}
	
	Debug ("EmulexCreateDriverParameterStr", "Returning $tmpstr");
	return ($tmpstr);
}

# Name: WriteNewParameters
# Description: Writes a new options qla2xxx to MODCONF
# In: None
# Out: None
# Returns: None
sub WriteNewParameters {
	my $tmpstr = "";

	# Open the files
	
	Debug ("WriteNewParamters", "modconf is $modconf and modconf.new is $modconf.new");
	open (SRC, $modconf) or die "Could not open $modconf\n";
	open (DEST, ">$modconf.new") or die "Could not open $modconf.new\n";
	
	while (<SRC>) {
		# If we encounter the options qla2xxx or options lpfc line,
		# write out the new QLogic and/or Emulex parameter lines,
		# else just write out the existing line to the new file
		
		if ($_ =~ /$qlogic_line/) {
			
			Debug ("WriteNewParameters", "options qla2xxx already exists");
			Debug ("WriteNewParameters: modprobe line ", "$_");

			# delete any newlines
			chomp $_;

			$tmpstr = QlogicCreateDriverParameterStr($FALSE);

			# Check for the strange case where $tmpstr does not have a newline

			Debug ("WriteNewParameters:  tmpstr after create", "$tmpstr");
			if (!($tmpstr =~ m/\n/)) {
				Debug ("WriteNewParameters", "adding a newline");
				$tmpstr = $tmpstr."\n";
			}

			Debug ("WriteNewParameters", "Writing ".$tmpstr." to $modconf.new");
			print DEST $tmpstr;
			
			# Need to chomp parameter string to print it to the screen

			chomp ($tmpstr);	
			Log ("set_parm: Adding $tmpstr to $modconf");
			print "Adding $tmpstr to $modconf\n";
		}
		elsif ($_ =~ /$emulex_line/) {
			Debug ("WriteNewParameters", "options lpfc already exists");
			Debug ("WriteNewParameters: modprobe line ", "$_");
			#Debug ("WriteNewParameters", "Writing ".EmulexCreateDriverParameterStr($FALSE)." to $modconf.new");
			
			# delete any newlines
			chomp $_;

			# Check for the strange case where $tmpstr does not have a newline
			$tmpstr = EmulexCreateDriverParameterStr($FALSE);
                        if (!($tmpstr =~ m/\n/)) {
				Debug ("WriteNewParameters", "adding a newline");
				$tmpstr = $tmpstr."\n";
			}

			Debug ("WriteNewParameters", "Writing ".$tmpstr." to $modconf.new");
			print DEST ($tmpstr);
			# Need to chomp parameter string to print it to the screen
			chomp ($tmpstr);
			Log ("set_parm: Adding $tmpstr to $modconf");
			print "Adding $tmpstr to $modconf\n";
		}
		else {
			Debug ("WriteNewParameters", "Writing $_ to $modconf.new");
			print DEST "$_";
		}
	}
	
	# If either the options qla2xxx or options lpfc do not exist in the
	# current modprobe.conf file, append them to the new file

	if (!(QlogicHasOptionLine())) {
		
		Debug ("WriteNewParameters", "options qla2xxx is not in $modconf.new");
		Debug ("WriteNewParameters", "Adding line ".QlogicCreateDriverParameterStr($TRUE)." to $modconf.new");
		print DEST QlogicCreateDriverParameterStr($TRUE);

		# Need to chomp parameter string to print it to the screen

		$tmpstr = QlogicCreateDriverParameterStr($FALSE);
		chomp ($tmpstr);	
		Log ("set_parm: Adding $tmpstr to $modconf");
		print "Adding $tmpstr to $modconf\n";
	}
	
	if (!(EmulexHasOptionLine())) {
		Debug ("WriteNewParameters", "options lpfc is not in $modconf.new");
		Debug ("WriteNewParameters", "Adding line ".EmulexCreateDriverParameterStr($TRUE)." to $modconf.new");
		print DEST EmulexCreateDriverParameterStr($TRUE);	
		
		# Need to chomp parameter string to print it to the screen

		$tmpstr = EmulexCreateDriverParameterStr($FALSE);
		chomp ($tmpstr);
		Log ("set_parm: Adding $tmpstr to $modconf");
		print "Adding $tmpstr to $modconf\n";
	}
	
	# Close the file
	
	close (SRC);
	close (DEST);
	
	# Now move the files into place
	
	Move ($modconf, "$modconf.old");
	Move ("$modconf.new", $modconf);
}

# Name: QlogicReadDriverParameters
# Description: Reads the QLogic driver parameters from modprobe.conf
# In: None
# Out: qlogic_param hash updated with parameters from modprobe.conf
# Returns: None
sub QlogicReadDriverParameters {
	# Open file and slurp in contents
	
	Debug ("QlogicReadDriverParameters", "modconf is $modconf");
	open (MODCONF, $modconf) or die "Could not open $modconf\n";
	my @contents = <MODCONF>;
	close (MODCONF);
	
	# Use grep to get the options qla2xxx line
	my @grep_results = grep (/$qlogic_line/, @contents); 
	my $optionstr = $grep_results[0];
	Debug ("QlogicReadDriverParameters", "optionstr is \"$optionstr\"");
	
	# Apply transform to get rid of options qla2xxx string
	$optionstr =~ s/$qlogic_line\s+//;
	
	# Split out all the parameters
	my @theparameters = split (/\s+/, $optionstr);
		
	# Now loop over all the parameters and set their values in the
	# qlogic_param hash
	
	my $size = @theparameters;
	Debug ("QlogicReadDriverParameters", "Number of parameters is $size");
	
	for (my $i = 0; $i < $size; $i = $i + 1) {
		my @awk = split (/=/, $theparameters[$i]);
		Debug ("QlogicReadDriverParameters", "Setting qlogic_param\{$awk[0]\} to $awk[1]");
		$qlogic_param{$awk[0]} = $awk[1];
	}
}


# Name: EmulexReadDriverParameters
# Description: Reads the Emulex driver parameters from modprobe.conf
# In: None
# Out: emulex_param hash updated with parameters from modprobe.conf
# Returns: None
sub EmulexReadDriverParameters {
	# Open file and slurp in contents
	
	Debug ("EmulexReadDriverParameters", "modconf is $modconf");
	open (MODCONF, $modconf) or die "Could not open $modconf\n";
	my @contents = <MODCONF>;
	close (MODCONF);
	
	# Use grep to get the options qla2xxx line
	my @grep_results = grep (/$emulex_line/, @contents); 
	my $optionstr = $grep_results[0];
	Debug ("EmulexReadDriverParameters", "optionstr is \"$optionstr\"");
	
	# Apply transform to get rid of options qla2xxx string
	#$optionstr =~ s/$emulex_line //;
	$optionstr =~ s/$emulex_line\s+//;
	
	# Split out all the parameters
	my @theparameters = split (/\s+/, $optionstr);
	
	# Now loop over all the parameters and set their values in the
	# qlogic_param hash
	
	my $size = @theparameters;
	Debug ("EmulexReadDriverParameters", "Number of parameters is $size");
	
	for (my $i = 0; $i < $size; $i = $i + 1) {
		my @awk = split (/=/, $theparameters[$i]);
		Debug ("EmulexReadDriverParameters", "Setting emulex_param\{$awk[0]\} to $awk[1]");
		$emulex_param{$awk[0]} = $awk[1];
	}
}
 
# Name: BrocadeSetParameters 
# Description: Sets Brocade HBA parameters (currently just pathtov) 
# In: pathtov value 
# Out: None
# Returns: None
sub BrocadeSetParameters {
 	my $pathtov = $_[0];
        my $brocade_port_str;
        my @brocade_ports;
	
        Debug ("BrocadeSetParameters", "Setting parameters");

        if ((-e "/usr/bin/bcu")) {

          $brocade_port_str = `bcu port --list | grep : | awk '{print \$3}'|grep :`;
          @brocade_ports = split ('\n', $brocade_port_str);

          foreach $brocade_port_str (@brocade_ports) {
                print "Setting pathtov=$pathtov for bfa port $brocade_port_str\n";
                (`bcu fcpim --pathtov $brocade_port_str $pathtov `);
          }
        }
}

# Name: RebuildInitrd
# Description: Rebuilds the initrd
# In: None
# Out: None
# Returns: None
sub RebuildInitrd () {
        if (-e $make_initrd) {
                print "\n";
                system ($make_initrd);
        }
        else {
                print "\n$make_initrd does not exist.  You will have to rebuild the initrd manually\n";
        }
}

#
# Script Main
#

# Save command line arguments
@arguments = @ARGV;

# Read the current parameters

QlogicReadDriverParameters();
EmulexReadDriverParameters();

# Parse the command line arguments

ParseArgs(@arguments);

# Change the parameters for multipath configurations

if ($set_multipath) {
        QlogicMultipathTransform();
        EmulexMultipathTransform();
	BrocadeMultipathTransform();
}
elsif ($set_singlepath) {
        QlogicSinglepathTransform();
        EmulexSinglepathTransform();
	BrocadeSinglepathTransform();
}	

# If we wanted to set default parameters set them here

if ($set_qlogic_default == $TRUE) {
	QlogicSetDefaultParameters();
}

if ($set_emulex_default == $TRUE) {
	EmulexSetDefaultParameters();
}	

# Write new parameters
WriteNewParameters();

# Remake the initrd if necessary

if ($remake_initrd) {
	RebuildInitrd();
}

Debug ("main", "Exiting GOOD");
exit ($GOOD);
