From 4d1e8f84c7ed304316dcb44a8293edb8608b2883 Mon Sep 17 00:00:00 2001 From: Mark Buechler Date: Wed, 23 Sep 2009 17:44:53 +0000 Subject: [PATCH] Changes for 1.0.10 - Added new [OPTIONS] section to config file. - Added new ISSUE_LIP option for fc targets to issue a LIP after group assignment changes. - Added new KEEP_CONFIG option to keep all options when overwriting a configuration file with -writeconfig. - General cleanup. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1134 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scstadmin/ChangeLog | 9 +++ scstadmin/README | 3 + scstadmin/scstadmin | 139 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 139 insertions(+), 12 deletions(-) diff --git a/scstadmin/ChangeLog b/scstadmin/ChangeLog index 4f9cadc13..579d54051 100644 --- a/scstadmin/ChangeLog +++ b/scstadmin/ChangeLog @@ -1,3 +1,12 @@ +Changes for 1.0.10 + +- Added new [OPTIONS] section to config file. +- Added new ISSUE_LIP option for fc targets to issue a LIP after group + assignment changes. +- Added new KEEP_CONFIG option to keep all options when overwriting a + configuration file with -writeconfig. +- General cleanup. + Changes for 1.0.9 - Move a user from one group to another when applying the configuration instead diff --git a/scstadmin/README b/scstadmin/README index 0314a3991..8e9b04242 100644 --- a/scstadmin/README +++ b/scstadmin/README @@ -75,6 +75,9 @@ To Do: - Compare device and assignment options between current and saved configurations and reopen/reassign as required if -ForceConfig is used. +Completed: +========== + - Create options section to scst.conf which will be carried forward in a -writeconfig. - Add option to issue a LIP after any group assignment changes so initiators can see diff --git a/scstadmin/scstadmin b/scstadmin/scstadmin index dfd718c7c..6045e887d 100755 --- a/scstadmin/scstadmin +++ b/scstadmin/scstadmin @@ -1,5 +1,5 @@ #!/usr/bin/perl -$Version = 'SCST Configurator v1.0.9'; +$Version = 'SCST Configurator v1.0.10'; # Configures SCST # @@ -23,6 +23,7 @@ General Operations Target Driver Operations -enable : Enable target mode for driver at specified WWN or host. -disable : Disable target mode for driver at specified WWN or host. + -issuelip : Issue LIP on all target-enabled fabrics. Device Operations -adddev : Adds a device to a handler. @@ -100,6 +101,9 @@ Examples: Rename a security group: scstadmin -RenameGroup HOST01 -to SERVER01 + Tell all initiators to rescan LUNs: + scstadmin -issuelip + EndUsage } @@ -212,6 +216,7 @@ sub getArgs { my $blocksize; my $enable; my $disable; + my $issuelip; my $p = new Getopt::Long::Parser; @@ -244,6 +249,7 @@ sub getArgs { 'blocksize=s' => \$blocksize, 'enable=s' => \$enable, 'disable=s' => \$disable, + 'issuelip' => \$issuelip, 'debug' => \$_DEBUG_)) { &usage(); } @@ -253,6 +259,11 @@ sub getArgs { usage(); } + if (defined($issuelip) && ($enable || $disable)) { + print "Argument -issuelip cannot be used with -enable or -disable.\n\n"; + usage(); + } + if ($handler && !$_HANDLER_MAP_{$handler}) { print "Invalid handler '$handler' specified. Available handlers are:\n\n"; foreach my $_handler (keys %_HANDLER_MAP_) { @@ -346,6 +357,7 @@ sub getArgs { $forceConfig = $TRUE if (defined($forceConfig)); $showSessions = $TRUE if (defined($showSessions)); + $issuelip = $TRUE if (defined($issuelip)); $enable =~ tr/A-Z/a-z/; $disable =~ tr/A-Z/a-z/; $options =~ tr/a-z/A-Z/ if ($options); @@ -362,7 +374,7 @@ sub getArgs { $applyConfig = $_DEF_CONFIG_ if (defined($applyConfig) && !$applyConfig); $checkConfig = $_DEF_CONFIG_ if (defined($checkConfig) && !$checkConfig); - return ($enable, $disable, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, + return ($enable, $disable, $issuelip, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, $moveUser, $removeUser, $clearUsers, $addGroup, $renameGroup, $toGroup, $removeGroup, $assignDev, $replaceDev, $releaseDev, $clearDevs, $handler, $group, $options, $blocksize, $applyConfig, $forceConfig, $clearConfig, $writeConfig, $checkConfig, $showSessions); @@ -376,7 +388,7 @@ sub main { # We need to run as root if ( $> ) {die("This program must run as root.\n");} - my ($enable, $disable, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, + my ($enable, $disable, $issuelip, $addDev, $devPath, $devLun, $resyncDev, $removeDev, $addUser, $moveUser, $removeUser, $clearUsers, $addGroup, $renameGroup, $toGroup, $removeGroup, $assignDev, $replaceDev, $releaseDev, $clearDevs, $handler, $group, $options, $blocksize, $applyConfig, $forceConfig, $clearConfig, $writeConfig, $checkConfig, $showSessions) = getArgs(); @@ -481,13 +493,17 @@ sub main { $rc = enableTarget($disable, $FALSE); last SWITCH; }; + $issuelip && do { + $rc = issueLIP(); + last SWITCH; + }; print "No valid operations specified.\n"; usage(); exit $TRUE; } - print "All done.\n"; + print "\nAll done.\n"; exit $rc; } @@ -495,7 +511,7 @@ sub main { sub readWorkingConfig { my %empty; - print "Collecting current configuration.. "; + print "Collecting current configuration: "; $TARGETS = undef; $DEVICES = undef; @@ -535,6 +551,9 @@ sub readWorkingConfig { sub writeConfiguration { my $file = shift; + my $keep_config; + + my $config = readConfig($file, $TRUE); if (-f $file) { if (!unlink $file) { @@ -557,6 +576,36 @@ sub writeConfiguration { print $io "# NOTE: Options are pipe (|) seperated.\n\n"; + print $io "[OPTIONS]\n"; + print $io "#OPTION <1|0|YES|NO|TRUE|FALSE|VALUE>\n"; + print $io "# Copy configuration options during a -writeconfig\n"; + print $io "KEEP_CONFIG "; + + if (defined($config)) { + $keep_config = $$config{'OPTIONS'}->{'default'}->{'KEEP_CONFIG'}[0]; + } else { + $keep_config = $FALSE; + } + + if (!defined($config)) { + print $io "TRUE\n"; + } elsif (!$keep_config ) { + print $io "FALSE\n"; + } else { + print $io "TRUE\n"; + } + + print $io "# For FC targets, issue a LIP after every assignment change\n"; + print $io "ISSUE_LIP "; + + if (!$keep_config) { + print $io "TRUE\n"; + } else { + print $io ($$config{'OPTIONS'}->{'default'}->{'ISSUE_LIP'}[0] ? "TRUE\n" : "FALSE\n"); + } + + print $io "\n"; + # Device information foreach my $handler (sort keys %HANDLERS) { if ($SCST->handlerType($handler) == $SCST::SCST::IOTYPE_VIRTUAL) { @@ -643,6 +692,9 @@ sub applyConfiguration { my $errs; my $changes = 0; + my $assign_changes = 0; + my $targets_changed = $FALSE; + my %used_devs; my %used_users; my %used_assignments; @@ -652,6 +704,8 @@ sub applyConfiguration { my %rename_group; + my $issue_lip = $$config{'OPTIONS'}->{'default'}->{'ISSUE_LIP'}[0]; + # Cache device/handler configuration foreach my $entry (keys %{$$config{'HANDLER'}}) { foreach my $device (@{$$config{'HANDLER'}->{$entry}->{'DEVICE'}}) { @@ -677,10 +731,19 @@ sub applyConfiguration { # Cache device association configuration foreach my $group (keys %{$$config{'ASSIGNMENT'}}) { + my %seen_luns; + foreach my $device (@{$$config{'ASSIGNMENT'}->{$group}->{'DEVICE'}}) { my($vname, $arg) = split(/\,/, $device, 2); $vname = cleanupString($vname); + my($lun, $options) = split(/\,/, $arg); + if ($seen_luns{$lun}) { + print "\t-> FATAL: Configuration invalid. Group '$group' has multiple ". + "devices assigned to LUN $lun.\n"; + exit 1; + } $used_assignments{$group}->{$vname} = $arg; + $seen_luns{$lun}++; } } @@ -697,6 +760,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $assign_changes++; } } else { print ".\n"; @@ -720,7 +784,6 @@ sub applyConfiguration { if (!$check) { my $_lun = $$_assignments{$device}; - my $replace_dev = findAssignedLun($used_assignments{$group}, $_lun); if (defined($replace_dev) && ($replace_dev ne $device)) { @@ -730,6 +793,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $assign_changes++; } } else { print ", releasing.\n"; @@ -737,6 +801,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $assign_changes++; } } } else { @@ -858,7 +923,7 @@ sub applyConfiguration { } } - print "Applying configuration additions..\n" if (!$check); + print "\nApplying configuration additions..\n" if (!$check); print "\n"; readWorkingConfig() if ($force); @@ -1001,6 +1066,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $assign_changes++; } } } @@ -1024,7 +1090,7 @@ sub applyConfiguration { $enable = $FALSE; } else { print "\t-> WARNING: Ignoring invalid TARGETS specifier '$type'. ". - "Should be one of enable,disable.\n"; + "Should be one of enable, disable.\n"; next; } @@ -1050,6 +1116,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $targets_changed = $TRUE; } } else { print ".\n"; @@ -1066,6 +1133,7 @@ sub applyConfiguration { $errs++; } else { $changes++; + $targets_changed = $TRUE; } } else { print ".\n"; @@ -1075,13 +1143,18 @@ sub applyConfiguration { } } - print "\nEncountered $errs error(s) while processing.\n" if ($errs); + if ($issue_lip && $assign_changes && !$targets_changed) { + print "\nMaking initiators aware of assignment changes..\n\n"; + issueLIP(); + } + + print "\n\nEncountered $errs error(s) while processing.\n" if ($errs); if ($check) { - print "Configuration checked, $changes difference(s) found with working configuration.\n"; + print "\nConfiguration checked, $changes difference(s) found with working configuration.\n"; } else { $changes = 0 if ($_DEBUG_); - print "Configuration applied, $changes changes made.\n"; + print "\nConfiguration applied, $changes changes made.\n"; } return $TRUE if ($errs); @@ -1612,6 +1685,11 @@ sub targets { $targets{$fcards{$entry}}->{'enabled'} = $enabled; $targets{$fcards{$entry}}->{'path'} = "$_SCSI_CLASS_/$entry/target_mode_enabled"; + + if (-f "$_FC_CLASS_/$entry/issue_lip") { + $targets{$fcards{$entry}}->{'ilip'} = "$_FC_CLASS_/$entry/issue_lip"; + } + $targets{$entry}->{'duplicate'} = $TRUE; } else { $targets{$entry}->{'duplicate'} = $FALSE; @@ -1704,8 +1782,30 @@ sub enableTarget { return $FALSE; } +sub issueLIP { + foreach my $target (keys %{$TARGETS}) { + next if ($$TARGETS{$target}->{'duplicate'}); + + if (defined($$TARGETS{$target}->{'ilip'})) { + my $io = new IO::File $$TARGETS{$target}->{'ilip'}, O_WRONLY; + return $TRUE if (!$io); + + print "\t-> Issuing LIP for target '$target': "; + + if ($_DEBUG_) { + print "DBG($$): ".$$TARGETS{$target}->{'ilip'}." -> $TRUE\n\n"; + } else { + print $io $TRUE; + } + + print "done.\n"; + } + } +} + sub readConfig { my $confile = shift; + my $ignoreError = shift; my %config; my $section; my $last_section; @@ -1715,7 +1815,11 @@ sub readConfig { my $io = new IO::File $confile, O_RDONLY; - die("FATAL: Unable to open specified configuration file $confile: $!\n") if (!$io); + if (!$io) { + return undef if ($ignoreError); + + die("FATAL: Unable to open specified configuration file $confile: $!\n"); + } while (my $line = <$io>) { ($line, undef) = split(/\#/, $line, 2); @@ -1724,6 +1828,8 @@ sub readConfig { if ($line =~ /^\[(.*)\]$/) { ($section, $arg) = split(/\s+/, $1, 2); + $arg = 'default' if ($section eq 'OPTIONS'); + if ($last_arg && ($last_arg ne $arg) && !defined($config{$last_section}->{$last_arg})) { $config{$last_section}->{$last_arg} = \%empty; @@ -1734,6 +1840,15 @@ sub readConfig { } elsif ($section && $arg && $line) { my($parameter, $value) = split(/\s+/, $line, 2); + if ($section eq 'OPTIONS') { + $value = $TRUE if (($value == 1) || + ($value =~ /^TRUE$/i) || + ($value =~ /^YES$/i)); + $value = $FALSE if (($value == 0) || + ($value =~ /^FALSE$/i) || + ($value =~ /^NO$/i)); + } + push @{$config{$section}->{$arg}->{$parameter}}, $value; } }