Changes for 1.0.10
authormgandalf <mgandalf@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Wed, 23 Sep 2009 17:44:53 +0000 (17:44 +0000)
committermgandalf <mgandalf@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Wed, 23 Sep 2009 17:44:53 +0000 (17:44 +0000)
- 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: https://scst.svn.sourceforge.net/svnroot/scst/trunk@1134 d57e44dd-8a1f-0410-8b47-8ef2f437770f

scstadmin/ChangeLog
scstadmin/README
scstadmin/scstadmin

index 4f9cadc..579d540 100644 (file)
@@ -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
index 0314a39..8e9b042 100644 (file)
@@ -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
index dfd718c..6045e88 100755 (executable)
@@ -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 <wwn|host>   : Enable target mode for driver at specified WWN or host.
      -disable <wwn|host>  : Disable target mode for driver at specified WWN or host.
+     -issuelip            : Issue LIP on all target-enabled fabrics.
 
 Device Operations
      -adddev <device>     : 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;
                }
        }