diff --git a/scstadmin/init.d/README.iscsi b/scstadmin/init.d/README.iscsi new file mode 100644 index 000000000..c86eba1e9 --- /dev/null +++ b/scstadmin/init.d/README.iscsi @@ -0,0 +1,2 @@ +These init scripts are intended for use with non-iscsi configurations. For +iscsi, please use one of the init scripts found in iscsi-scst/etc/initd. 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 16e39d0fd..7316384cf 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 @@ -81,6 +81,7 @@ SCST_C_TGT_BAD_ATTRIBUTES => 50, SCST_C_TGT_ATTRIBUTE_STATIC => 51, SCST_C_TGT_SETATTR_FAIL => 52, SCST_C_TGT_CLR_LUN_FAIL => 53, +SCST_C_TGT_BUSY => 54, SCST_C_GRP_NO_GROUP => 60, SCST_C_GRP_EXISTS => 61, @@ -112,6 +113,9 @@ SCST_C_LUN_SETATTR_FAIL => 99, SCST_C_INI_BAD_ATTRIBUTES => 100, SCST_C_INI_ATTRIBUTE_STATIC => 101, SCST_C_INI_SETATTR_FAIL => 102, + +SCST_C_NO_SESSION => 110, +SCST_C_SESSION_CLOSE_FAIL => 111, }; my %VERBOSE_ERROR = ( @@ -155,6 +159,7 @@ my %VERBOSE_ERROR = ( (SCST_C_TGT_ATTRIBUTE_STATIC) => 'Target attribute specified is static.', (SCST_C_TGT_SETATTR_FAIL) => 'Failed to set target attribute. See "dmesg" for more information.', (SCST_C_TGT_CLR_LUN_FAIL) => 'Failed to clear LUNs from target. See "dmesg" for more information.', +(SCST_C_TGT_BUSY) => 'Failed to remove target - target has active sessions. See "dmesg" for more information.', (SCST_C_GRP_NO_GROUP) => 'No such group exists.', (SCST_C_GRP_EXISTS) => 'Group already exists.', @@ -186,6 +191,9 @@ my %VERBOSE_ERROR = ( (SCST_C_INI_BAD_ATTRIBUTES) => 'Bad attributes for initiator.', (SCST_C_INI_ATTRIBUTE_STATIC) => 'Initiator attribute specified is static.', (SCST_C_INI_SETATTR_FAIL) => 'Failed to set initiator attribute. See "dmesg" for more information.', + +(SCST_C_NO_SESSION) => 'Session not found for driver/target.', +(SCST_C_SESSION_CLOSE_FAIL) => 'Failed to close session.', ); use vars qw(@ISA @EXPORT $VERSION); @@ -1011,6 +1019,38 @@ sub removeVirtualTarget { return SCST_C_TGT_REM_FAIL if (!$io); + $self->enableTarget($driver, $target, FALSE); + + my $sessions = $self->sessions($driver, $target); + + my %can_close; + foreach my $session (keys %{$sessions}) { + if (defined($$sessions{$session}->{'force_close'})) { + $can_close{$session}++; + my $rc = $self->closeSession($driver, $target, $session); + return $rc if ($rc); + } + } + + if (scalar keys %can_close) { + my $has_sessions = 1; + my $now = time(); + while ($has_sessions && (($now + $TIMEOUT) > time())) { + $sessions = $self->sessions($driver, $target); + + foreach my $session (keys %can_close) { + if (!defined($$sessions{$session})) { + delete $can_close{$session}; + } + } + + $has_sessions = scalar keys %can_close; + sleep 1 if ($has_sessions); + } + + return SCST_C_TGT_BUSY if ($has_sessions); + } + my $cmd = "del_target $target\n"; my $bytes; @@ -1022,6 +1062,7 @@ sub removeVirtualTarget { close $io; + return SCST_C_TGT_BUSY if ($bytes == -1); return FALSE if ($self->{'debug'} || $bytes); return SCST_C_TGT_REM_FAIL; } @@ -3260,18 +3301,36 @@ sub sessions { $self->luns($driver, $target, $group); } } else { - my $io = new IO::File $pPath, O_RDONLY; + my $mode = (stat($pPath))[2]; + if (-d $pPath) { + # Skip directories + } else { + if (!(($mode & S_IRUSR) >> 6)) { + $_sessions{$session}->{$attribute}->{'static'} = FALSE; + $_sessions{$session}->{$attribute}->{'value'} = undef; + } else { + my $is_static; + if (($mode & S_IWUSR) >> 6) { + $is_static = FALSE; + } else { + $is_static = TRUE; + } - if (!$io) { - $self->{'err_string'} = "sessions(): Unable to read ". - "session attribute '$attribute': $!"; - return undef; + my $io = new IO::File $pPath, O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "sessions(): Unable to read ". + "session attribute '$attribute': $!"; + return undef; + } + + my $value = <$io>; + chomp $value; + + $_sessions{$session}->{$attribute}->{'value'} = $value; + $_sessions{$session}->{$attribute}->{'static'} = $is_static; + } } - - my $value = <$io>; - chomp $value; - - $_sessions{$session}->{$attribute} = $value; } } } @@ -3279,6 +3338,37 @@ sub sessions { return \%_sessions; } +sub closeSession { + my $self = shift; + my $driver = shift; + my $target = shift; + my $session = shift; + + my $sessions = $self->sessions($driver, $target); + + return SCST_C_NO_SESSION if (!defined($$sessions{$session})); + + # If it's not closable, silently return + return FALSE if (!defined($$sessions{$session}->{'force_close'})); + + my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_SESSIONS, $session, 'force_close'); + + my $io = new IO::File $path, O_WRONLY; + + my $cmd = "1"; + + my $bytes; + + if ($self->{'debug'}) { + print "DBG($$): $cmd\n"; + } else { + $bytes = _syswrite($io, $cmd, length($cmd)); + } + + return FALSE if ($self->{'debug'} || $bytes); + return SCST_C_SESSION_CLOSE_FAIL; +} + sub sgvStats { my $self = shift; my %stats; @@ -3391,6 +3481,8 @@ sub _syswrite { } close $res; + } elsif ($! == EBUSY) { + return -1; } } diff --git a/scstadmin/scstadmin.sysfs/scstadmin b/scstadmin/scstadmin.sysfs/scstadmin index 582ff8a27..1dd502171 100755 --- a/scstadmin/scstadmin.sysfs/scstadmin +++ b/scstadmin/scstadmin.sysfs/scstadmin @@ -2157,7 +2157,18 @@ sub clearConfiguration { } # Todo - check return code - # TODO: should we disable all target drivers as well? + + my $drivers = $SCST->drivers(); + + foreach my $driver (@{$drivers}) { + my $targets = $SCST->targets($driver); + + foreach my $target (@{$targets}) { + disableTarget($driver, $target); + } + + disableDriver($driver); + } print "\t-> Configuration cleared.\n"; } @@ -2399,7 +2410,7 @@ sub listSessions { $$sessions{$session}->{'luns'}->{$lun}; } } else { - $attributes{$attr}->{'value'} = $$sessions{$session}->{$attr}; + $attributes{$attr}->{'value'} = $$sessions{$session}->{$attr}->{'value'}; } } @@ -3860,6 +3871,26 @@ sub disableTarget { setTargetAttributes($driver, $target, \%attributes); } +sub enableDriver { + my $driver = shift; + my %attributes = ('enabled', 1); + + my $attrs = $SCST->driverAttributes($driver); + return if (!defined($$attrs{'enabled'})); + + setDriverAttributes($driver, \%attributes); +} + +sub disableDriver { + my $driver = shift; + my %attributes = ('enabled', 0); + + my $attrs = $SCST->driverAttributes($driver); + return if (!defined($$attrs{'enabled'})); + + setDriverAttributes($driver, \%attributes); +} + sub issueLip { my $driver = shift; my $target = shift;