From d1b42a46a6d8994f7bb2551ad2033bf0a4c3a7a5 Mon Sep 17 00:00:00 2001 From: Mark Buechler Date: Fri, 22 Jul 2011 18:19:33 +0000 Subject: [PATCH] - Add initiator and attribute methods to module. - Rename overly long method names. - Add a couple more ALUA options to scstadmin. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3735 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- .../scst-0.9.10/lib/SCST/SCST.pm | 347 +++++++++++++++++- scstadmin/scstadmin.sysfs/scstadmin | 224 ++++++++++- 2 files changed, 536 insertions(+), 35 deletions(-) diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm index 9755c7fe1..44749e934 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm @@ -154,6 +154,15 @@ SCST_C_DGRP_GROUP_EXISTS => 137, SCST_C_TGRP_BAD_ATTRIBUTES => 140, SCST_C_TGRP_ATTRIBUTE_STATIC => 141, SCST_C_TGRP_SETATTR_FAIL => 142, + +SCST_C_TGRP_ADD_INI_FAIL => 150, +SCST_C_TGRP_REM_INI_FAIL => 151, +SCST_C_TGRP_NO_INI => 152, +SCST_C_TGRP_INI_EXISTS => 153, + +SCST_C_TGRP_INI_BAD_ATTR => 160, +SCST_C_TGRP_INI_ATTR_STATIC => 161, +SCST_C_TGRP_INI_SETATTR_FAIL => 162, }; my %VERBOSE_ERROR = ( @@ -250,6 +259,15 @@ my %VERBOSE_ERROR = ( (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.', + +(SCST_C_TGRP_ADD_INI_FAIL) => 'Failed to add initiator to target group.', +(SCST_C_TGRP_REM_INI_FAIL) => 'Failed to remove initiator from target group.', +(SCST_C_TGRP_NO_INI) => 'No such initiator exists within target group.', +(SCST_C_TGRP_INI_EXISTS) => 'Initiator already exists within target group.', + +(SCST_C_TGRP_INI_BAD_ATTR) => 'Bad attributes for target group initiator.', +(SCST_C_TGRP_INI_ATTR_STATIC) => 'Target group initiator attribute specified is static.', +(SCST_C_TGRP_INI_SETATTR_FAIL) => 'Failed to set target group initiator attribute. See "dmesg" for more information.', ); use vars qw(@ISA @EXPORT $VERSION); @@ -742,20 +760,20 @@ sub deviceGroupDevices { return \@devices; } -sub deviceGroupTargetGroups { +sub targetGroups { my $self = shift; my $group = shift; my @tgroups; if ($self->deviceGroupExists($group) != TRUE) { - $self->{'err_string'} = "deviceGroupTargetGroups(): Device group '$group' does not exist"; + $self->{'err_string'} = "targetGroups(): Device group '$group' does not exist"; return undef; } my $dHandle = new IO::Handle; my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS); if (!(opendir $dHandle, $_path)) { - $self->{'err_string'} = "deviceGroupTargetGroups(): Unable to read directory '$_path': $!"; + $self->{'err_string'} = "targetGroups(): Unable to read directory '$_path': $!"; return undef; } @@ -772,6 +790,42 @@ sub deviceGroupTargetGroups { return \@tgroups; } +sub targetGroupInitiators { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my @initiators; + + if ($self->deviceGroupExists($group) != TRUE) { + $self->{'err_string'} = "targetGroupInitiators(): Device group '$group' does not exist"; + return undef; + } + + if ($self->targetGroupExists($group, $tgroup) != TRUE) { + $self->{'err_string'} = "targetGroupInitiators(): Target group '$tgroup' does not exist"; + return undef; + } + + my $dHandle = new IO::Handle; + my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup); + if (!(opendir $dHandle, $_path)) { + $self->{'err_string'} = "targetGroups(): Unable to read directory '$_path': $!"; + return undef; + } + + foreach my $ini (readdir($dHandle)) { + next if (($ini eq '.') || ($ini eq '..')); + + if (-d make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $ini)) { + push @initiators, $ini; + } + } + + close $dHandle; + + return \@initiators; +} + sub driverExists { my $self = shift; my $driver = shift; @@ -1620,7 +1674,7 @@ sub addDeviceGroupDevice { return SCST_C_DGRP_ADD_DEV_FAIL; } -sub addDeviceGroupTargetGroup { +sub addTargetGroup { my $self = shift; my $group = shift; my $tgroup = shift; @@ -1629,7 +1683,7 @@ sub addDeviceGroupTargetGroup { return SCST_C_DEV_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - $rc = $self->deviceGroupTargetGroupExists($group, $tgroup); + $rc = $self->targetGroupExists($group, $tgroup); return SCST_C_DGRP_GROUP_EXISTS if ($rc == TRUE); return $rc if ($rc > 1); @@ -1659,6 +1713,51 @@ sub addDeviceGroupTargetGroup { return SCST_C_DGRP_ADD_GRP_FAIL; } +sub addTargetGroupInitiator { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $ini = shift; + + my $rc = $self->deviceGroupExists($group); + return SCST_C_DEV_GRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->targetGroupExists($group, $tgroup); + return SCST_C_DGRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->targetGroupInitiatorExists($group, $tgroup, $ini); + return SCST_C_TGRP_INI_EXISTS if ($rc == TRUE); + return $rc if ($rc > 1); + + my ($path, $cmd); + if (new_sysfs_interface()) { + die("New /sys interface for device groups not yet supported."); + } else { + $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, + $tgroup, SCST_MGMT_IO); + } + $cmd .= "add $ini"; + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGRP_ADD_INI_FAIL if (!$io); + + my $bytes; + + if ($self->{'debug'}) { + print "DBG($$): $path -> $cmd\n"; + } else { + $bytes = _syswrite($io, $cmd, length($cmd)); + } + + close $io; + + return FALSE if ($self->{'debug'} || $bytes); + return SCST_C_TGRP_ADD_INI_FAIL; +} + sub removeDeviceGroupDevice { my $self = shift; my $group = shift; @@ -1702,7 +1801,7 @@ sub removeDeviceGroupDevice { return SCST_C_DGRP_REM_DEV_FAIL; } -sub removeDeviceGroupTargetGroup { +sub removeTargetGroup { my $self = shift; my $group = shift; my $tgroup = shift; @@ -1711,7 +1810,7 @@ sub removeDeviceGroupTargetGroup { return SCST_C_DEV_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - $rc = $self->deviceGroupTargetGroupExists($group, $tgroup); + $rc = $self->targetGroupExists($group, $tgroup); return SCST_C_DGRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); @@ -1741,6 +1840,51 @@ sub removeDeviceGroupTargetGroup { return SCST_C_DGRP_REM_GRP_FAIL; } +sub removeTargetGroupInitiator { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $ini = shift; + + my $rc = $self->deviceGroupExists($group); + return SCST_C_DEV_GRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->targetGroupExists($group, $tgroup); + return SCST_C_DGRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->targetGroupInitiatorExists($group, $tgroup, $ini); + return SCST_C_TGRP_NO_INI if (!$rc); + return $rc if ($rc > 1); + + my ($path, $cmd); + if (new_sysfs_interface()) { + die("New /sys interface for device groups not yet supported."); + } else { + $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, + $tgroup, SCST_MGMT_IO); + } + $cmd .= "del $ini"; + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGRP_REM_INI_FAIL if (!$io); + + my $bytes; + + if ($self->{'debug'}) { + print "DBG($$): $path -> $cmd\n"; + } else { + $bytes = _syswrite($io, $cmd, length($cmd)); + } + + close $io; + + return FALSE if ($self->{'debug'} || $bytes); + return SCST_C_TGRP_REM_INI_FAIL; +} + sub addInitiator { my $self = shift; my $driver = shift; @@ -3229,26 +3373,26 @@ sub setInitiatorAttribute { return SCST_C_INI_SETATTR_FAIL; } -sub deviceGroupTargetGroupAttributes { +sub targetGroupAttributes { 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"; + $self->{'err_string'} = "targetGroupAttributes(): Device group '$group' does not exist"; return undef; } - if ($self->deviceGroupTargetGroupExists($group, $tgroup) != TRUE) { - $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Target Group '$tgroup' does not exist"; + if ($self->targetGroupExists($group, $tgroup) != TRUE) { + $self->{'err_string'} = "targetGroupAttributes(): 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': $!"; + $self->{'err_string'} = "targetGroupAttributes(): Unable to read directory '$_path': $!"; return undef; } @@ -3274,7 +3418,7 @@ sub deviceGroupTargetGroupAttributes { my $io = new IO::File $pPath, O_RDONLY; if (!$io) { - $self->{'err_string'} = "deviceGroupTargetGroupAttributes(): Unable to read ". + $self->{'err_string'} = "targetGroupAttributes(): Unable to read ". "target group attribute '$attribute': $!"; return undef; } @@ -3310,7 +3454,95 @@ sub deviceGroupTargetGroupAttributes { return \%attributes; } -sub setDeviceGroupTargetGroupAttribute { +sub targetGroupInitiatorAttributes { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $ini = shift; + my %attributes; + + if ($self->deviceGroupExists($group) != TRUE) { + $self->{'err_string'} = "targetGroupInitiatorAttributes(): Device group '$group' does not exist"; + return undef; + } + + if ($self->targetGroupExists($group, $tgroup) != TRUE) { + $self->{'err_string'} = "targetGroupInitiatorAttributes(): Target Group '$tgroup' does not exist"; + return undef; + } + + if ($self->targetGroupInitiatorExists($group, $tgroup, $ini) != TRUE) { + $self->{'err_string'} = "targetGroupInitiatorAttributes(): Initiator '$ini' does not exist"; + return undef; + } + + my $pHandle = new IO::Handle; + my $_path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, $tgroup, $ini); + if (!(opendir $pHandle, $_path)) { + $self->{'err_string'} = "targetGroupInitiatorAttributes(): 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, $ini, $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'} = "targetGroupInitiatorAttributes(): Unable to read ". + "target group initiator 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 setTargetGroupAttribute { my $self = shift; my $group = shift; my $tgroup = shift; @@ -3321,13 +3553,13 @@ sub setDeviceGroupTargetGroupAttribute { return SCST_C_DEV_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - $rc = $self->deviceGroupTargetGroupExists($group, $tgroup); + $rc = $self->targetGroupExists($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); + my $attributes = $self->targetGroupAttributes($group, $tgroup); return SCST_C_TGRP_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_TGRP_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); @@ -3349,7 +3581,55 @@ sub setDeviceGroupTargetGroupAttribute { close $io; return FALSE if ($self->{'debug'} || $bytes); - return SCST_C_GRP_SETATTR_FAIL; + return SCST_C_TGRP_SETATTR_FAIL; +} + +sub setTargetGroupInitiatorAttribute { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $ini = 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->targetGroupExists($group, $tgroup); + return SCST_C_DGRP_NO_GROUP if (!$rc); + return $rc if ($rc > 1); + + $rc = $self->targetGroupInitiatorExists($group, $tgroup, $ini); + return SCST_C_TGRP_NO_INI if (!$rc); + return $rc if ($rc > 1); + + return TRUE if (!defined($attribute) || !defined($value)); + + my $attributes = $self->targetGroupInitiatorAttributes($group, $tgroup, $ini); + + return SCST_C_TGRP_INI_BAD_ATTR if (!defined($$attributes{$attribute})); + return SCST_C_TGRP_INI_ATTR_STATIC if ($$attributes{$attribute}->{'static'}); + + my $path = make_path(SCST_DEV_GROUP_DIR(), $group, SCST_DG_TGROUPS, + $tgroup, $ini, $attribute); + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGRP_INI_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_TGRP_INI_SETATTR_FAIL; } sub handlers { @@ -3950,17 +4230,17 @@ sub deviceGroupDeviceExists { return FALSE; } -sub deviceGroupTargetGroupExists { +sub targetGroupExists { my $self = shift; my $group = shift; my $tgroup = shift; if ($self->deviceGroupExists($group) != TRUE) { - $self->{'err_string'} = "deviceGroupTargetGroupExists(): Device group '$group' does not exist"; + $self->{'err_string'} = "targetGroupExists(): Device group '$group' does not exist"; return undef; } - my $tgroups = $self->deviceGroupTargetGroups($group); + my $tgroups = $self->targetGroups($group); return SCST_C_FATAL_ERROR if (!defined($tgroups)); @@ -3971,6 +4251,33 @@ sub deviceGroupTargetGroupExists { return FALSE; } +sub targetGroupInitiatorExists { + my $self = shift; + my $group = shift; + my $tgroup = shift; + my $ini = shift; + + if ($self->deviceGroupExists($group) != TRUE) { + $self->{'err_string'} = "targetGroupInitiatorExists(): Device group '$group' does not exist"; + return undef; + } + + if ($self->targetGroupExists($group, $tgroup) != TRUE) { + $self->{'err_string'} = "targetGroupInitiatorExists(): Target group '$tgroup' does not exist"; + return undef; + } + + my $initiators = $self->targetGroupInitiators($group, $tgroup); + + return SCST_C_FATAL_ERROR if (!defined($initiators)); + + foreach my $_ini (@{$initiators}) { + return TRUE if ($ini eq $_ini); + } + + return FALSE; +} + sub checkLunCreateAttributes { my $self = shift; my $driver = shift; diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 8afdc46b1..aa825e15a 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -26,7 +26,9 @@ 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_dgrp [] : List all device groups or specific . + -list_tgrp [] + [-target : List all target groups within a device group. -list_driver [] : List all available drivers or specific . -list_target [] : List all available targets or specific . [-driver ] @@ -104,8 +106,12 @@ Device Operations -handler Device Group Operations - -add_dev_grp : Add device group . - -rem_dev_grp : Remove device group . + -add_dgrp : Add device group . + -rem_dgrp : Remove device group . + -add_dgrp_dev + -device : Add device to device group . + -rem_dgrp_dev + -device : Remove device from device group . Target Operations -add_target : Add a dynamic target to a capable driver. @@ -243,6 +249,7 @@ sub getArgs { my $listHandler; my $listDevice; my $listDeviceGroup; + my $listTargetGroup; my $listDriver; my $listTarget; my $listGroup; @@ -277,6 +284,8 @@ sub getArgs { my $addDevGroup; my $removeDevGroup; + my $addDevGroupDevice; + my $removeDevGroupDevice; my $addTarget; my $removeTarget; @@ -320,7 +329,8 @@ sub getArgs { 'list_handler:s' => \$listHandler, 'list_device:s' => \$listDevice, - 'list_dev_grp:s' => \$listDeviceGroup, + 'list_dgrp:s' => \$listDeviceGroup, + 'list_tgrp:s' => \$listTargetGroup, 'list_driver:s' => \$listDriver, 'list_target:s' => \$listTarget, 'list_group:s' => \$listGroup, @@ -353,8 +363,10 @@ sub getArgs { 'close_dev=s' => \$closeDev, 'resync_dev=s' => \$resyncDev, - 'add_dev_grp=s' => \$addDevGroup, - 'rem_dev_grp=s' => \$removeDevGroup, + 'add_dgrp=s' => \$addDevGroup, + 'rem_dgrp=s' => \$removeDevGroup, + 'add_dgrp_dev=s' => \$addDevGroupDevice, + 'rem_dgrp_dev=s' => \$removeDevGroupDevice, 'add_target=s' => \$addTarget, 'rem_target=s' => \$removeTarget, @@ -407,7 +419,7 @@ sub getArgs { $force = TRUE if (defined($force)); $nonkey = TRUE if (defined($nonkey)); - my $query_mode = defined($listHandler) || defined($listDevice) || defined($listDeviceGroup) || + my $query_mode = defined($listHandler) || defined($listDevice) || defined($listDeviceGroup) || defined($listTargetGroup) || defined($listDriver) || defined($listTarget) || defined($listGroup) || defined($listSessions) || defined($listScstAttr) || defined($listHandlerAttr) || defined($listDeviceAttr) || defined($listDriverAttr) || defined($listTargetAttr) || defined($listGroupAttr) || defined($listLunAttr) || defined($listInitiatorAttr); @@ -418,7 +430,7 @@ sub getArgs { my $op_mode = defined($clearConfig) + defined($writeConfig) + defined($checkConfig) + defined($openDev) + defined($closeDev) + defined($addDevGroup) + defined($removeDevGroup) + - defined($addGroup) + defined($removeGroup) + + defined($addGroup) + defined($removeGroup) + defined($addDevGroupDevice) + defined($removeDevGroupDevice) + defined($addInitiator) + defined($removeInitiator) + defined($clearInitiators) + defined($addDriverAttr) + defined($addTargetAttr) + defined($remDriverAttr) + defined($remTargetAttr) + defined($addTarget) + defined($removeTarget) + @@ -564,6 +576,11 @@ sub getArgs { exit 1; } + if ((defined($addDevGroupDevice) || defined($removeDevGroupDevice)) && ($device eq '')) { + print "Please specify -device with -add_dgrp_dev/-rem_dgrp_dev.\n"; + exit 1; + } + $applyConfig = $_DEF_CONFIG_ if (defined($applyConfig) && ($applyConfig eq '')); $checkConfig = $_DEF_CONFIG_ if (defined($checkConfig) && ($checkConfig eq '')); @@ -583,13 +600,13 @@ sub getArgs { } return ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listDriver, $listTarget, $listGroup, + $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listTargetGroup, $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, + $addDevGroup, $removeDevGroup, $addDevGroupDevice, $removeDevGroupDevice, $addTarget, $removeTarget, $addGroup, $removeGroup, $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, @@ -609,13 +626,13 @@ sub main { if ( $> ) {die("This program must run as root.\n");} my ($applyConfig, $clearConfig, $writeConfig, $checkConfig, - $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listDriver, $listTarget, $listGroup, + $listScstAttr, $listHandler, $listDevice, $listDeviceGroup, $listTargetGroup, $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, + $addDevGroup, $removeDevGroup, $addDevGroupDevice, $removeDevGroupDevice, $addTarget, $removeTarget, $addGroup, $removeGroup, $addInitiator, $removeInitiator, $moveInitiator, $clearInitiators, @@ -670,6 +687,10 @@ sub main { $rc = listDeviceGroups($listDeviceGroup); $all_good = TRUE; }; + defined($listTargetGroup) && do { + $rc = listTargetGroups($listTargetGroup, $target); + $all_good = TRUE; + }; defined($listDriver) && do { $rc = listDrivers($listDriver); $all_good = TRUE; @@ -837,6 +858,18 @@ sub main { print "\t-> Done.\n"; last SWITCH; }; + defined($addDevGroupDevice) && do { + print "\n-> Making requested changes.\n"; + $rc = addDeviceGroupDevice($addDevGroupDevice, $device); + print "\t-> Done.\n"; + last SWITCH; + }; + defined($removeDevGroupDevice) && do { + print "\n-> Making requested changes.\n"; + $rc = removeDeviceGroupDevice($removeDevGroupDevice, $device, $force); + print "\t-> Done.\n"; + last SWITCH; + }; defined($addTarget) && do { print "\n-> Making requested changes.\n"; $rc = addVirtualTarget($driver, $addTarget, $attributes); @@ -2346,6 +2379,7 @@ sub listDevice { sub listDeviceGroups { my $group = shift; + my $showall = shift; return listDeviceGroup($group) if ($group ne ''); @@ -2366,7 +2400,8 @@ sub listDeviceGroups { print "\n"; foreach my $group (@{$groups}) { - print "\t$group\n"; + print "\t$group\n\n"; + listTargetGroups($group, undef, TRUE) if ($showall); } return FALSE; @@ -2395,7 +2430,7 @@ sub listDeviceGroup { print "\t$device\n"; } - my $tgroups = $SCST->deviceGroupTargetGroups($group); + my $tgroups = $SCST->targetGroups($group); my $l_tgroup; foreach my $tgroup (@{$tgroups}) { @@ -2418,6 +2453,97 @@ sub listDeviceGroup { return FALSE; } +sub listTargetGroups { + my $group = shift; + my $tgroup = shift; + my $indent = shift; + + return listDeviceGroups(undef, TRUE) if ($group eq ''); + return listTargetGroup($group, $tgroup) if ($tgroup ne ''); + + my $tgroups = $SCST->targetGroups($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"; + print "\t" if ($indent); + print "\tTarget Groups\n"; + print "\t"; + print "\t" if ($indent); + for (my $x = 0; $x < $l_tgroup; $x++) { + print "-"; + } + print "\n"; + + foreach my $tgroup (@{$tgroups}) { + print "\t" if ($indent); + print "\t$tgroup\n"; + } + + return FALSE; +} + +sub listTargetGroup { + my $group = shift; + my $tgroup = shift; + + my $initiators = $SCST->targetGroupInitiators($group, $tgroup); + + my $l_ini; + foreach my $ini (@{$initiators}) { + $l_ini = length($ini) if ($l_ini < length($ini)); + } + + $l_ini = 10 if ($l_ini < 10); + + print "\tInitiators\n"; + print "\t"; + for (my $x = 0; $x < $l_ini; $x++) { + print "-"; + } + print "\n"; + + foreach my $ini (@{$initiators}) { + print "\t$ini\n"; + } + + return FALSE; +} + +sub listDeviceGroupDevices { + my $group = shift; + my $device = shift; + + return listDevice($device) if ($device ne ''); + + 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 < 7); + + print "\tDevices\n"; + print "\t"; + for (my $x = 0; $x < $l_device; $x++) { + print "-"; + } + print "\n"; + + foreach my $device (@{$devices}) { + print "\t$device\n"; + } + + return FALSE; +} + sub listDrivers { my $driver = shift; @@ -3079,6 +3205,24 @@ sub listInitiatorAttributes { return listAttributes($attributes, $nonkey); } +sub listTargetGroupInitiatorAttributes { + my $group = shift; + my $tgroup = shift; + my $ini = shift; + my $nonkey = shift; + + my $attributes = $SCST->targetGroupInitiatorAttributes($group, $tgroup, $ini); + + return TRUE if issueWarning($SCST->errorString()); + + if (!scalar(keys %{$attributes})) { + print "No such initiator '$ini' exists within specified target group.\n"; + return; + } + + return listAttributes($attributes, $nonkey); +} + #################################################################### sub setScstAttribute { @@ -3772,7 +3916,7 @@ sub removeDeviceGroup { if (!$force) { my $devices = $SCST->deviceGroupDevices($group); - my $tgroups = $SCST->deviceGroupTargetGroups($group); + my $tgroups = $SCST->targetGroups($group); if (($#{$devices} > -1) || ($#{$tgroups} > -1)) { print "\n"; @@ -3792,6 +3936,56 @@ sub removeDeviceGroup { return FALSE; } +sub addDeviceGroupDevice { + my $group = shift; + my $device = shift; + + print "\t-> Adding new device group/device '$group/$device': "; + + my $rc = $SCST->addDeviceGroupDevice($group, $device); + + print "done.\n"; + + immediateExit($SCST->errorString($rc)) if ($rc); + + return FALSE; +} + +sub removeDeviceGroupDevice { + my $group = shift; + my $device = shift; + my $force = shift; + + if (!$force) { + my $found = FALSE; + my $tgroups = $SCST->targetGroups($group); + + foreach my $tgroup (@{$tgroups}) { + my $initiators = $SCST->targetGroupInitiators($group, $tgroup); + + if ($#{$initiators} > -1) { + print "\n"; + listTargetGroup($group, $tgroup); + $found = TRUE; + } + } + + if ($found) { + immediateExit("Device may still be in use, aborting. Use -force to override."); + } + } + + print "\t-> Removing device '$device' from target group '$group': "; + + my $rc = $SCST->removeDeviceGroupDevice($group, $device); + + print "done.\n"; + + immediateExit($SCST->errorString($rc)) if ($rc); + + return FALSE; +} + #################################################################### sub addGroup {