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 d9354ee91..c74f04e47 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 @@ -143,6 +143,10 @@ SCST_C_DEV_GRP_EXISTS => 121, SCST_C_DEV_GRP_ADD_FAIL => 122, SCST_C_DEV_GRP_REM_FAIL => 123, +SCST_C_ALUA_BAD_ATTRIBUTES => 125, +SCST_C_ALUA_ATTRIBUTE_STATIC => 126, +SCST_C_ALUA_SETATTR_FAIL => 127, + SCST_C_DGRP_ADD_DEV_FAIL => 130, SCST_C_DGRP_REM_DEV_FAIL => 131, SCST_C_DGRP_NO_DEVICE => 132, @@ -743,6 +747,57 @@ sub luns { return \%luns; } +sub aluaAttributes { + my $self = shift; + my %attributes; + + my $pHandle = new IO::Handle; + my $_path = SCST_DEV_GROUP_DIR(); + if (!(opendir $pHandle, $_path)) { + $self->{'err_string'} = "deviceGroupsAttributes(): Unable to read directory '$_path': $!"; + return undef; + } + + foreach my $attribute (readdir($pHandle)) { + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO || $attribute eq 'uevent'); + my $pPath = make_path(SCST_DEV_GROUP_DIR(), $attribute); + my $mode = (stat($pPath))[2]; + + if (!($mode & S_IRUSR)) { + $attributes{$attribute}->{'static'} = FALSE; + $attributes{$attribute}->{'value'} = undef; + } else { + my $is_static = !($mode & S_IWUSR); + my $io = new IO::File $pPath, O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "deviceGroupsAttributes(): Unable to read device attribute '$attribute': $!"; + return undef; + } + + my $value = <$io>; + chomp $value; + + my $second_line = <$io>; + if (new_sysfs_interface() && !$is_static + || ($second_line =~ /\[key\]/)) { + my $key = 0; + if ($attribute =~ /^([^\d]+)(\d+)$/) { + $attribute = $1; + $key = $2; + } + $attributes{$attribute}->{'keys'}->{$key}->{'value'} = $value; + } else { + $attributes{$attribute}->{'value'} = $value; + } + $attributes{$attribute}->{'static'} = $is_static; + } + } + + return \%attributes; +} + sub deviceGroups { my $self = shift; my @groups; @@ -3697,6 +3752,36 @@ sub targetGroupTargetAttributes { return \%attributes; } +sub setAluaAttribute { + my $self = shift; + my $attribute = shift; + my $value = shift; + + return TRUE if (!defined($attribute) || !defined($value)); + + my $attributes = $self->aluaAttributes(); + + return SCST_C_ALUA_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); + return SCST_C_ALUA_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); + + my $path = make_path(SCST_DEV_GROUP_DIR(), $attribute); + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_ALUA_SETATTR_FAIL if (!$io); + + my $bytes; + + if ($self->{'debug'}) { + print "DBG($$): $value > $path\n"; + } else { + $bytes = _syswrite($io, $value, length($value)); + } + + close $io; + + return ($self->{'debug'} || $bytes) ? 0 : SCST_C_ALUA_SETATTR_FAIL; +} + sub setDeviceGroupAttribute { my $self = shift; my $group = shift; diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index defe6cf49..62d333e9d 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -1632,6 +1632,19 @@ sub writeConfiguration { } } + my $dga = $SCST->aluaAttributes(); + my $dga_buff = serializeKeyAttr("\t", $dga); + my $dga_buff_nk = serializeNkAttr("\t", $dga) if ($nonkey); + if ($dga_buff_nk) { + $dga_buff .= "\t# Non-key attributes\n"; + $dga_buff .= $dga_buff_nk; + } + if ($dga_buff) { + print $io "ALUA {\n"; + print $io $dga_buff; + print $io "}\n\n"; + } + foreach my $dgroup (sort keys %{$CURRENT{'dgroups'}}) { my $dgroup_buff; @@ -1942,6 +1955,7 @@ sub applyConfiguration { # Apply config additions $changes += applyConfigDevices($CONFIG, $force); $changes += applyConfigAssignments($CONFIG, $force); + $changes += applyConfigAlua($CONFIG, $force); $changes += applyConfigDeviceGroups($CONFIG, $force); # And SCST attributes.. @@ -1949,6 +1963,7 @@ sub applyConfiguration { foreach my $item (keys %{$CONFIG}) { next if ($item eq 'HANDLER'); next if ($item eq 'TARGET_DRIVER'); + next if ($item eq 'ALUA'); next if ($item eq 'DEVICE_GROUP'); $_attributes{$item} = $$CONFIG{$item}; } @@ -2209,6 +2224,19 @@ sub applyConfigAssignments { return $changes; } +sub applyConfigAlua { + my $config = shift; + my $deletions = shift; + + my $alua_attr = $$config{'ALUA'}; + my %_attributes; + foreach my $item (keys %{$alua_attr}) { + $_attributes{$item} = $alua_attr->{$item}; + } + my $attributes = configToAttr(\%_attributes); + return setAluaAttributes($attributes); +} + sub applyConfigDeviceGroups { my $config = shift; my $deletions = shift; @@ -3924,6 +3952,35 @@ sub setInitiatorAttributes { $_attributes, $error, \&setInitiatorAttribute, $showset); } +sub setAluaAttributes { + my $attributes = shift; + my $showset = shift; + + my $error = "\t-> WARNING: no settable ALUA attribute '%s', ignoring.\n\n"; + + my $_attributes = $SCST->aluaAttributes(); + + return TRUE if issueWarning($SCST->errorString()); + + return setAttributes(undef, undef, undef, undef, $attributes, + $_attributes, $error, \&setAluaAttribute, $showset); +} + +sub setAluaAttribute { + shift; + shift; + shift; + shift; + my $attribute = shift; + my $value = shift; + + print "\t-> Setting ALUA attribute '$attribute' to value '$value': "; + my $rc = $SCST->setAluaAttribute($attribute, $value); + print "done.\n"; + + return $rc; +} + sub setDeviceGroupAttributes { my $group = shift; my $attributes = shift;