From 1e95f146b16fecc61198636504db3c252c67f1b9 Mon Sep 17 00:00:00 2001 From: Mark Buechler Date: Thu, 21 Jul 2011 18:50:58 +0000 Subject: [PATCH] - Hopefully finish out module additions (largely untested) - Add basic functions to scstadmin for ALUA - Increment version to be more in line with next SCST release git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3715 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- .../scst-0.9.00/lib/SCST/SCST.pm | 137 ++++++++++++++- scstadmin/scstadmin.sysfs/scstadmin | 166 +++++++++++++++++- 2 files changed, 292 insertions(+), 11 deletions(-) diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.00/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-0.9.00/lib/SCST/SCST.pm index dc92ce9dd..9755c7fe1 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.00/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-0.9.00/lib/SCST/SCST.pm @@ -150,6 +150,10 @@ SCST_C_DGRP_ADD_GRP_FAIL => 134, SCST_C_DGRP_REM_GRP_FAIL => 135, SCST_C_DGRP_NO_GROUP => 136, SCST_C_DGRP_GROUP_EXISTS => 137, + +SCST_C_TGRP_BAD_ATTRIBUTES => 140, +SCST_C_TGRP_ATTRIBUTE_STATIC => 141, +SCST_C_TGRP_SETATTR_FAIL => 142, }; my %VERBOSE_ERROR = ( @@ -242,20 +246,24 @@ my %VERBOSE_ERROR = ( (SCST_C_DGRP_REM_GRP_FAIL) => 'Failed to remove target group from device group. See "dmesg" for more information.', (SCST_C_DGRP_NO_GROUP) => 'No such target group exists within device group.', (SCST_C_DGRP_GROUP_EXISTS) => 'Target group already exists within device group.', + +(SCST_C_TGRP_BAD_ATTRIBUTES) => 'Bad attributes for target group.', +(SCST_C_TGRP_ATTRIBUTE_STATIC) => 'Target group attribute specified is static.', +(SCST_C_TGRP_SETATTR_FAIL) => 'Failed to set target group attribute. See "dmesg" for more information.', ); use vars qw(@ISA @EXPORT $VERSION); use vars qw($TGT_TYPE_HARDWARE $TGT_TYPE_VIRTUAL); -$VERSION = 0.9.00; +$VERSION = 0.9.10; $TGT_TYPE_HARDWARE = 1; $TGT_TYPE_VIRTUAL = 2; my $TIMEOUT = 300; # Command execution timeout -my $_SCST_MIN_MAJOR_ = 2; +my $_SCST_MIN_MAJOR_ = 3; my $_SCST_MIN_MINOR_ = 0; my $_SCST_MIN_RELEASE_ = 0; @@ -328,7 +336,9 @@ sub new { die("Failed to obtain SCST version information. Are the SCST modules loaded?\n") if (!defined($scstVersion)); + ($scstVersion, undef) = split(/\-/, $scstVersion); my($major, $minor, $release) = split(/\./, $scstVersion, 3); + ($release, undef) = split(/\-/, $release) if ($release =~ /\-/); $badVersion = 0 if (($major > $_SCST_MIN_MAJOR_) || @@ -3219,6 +3229,129 @@ sub setInitiatorAttribute { return SCST_C_INI_SETATTR_FAIL; } +sub deviceGroupTargetGroupAttributes { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my %attributes; + + if ($self->deviceGroupExists($group) != TRUE) { + $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Device group '$group' does not exist"; + return undef; + } + + if ($self->deviceGroupTargetGroupExists($group, $tgroup) != TRUE) { + $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Target Group '$tgroup' does not exist"; + return undef; + } + + my $pHandle = new IO::Handle; + my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup); + if (!(opendir $pHandle, $_path)) { + $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Unable to read directory '$_path': $!"; + return undef; + } + + foreach my $attribute (readdir($pHandle)) { + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); + my $pPath = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $attribute); + my $mode = (stat($pPath))[2]; + if (-d $pPath) { + # Skip directories + } else { + if (!(($mode & S_IRUSR) >> 6)) { + $attributes{$attribute}->{'static'} = FALSE; + $attributes{$attribute}->{'value'} = undef; + } else { + my $is_static; + if (($mode & S_IWUSR) >> 6) { + $is_static = FALSE; + } else { + $is_static = TRUE; + } + + my $io = new IO::File $pPath, O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Unable to read ". + "target group attribute '$attribute': $!"; + return undef; + } + + my $value = <$io>; + chomp $value; + + my $is_key = <$io>; + $is_key = new_sysfs_interface() && !$is_static || + ($is_key =~ /\[key\]/) ? TRUE : FALSE; + + my $key = 0; + if ($is_key) { + if ($attribute =~ /.*(\d+)$/) { + $key = $1; + $attribute =~ s/\d+$//; + } + } + + next if ($attribute eq SCST_MGMT_IO); + + $attributes{$attribute}->{'static'} = $is_static; + + if ($is_key) { + $attributes{$attribute}->{'keys'}->{$key}->{'value'} = $value; + } else { + $attributes{$attribute}->{'value'} = $value; + } + } + } + } + + return \%attributes; +} + +sub setDeviceGroupTargetGroupAttribute { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $attribute = shift; + my $value = shift; + + my $rc = $self->deviceGroupExists($group); + return SCST_C_DEV_GRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->deviceGroupTargetGroupExists($group, $tgroup); + return SCST_C_DGRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + return TRUE if (!defined($attribute) || !defined($value)); + + my $attributes = $self->deviceGroupTargetGroupAttributes($group, $tgroup); + + return SCST_C_TGRP_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); + return SCST_C_TGRP_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); + + my $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $attribute); + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGRP_SETATTR_FAIL if (!$io); + + my $bytes; + + if ($self->{'debug'}) { + print "DBG($$): $path -> $attribute = $value\n"; + } else { + $bytes = _syswrite($io, $value, length($value)); + } + + close $io; + + return FALSE if ($self->{'debug'} || $bytes); + return SCST_C_GRP_SETATTR_FAIL; +} + sub handlers { my $self = shift; my @handlers; diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 7c6acb04c..8afdc46b1 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -1,12 +1,12 @@ #!/usr/bin/perl -$Version = 'SCST Configurator v2.0.0'; +$Version = 'SCST Configurator v3.0.0-pre0'; # Configures SCST # # Author: Mark R. Buechler # License: GPLv2 -# Copyright (c) 2005-2010 Mark R. Buechler +# Copyright (c) 2005-2011 Mark R. Buechler # Copyright (C) 2011 Bart Van Assche sub usage @@ -26,6 +26,7 @@ General Operations Query Operations -list_handler [] : List all available handlers or specific . -list_device [] : List all open devices or specific . + -list_dev_grp [] : List all device groups or specific . -list_driver [] : List all available drivers or specific . -list_target [] : List all available targets or specific . [-driver ] @@ -102,6 +103,10 @@ Device Operations -close_dev : Closes a device belonging to handler . -handler +Device Group Operations + -add_dev_grp : Add device group . + -rem_dev_grp : Remove device group . + Target Operations -add_target : Add a dynamic target to a capable driver. -driver @@ -198,7 +203,7 @@ Examples: EndUsage } -use SCST::SCST 0.9.0; +use SCST::SCST 0.9.10; use Getopt::Long; use IO::File; use IO::Dir; @@ -237,6 +242,7 @@ sub getArgs { my $listHandler; my $listDevice; + my $listDeviceGroup; my $listDriver; my $listTarget; my $listGroup; @@ -269,6 +275,9 @@ sub getArgs { my $closeDev; my $resyncDev; + my $addDevGroup; + my $removeDevGroup; + my $addTarget; my $removeTarget; @@ -311,6 +320,7 @@ sub getArgs { 'list_handler:s' => \$listHandler, 'list_device:s' => \$listDevice, + 'list_dev_grp:s' => \$listDeviceGroup, 'list_driver:s' => \$listDriver, 'list_target:s' => \$listTarget, 'list_group:s' => \$listGroup, @@ -343,6 +353,9 @@ sub getArgs { 'close_dev=s' => \$closeDev, 'resync_dev=s' => \$resyncDev, + 'add_dev_grp=s' => \$addDevGroup, + 'rem_dev_grp=s' => \$removeDevGroup, + 'add_target=s' => \$addTarget, 'rem_target=s' => \$removeTarget, @@ -394,9 +407,9 @@ sub getArgs { $force = TRUE if (defined($force)); $nonkey = TRUE if (defined($nonkey)); - my $query_mode = defined($listHandler) || defined($listDevice) || defined($listDriver) || - defined($listTarget) || defined($listGroup) || defined($listSessions) || defined($listScstAttr) || - defined($listHandlerAttr) || defined($listDeviceAttr) || defined($listDriverAttr) || + my $query_mode = defined($listHandler) || defined($listDevice) || defined($listDeviceGroup) || + defined($listDriver) || defined($listTarget) || defined($listGroup) || defined($listSessions) || + defined($listScstAttr) || defined($listHandlerAttr) || defined($listDeviceAttr) || defined($listDriverAttr) || defined($listTargetAttr) || defined($listGroupAttr) || defined($listLunAttr) || defined($listInitiatorAttr); my $set_mode = defined($setScstAttr) + defined($setHandlerAttr) + defined($setDeviceAttr) + @@ -404,7 +417,8 @@ sub getArgs { defined($setLunAttr) + defined($setInitiatorAttr); my $op_mode = defined($clearConfig) + defined($writeConfig) + defined($checkConfig) + - defined($openDev) + defined($closeDev) + defined($addGroup) + defined($removeGroup) + + defined($openDev) + defined($closeDev) + defined($addDevGroup) + defined($removeDevGroup) + + defined($addGroup) + defined($removeGroup) + defined($addInitiator) + defined($removeInitiator) + defined($clearInitiators) + defined($addDriverAttr) + defined($addTargetAttr) + defined($remDriverAttr) + defined($remTargetAttr) + defined($addTarget) + defined($removeTarget) + @@ -569,12 +583,13 @@ sub getArgs { } return ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDriver, $listTarget, $listGroup, + $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listDriver, $listTarget, $listGroup, $listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr, $listGroupAttr, $listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, $setDeviceAttr, $setDriverAttr, $setTargetAttr, $setGroupAttr, $setLunAttr, $setInitiatorAttr, $addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr, $openDev, $closeDev, $resyncDev, + $addDevGroup, $removeDevGroup, $addTarget, $removeTarget, $addGroup, $removeGroup, $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, @@ -594,12 +609,13 @@ sub main { if ( $> ) {die("This program must run as root.\n");} my ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDriver, $listTarget, $listGroup, + $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listDriver, $listTarget, $listGroup, $listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr, $listGroupAttr, $listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, $setDeviceAttr, $setDriverAttr, $setTargetAttr, $setGroupAttr, $setLunAttr, $setInitiatorAttr, $addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr, $openDev, $closeDev, $resyncDev, + $addDevGroup, $removeDevGroup, $addTarget, $removeTarget, $addGroup, $removeGroup, $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, @@ -650,6 +666,10 @@ sub main { $rc = listDevices($listDevice, $nonkey); $all_good = TRUE; }; + defined($listDeviceGroup) && do { + $rc = listDeviceGroups($listDeviceGroup); + $all_good = TRUE; + }; defined($listDriver) && do { $rc = listDrivers($listDriver); $all_good = TRUE; @@ -805,6 +825,18 @@ sub main { print "\t-> Done.\n"; last SWITCH; }; + defined($addDevGroup) && do { + print "\n-> Making requested changes.\n"; + $rc = addDeviceGroup($addDevGroup); + print "\t-> Done.\n"; + last SWITCH; + }; + defined($removeDevGroup) && do { + print "\n-> Making requested changes.\n"; + $rc = removeDeviceGroup($removeDevGroup, $force); + print "\t-> Done.\n"; + last SWITCH; + }; defined($addTarget) && do { print "\n-> Making requested changes.\n"; $rc = addVirtualTarget($driver, $addTarget, $attributes); @@ -2312,6 +2344,80 @@ sub listDevice { return listAttributes($attributes, $nonkey); } +sub listDeviceGroups { + my $group = shift; + + return listDeviceGroup($group) if ($group ne ''); + + my $groups = $SCST->deviceGroups(); + + my $l_group; + foreach my $group (@{$groups}) { + $l_group = length($group) if ($l_group < length($group)); + } + + $l_group = 12 if ($l_group < 12); + + print "\tDevice Group\n"; + print "\t"; + for (my $x = 0; $x < $l_group; $x++) { + print "-"; + } + print "\n"; + + foreach my $group (@{$groups}) { + print "\t$group\n"; + } + + return FALSE; +} + +sub listDeviceGroup { + my $group = shift; + + my $devices = $SCST->deviceGroupDevices($group); + + my $l_device; + foreach my $device (@{$devices}) { + $l_device = length($device) if ($l_device < length($device)); + } + + $l_device = 7 if ($l_device < 6); + + print "\tDevices\n"; + print "\t"; + for (my $x = 0; $x < $l_device; $x++) { + print "-"; + } + print "\n"; + + foreach my $device (@{$devices}) { + print "\t$device\n"; + } + + my $tgroups = $SCST->deviceGroupTargetGroups($group); + + my $l_tgroup; + foreach my $tgroup (@{$tgroups}) { + $l_tgroup = length($tgroup) if ($l_tgroup < length($tgroup)); + } + + $l_tgroup = 12 if ($l_tgroup < 12); + + print "\n\tTarget Groups\n"; + print "\t"; + for (my $x = 0; $x < $l_tgroup; $x++) { + print "-"; + } + print "\n"; + + foreach my $tgroup (@{$tgroups}) { + print "\t$tgroup\n"; + } + + return FALSE; +} + sub listDrivers { my $driver = shift; @@ -3646,6 +3752,48 @@ sub resyncDevice { #################################################################### +sub addDeviceGroup { + my $group = shift; + + print "\t-> Adding new device group '$group': "; + + my $rc = $SCST->addDeviceGroup($group); + + print "done.\n"; + + immediateExit($SCST->errorString($rc)) if ($rc); + + return FALSE; +} + +sub removeDeviceGroup { + my $group = shift; + my $force = shift; + + if (!$force) { + my $devices = $SCST->deviceGroupDevices($group); + my $tgroups = $SCST->deviceGroupTargetGroups($group); + + if (($#{$devices} > -1) || ($#{$tgroups} > -1)) { + print "\n"; + listDeviceGroup($group); + immediateExit("Device group is still in use, aborting. Use -force to override."); + } + } + + print "\t-> Removing device group '$group': "; + + my $rc = $SCST->removeDeviceGroup($group); + + print "done.\n"; + + immediateExit($SCST->errorString($rc)) if ($rc); + + return FALSE; +} + +#################################################################### + sub addGroup { my $driver = shift; my $target = shift;