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 27e33001e..eb6456341 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 @@ -5,6 +5,7 @@ package SCST::SCST; # Author: Mark R. Buechler # License: GPLv2 # Copyright (c) 2005-2010 Mark R. Buechler +# Copyright (c) 2011 Bart Van Assche . use 5.005; use Fcntl ':mode'; @@ -19,14 +20,26 @@ use constant { TRUE => 1, FALSE => 0, -SCST_ROOT => '/sys/kernel/scst_tgt', +SCST_ROOT_OLD => '/sys/kernel/scst_tgt', +SCST_ROOT_NEW => '/sys/devices/scst', # Root-level +SCST_SGV => 'sgv', +# Root level, old sysfs interface SCST_HANDLERS => 'handlers', SCST_DEVICES => 'devices', SCST_TARGETS => 'targets', -SCST_SGV => 'sgv', SCST_QUEUE_RES => 'last_sysfs_mgmt_res', +# Root level, new sysfs interface +IN_SCST_HANDLERS => 'device_driver', +IN_SCST_DEVICES => 'device', +IN_SCST_TARGETS => 'target_driver', +SCST_ADD_TGT => 'add_target', +SCST_ADD_TGT_PARAMS => 'add_target_parameters', +SCST_TGTT_ATTR => 'driver_attributes', +SCST_TGT_ATTR => 'target_attributes', +SCST_ADD_DEV_PARAMS => 'add_device_parameters', +SCST_PARAM_ATTR => 'parameters', # Target specific SCST_GROUPS => 'ini_groups', @@ -213,6 +226,49 @@ my $_SCST_MIN_MAJOR_ = 2; my $_SCST_MIN_MINOR_ = 0; my $_SCST_MIN_RELEASE_ = 0; +sub new_sysfs_interface { + return !(-d SCST_ROOT_OLD); +} + +sub SCST_ROOT_DIR { + return -d SCST_ROOT_OLD ? SCST_ROOT_OLD : SCST_ROOT_NEW; +} + +sub SCST_SGV_DIR { + return SCST_ROOT_DIR() . '/sgv' +} + +sub SCST_QUEUE_RES_PATH { + return -d SCST_ROOT_OLD ? SCST_ROOT_OLD . '/' . SCST_QUEUE_RES : undef; +} + +# Device handlers. +sub SCST_HANDLERS_DIR { + if (-d SCST_ROOT_OLD) { + return SCST_ROOT_OLD . '/' . SCST_HANDLERS; + } else { + return '/sys/bus/scst_tgt_dev/drivers'; + } +} + +# Device instances. +sub SCST_DEVICES_DIR { + if (-d SCST_ROOT_OLD) { + return SCST_ROOT_OLD . '/' . SCST_DEVICES; + } else { + return '/sys/bus/scst_tgt_dev/devices'; + } +} + +# Target drivers. +sub SCST_TARGETS_DIR { + if (-d SCST_ROOT_OLD) { + return SCST_ROOT_OLD . '/' . SCST_TARGETS; + } else { + return '/sys/bus/scst_target/drivers'; + } +} + sub new { my $this = shift; my $debug = shift; @@ -258,15 +314,16 @@ sub scstAttributes { my %attributes; my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT); + my $_path = SCST_ROOT_DIR(); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "scstAttributes(): Unable to read directory '$_path': $!"; return undef; } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, $attribute); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); + my $pPath = mkpath(SCST_ROOT_DIR(), $attribute); my $mode = (stat($pPath))[2]; if (-d $pPath) { @@ -353,7 +410,7 @@ sub setScstAttribute { return SCST_C_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, $attribute); + my $path = mkpath(SCST_ROOT_DIR(), $attribute); my $io = new IO::File $path, O_WRONLY; @@ -378,7 +435,7 @@ sub drivers { my @drivers; my $dHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS); + my $_path = SCST_TARGETS_DIR(); if (!(opendir $dHandle, $_path)) { $self->{'err_string'} = "drivers(): Unable to read directory '$_path': $!"; return undef; @@ -387,7 +444,7 @@ sub drivers { foreach my $driver (readdir($dHandle)) { next if (($driver eq '.') || ($driver eq '..')); - if (-d mkpath(SCST_ROOT, SCST_TARGETS, $driver)) { + if (-d mkpath(SCST_TARGETS_DIR(), $driver)) { push @drivers, $driver; } } @@ -409,16 +466,17 @@ sub targets { } my $tHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver); if (!(opendir $tHandle, $_path)) { $self->{'err_string'} = "targets(): Unable to read directory '$_path': $!"; return undef; } foreach my $target (readdir($tHandle)) { - next if (($target eq '.') || ($target eq '..')); + next if ($target eq '.' || $target eq '..' || + $target eq 'module'); - if (-d mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target)) { + if (-d mkpath(SCST_TARGETS_DIR(), $driver, $target)) { push @targets, $target; } } @@ -445,7 +503,7 @@ sub groups { } my $gHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS); if (!(opendir $gHandle, $_path)) { $self->{'err_string'} = "groups(): Unable to read directory '$_path': $!"; return undef; @@ -454,7 +512,7 @@ sub groups { foreach my $group (readdir($gHandle)) { next if (($group eq '.') || ($group eq '..')); - if (-d mkpath(SCST_ROOT, SCST_TARGETS, $driver, + if (-d mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group)) { push @groups, $group; } @@ -488,7 +546,7 @@ sub initiators { } my $iHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_INITIATORS); if (!(opendir $iHandle, $_path)) { $self->{'err_string'} = "initiators(): Unable to read directory '$_path': $!"; @@ -532,10 +590,10 @@ sub luns { return undef; } - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_LUNS); } else { - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS); + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_LUNS); } my $lHandle = new IO::Handle; @@ -563,12 +621,8 @@ sub luns { if (-l $pPath) { my $linked = readlink($pPath); - - my $d = SCST_DEVICES; - - if ($linked =~ /.*\/$d\/(.*)/) { - $luns{$lun} = $1; - } + $linked =~ s/.*\///; + $luns{$lun} = $linked; } } } @@ -606,26 +660,38 @@ sub driverDynamicAttributes { return undef; } - my $io = new IO::File mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO), O_RDONLY; - - if (!$io) { - $self->{'err_string'} = "driverDynamicAttributes(): Unable to open mgmt ". - "interface for driver '$driver': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following target driver attributes available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; + if (new_sysfs_interface()) { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_TGTT_ATTR), O_RDONLY; + if ($io) { + while (my $attribute = <$io>) { + chomp($attribute); + $attributes{$attribute} = ''; + } } - } + } else { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_MGMT_IO), O_RDONLY; - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; - $attributes{$attribute} = ''; + if (!$io) { + $self->{'err_string'} = "driverDynamicAttributes(): Unable to open mgmt ". + "interface for driver '$driver': $!"; + return undef; + } + + while (my $in = <$io>) { + if ($in =~ /^The following target driver attributes available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } + + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } } } @@ -678,13 +744,19 @@ sub addDriverDynamicAttribute { return SCST_C_DRV_BAD_ATTRIBUTES if ($rc == 1); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "add_attribute $attribute $value"; my $io = new IO::File $path, O_WRONLY; return SCST_C_DRV_ADDATTR_FAIL if (!$io); - my $cmd = "add_attribute $attribute $value\n"; my $bytes; if ($self->{'debug'}) { @@ -716,13 +788,19 @@ sub removeDriverDynamicAttribute { return SCST_C_DRV_BAD_ATTRIBUTES if ($rc == 1); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "del_attribute $attribute $value"; my $io = new IO::File $path, O_WRONLY; return SCST_C_DRV_REMATTR_FAIL if (!$io); - my $cmd = "del_attribute $attribute $value\n"; my $bytes; if ($self->{'debug'}) { @@ -768,12 +846,19 @@ sub driverIsVirtualCapable { return SCST_C_DRV_NO_DRIVER if (!$rc); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); - - my $io = new IO::File $path, O_WRONLY; - - return FALSE if (!defined($io)); - return TRUE; + if (new_sysfs_interface()) { + my $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_ADD_TGT); + my $io = new IO::File $path, O_RDONLY; + if ($io) { + my $line = <$io>; + chomp($line); + return $line eq '1'; + } + return FALSE; + } else { + my $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + return (-w $path) ? TRUE : FALSE; + } } sub targetType { @@ -815,12 +900,6 @@ sub addVirtualTarget { return SCST_C_TGT_BAD_ATTRIBUTES if ($rc == TRUE); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); - - my $io = new IO::File $path, O_WRONLY; - - return SCST_C_TGT_ADD_FAIL if (!$io); - my $o_string; foreach my $attribute (keys %{$attributes}) { if (ref($$attributes{$attribute}) eq 'ARRAY') { @@ -834,7 +913,20 @@ sub addVirtualTarget { } $o_string =~ s/\s$//; - my $cmd = "add_target $target $o_string\n"; + + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "add_target $target $o_string"; + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGT_ADD_FAIL if (!$io); + my $bytes; if ($self->{'debug'}) { @@ -861,26 +953,38 @@ sub targetDynamicAttributes { return undef; } - my $io = new IO::File mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO), O_RDONLY; - - if (!$io) { - $self->{'err_string'} = "targetDynamicAttributes(): Unable to open mgmt ". - "interface for driver '$driver': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following target attributes available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; + if (new_sysfs_interface()) { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_TGT_ATTR), O_RDONLY; + if ($io) { + while (my $attribute = <$io>) { + chomp($attribute); + $attributes{$attribute} = ''; + } } - } + } else { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_MGMT_IO), O_RDONLY; - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; - $attributes{$attribute} = ''; + if (!$io) { + $self->{'err_string'} = "targetDynamicAttributes(): Unable to open mgmt ". + "interface for driver '$driver': $!"; + return undef; + } + + while (my $in = <$io>) { + if ($in =~ /^The following target attributes available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } + + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } } } @@ -938,13 +1042,19 @@ sub addTargetDynamicAttribute { return SCST_C_TGT_BAD_ATTRIBUTES if ($rc == 1); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "add_target_attribute $target $attribute $value"; my $io = new IO::File $path, O_WRONLY; return SCST_C_TGT_ADDATTR_FAIL if (!$io); - my $cmd = "add_target_attribute $target $attribute $value\n"; my $bytes; if ($self->{'debug'}) { @@ -980,13 +1090,19 @@ sub removeTargetDynamicAttribute { return SCST_C_TGT_BAD_ATTRIBUTES if ($rc == 1); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver"; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "del_target_attribute $target $attribute $value"; my $io = new IO::File $path, O_WRONLY; return SCST_C_TGT_REMATTR_FAIL if (!$io); - my $cmd = "del_target_attribute $target $attribute $value\n"; my $bytes; if ($self->{'debug'}) { @@ -1016,12 +1132,6 @@ sub removeVirtualTarget { return SCST_C_DRV_NOTVIRT if (!$self->driverIsVirtualCapable($driver)); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO); - - my $io = new IO::File $path, O_WRONLY; - - return SCST_C_TGT_REM_FAIL if (!$io); - $self->enableTarget($driver, $target, FALSE); my $sessions = $self->sessions($driver, $target); @@ -1054,7 +1164,19 @@ sub removeVirtualTarget { return SCST_C_TGT_BUSY if ($has_sessions); } - my $cmd = "del_target $target\n"; + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, SCST_MGMT_IO); + } + $cmd .= "del_target $target"; + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_TGT_REM_FAIL if (!$io); + my $bytes; if ($self->{'debug'}) { @@ -1172,14 +1294,21 @@ sub addGroup { return SCST_C_GRP_EXISTS if ($rc == TRUE); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, - SCST_GROUPS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, SCST_MGMT_IO); + } + $cmd .= "create $group"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_ADD_FAIL if (!$io); - my $cmd = "create $group\n"; my $bytes; if ($self->{'debug'}) { @@ -1212,14 +1341,21 @@ sub removeGroup { return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, - SCST_GROUPS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, SCST_MGMT_IO); + } + $cmd .= "del $group"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_REM_FAIL if (!$io); - my $cmd = "del $group\n"; my $bytes; if ($self->{'debug'}) { @@ -1257,14 +1393,22 @@ sub addInitiator { return SCST_C_GRP_INI_EXISTS if ($rc == TRUE); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_INITIATORS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_INITIATORS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_INITIATORS, + SCST_MGMT_IO); + } + $cmd .= "add $initiator"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_ADD_INI_FAIL if (!$io); - my $cmd = "add $initiator\n"; my $bytes; if ($self->{'debug'}) { @@ -1302,14 +1446,22 @@ sub removeInitiator { return SCST_C_GRP_NO_INI if (!$rc); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_INITIATORS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_INITIATORS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_INITIATORS, + SCST_MGMT_IO); + } + $cmd .= "del $initiator"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_REM_INI_FAIL if (!$io); - my $cmd = "del $initiator\n"; my $bytes; if ($self->{'debug'}) { @@ -1356,14 +1508,22 @@ sub moveInitiator { return SCST_C_GRP_INI_EXISTS if ($rc == TRUE); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $from, SCST_INITIATORS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$from/" . SCST_INITIATORS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $from, SCST_INITIATORS, + SCST_MGMT_IO); + } + $cmd .= "move $initiator $to"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_MOV_INI_FAIL if (!$io); - my $cmd = "move $initiator $to\n"; my $bytes; if ($self->{'debug'}) { @@ -1396,14 +1556,22 @@ sub clearInitiators { return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_INITIATORS, SCST_MGMT_IO); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_INITIATORS . " "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_INITIATORS, + SCST_MGMT_IO); + } + $cmd .= "clear"; my $io = new IO::File $path, O_WRONLY; return SCST_C_GRP_CLR_INI_FAIL if (!$io); - my $cmd = "clear\n"; my $bytes; if ($self->{'debug'}) { @@ -1427,8 +1595,8 @@ sub addLun { my $attributes = shift; my $group = shift; - my $err = SCST_C_TGT_ADD_LUN_FAIL; - my $err2 = SCST_C_TGT_LUN_EXISTS; + my $err; + my $err2; my $rc = $self->driverExists($driver); return SCST_C_DRV_NO_DRIVER if (!$rc); @@ -1446,8 +1614,6 @@ sub addLun { return SCST_C_LUN_BAD_ATTRIBUTES if ($rc == TRUE); return $rc if ($rc > 1); - my $path; - if ($group) { $rc = $self->groupExists($driver, $target, $group); return SCST_C_GRP_NO_GROUP if (!$rc); @@ -1456,10 +1622,9 @@ sub addLun { $err = SCST_C_GRP_ADD_LUN_FAIL; $err2 = SCST_C_GRP_LUN_EXISTS; - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_LUNS, SCST_MGMT_IO); } else { - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, SCST_MGMT_IO); + $err = SCST_C_TGT_ADD_LUN_FAIL; + $err2 = SCST_C_TGT_LUN_EXISTS; } return $err if (!defined($lun)); @@ -1468,10 +1633,6 @@ sub addLun { return $err2 if ($rc == TRUE); return $rc if ($rc > 1); - my $io = new IO::File $path, O_WRONLY; - - return $err if (!$io); - my $o_string; foreach my $attribute (keys %{$attributes}) { my $value = $$attributes{$attribute}; @@ -1479,7 +1640,32 @@ sub addLun { } $o_string =~ s/\s$//; - my $cmd = "add $device $lun $o_string\n"; + + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + if ($group) { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_LUNS . " "; + } else { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_LUNS . " "; + } + } else { + if ($group) { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_MGMT_IO); + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_MGMT_IO); + } + } + $cmd .= "add $device $lun $o_string"; + + my $io = new IO::File $path, O_WRONLY; + + return $err if (!$io); my $bytes; @@ -1502,8 +1688,8 @@ sub removeLun { my $lun = shift; my $group = shift; - my $err = SCST_C_TGT_ADD_LUN_FAIL; - my $err2 = SCST_C_TGT_NO_LUN; + my $err; + my $err2; my $rc = $self->driverExists($driver); return SCST_C_DRV_NO_DRIVER if (!$rc); @@ -1513,8 +1699,6 @@ sub removeLun { return SCST_C_TGT_NO_TARGET if (!$rc); return $rc if ($rc > 1); - my $path; - if ($group) { $rc = $self->groupExists($driver, $target, $group); return SCST_C_GRP_NO_GROUP if (!$rc); @@ -1522,11 +1706,9 @@ sub removeLun { $err = SCST_C_GRP_REM_LUN_FAIL; $err2 = SCST_C_GRP_NO_LUN; - - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_LUNS, SCST_MGMT_IO); } else { - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, SCST_MGMT_IO); + $err = SCST_C_TGT_ADD_LUN_FAIL; + $err2 = SCST_C_TGT_NO_LUN; } return $err if (!defined($lun)); @@ -1535,11 +1717,32 @@ sub removeLun { return $err2 if (!$rc); return $rc if ($rc > 1); + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + if ($group) { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_LUNS . " "; + } else { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_LUNS . " "; + } + } else { + if ($group) { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_MGMT_IO); + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_MGMT_IO); + } + } + $cmd .= "del $lun"; + my $io = new IO::File $path, O_WRONLY; return $err if (!$io); - my $cmd = "del $lun\n"; my $bytes; if ($self->{'debug'}) { @@ -1563,7 +1766,7 @@ sub replaceLun { my $attributes = shift; my $group = shift; - my $err = SCST_C_TGT_NO_LUN; + my $err; return TRUE if (!defined($lun)); @@ -1575,19 +1778,14 @@ sub replaceLun { return SCST_C_TGT_NO_TARGET if (!$rc); return $rc if ($rc > 1); - my $path; - if ($group) { $rc = $self->groupExists($driver, $target, $group); return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); $err = SCST_C_GRP_NO_LUN; - - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_LUNS, SCST_MGMT_IO); } else { - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, SCST_MGMT_IO); + $err = SCST_C_TGT_NO_LUN; } $rc = $self->lunExists($driver, $target, $lun, $group); @@ -1606,10 +1804,6 @@ sub replaceLun { return SCST_C_LUN_DEV_EXISTS if ($$luns{$lun} eq $device); - my $io = new IO::File $path, O_WRONLY; - - return SCST_C_LUN_RPL_DEV_FAIL if (!$io); - my $o_string; foreach my $attribute (keys %{$attributes}) { my $value = $$attributes{$attribute}; @@ -1617,7 +1811,33 @@ sub replaceLun { } $o_string =~ s/\s$//; - my $cmd = "replace $device $lun $o_string\n"; + + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + if ($group) { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_LUNS . " "; + } else { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_LUNS . " "; + } + } else { + if ($group) { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_MGMT_IO); + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_MGMT_IO); + } + } + $cmd .= "replace $device $lun $o_string"; + + my $io = new IO::File $path, O_WRONLY; + + return SCST_C_LUN_RPL_DEV_FAIL if (!$io); + my $bytes; if ($self->{'debug'}) { @@ -1638,7 +1858,7 @@ sub clearLuns { my $target = shift; my $group = shift; - my $err = SCST_C_TGT_CLR_LUN_FAIL; + my $err; my $rc = $self->driverExists($driver); return SCST_C_DRV_NO_DRIVER if (!$rc); @@ -1648,26 +1868,42 @@ sub clearLuns { return SCST_C_TGT_NO_TARGET if (!$rc); return $rc if ($rc > 1); - my $path; - if ($group) { $rc = $self->groupExists($driver, $target, $group); return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); $err = SCST_C_GRP_CLR_LUN_FAIL; - - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, SCST_LUNS, SCST_MGMT_IO); } else { - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, SCST_MGMT_IO); + $err = SCST_C_TGT_CLR_LUN_FAIL } + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + if ($group) { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group/" . SCST_LUNS . " "; + } else { + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_LUNS . " "; + } + } else { + if ($group) { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_MGMT_IO); + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_MGMT_IO); + } + } + $cmd .= "clear"; + my $io = new IO::File $path, O_WRONLY; return $err if (!$io); - my $cmd = "clear\n"; my $bytes; if ($self->{'debug'}) { @@ -1687,17 +1923,28 @@ sub devices { my @devices; my $dHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_DEVICES); + my $_path = SCST_DEVICES_DIR(); if (!(opendir $dHandle, $_path)) { $self->{'err_string'} = "devices(): Unable to read directory '$_path': $!"; return undef; } - foreach my $device (readdir($dHandle)) { - next if (($device eq '.') || ($device eq '..')); + if (new_sysfs_interface()) { + foreach my $device (readdir($dHandle)) { + my $link = readlink(mkpath(SCST_DEVICES_DIR(), + $device)); + $link =~ s/.*\///; + if ($link) { + push @devices, $link; + } + } + } else { + foreach my $device (readdir($dHandle)) { + next if (($device eq '.') || ($device eq '..')); - if (-d mkpath(SCST_ROOT, SCST_DEVICES, $device)) { - push @devices, $device; + if (-d mkpath(SCST_DEVICES_DIR(), $device)) { + push @devices, $device; + } } } @@ -1734,20 +1981,21 @@ sub deviceAttributes { } my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_DEVICES, $device); + my $_path = mkpath(SCST_DEVICES_DIR(), $device); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "deviceAttributes(): Unable to read directory '$_path': $!"; return undef; } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, SCST_DEVICES, $device, $attribute); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO || $attribute eq 'uevent'); + my $pPath = mkpath(SCST_DEVICES_DIR(), $device, $attribute); my $mode = (stat($pPath))[2]; if ($attribute eq 'exported') { my $eHandle = new IO::Handle; - opendir $eHandle, mkpath(SCST_ROOT, SCST_DEVICES, + opendir $eHandle, mkpath(SCST_DEVICES_DIR(), $device, $attribute); foreach my $export (readdir($eHandle)) { @@ -1755,11 +2003,10 @@ sub deviceAttributes { my $linked = readlink mkpath($pPath, $export); - my $t = SCST_TARGETS; my $g = SCST_GROUPS; my $l = SCST_LUNS; - if ($linked =~ /\.\.\/\.\.\/$t\/(.+)\/(.+)\/$g\/(.+)\/$l\/(\d+)/) { + if ($linked =~ /.*\/(.+)\/(.+)\/$g\/(.+)\/$l\/(\d+)/) { my $driver = $1; my $target = $2; my $group = $3; @@ -1773,18 +2020,13 @@ sub deviceAttributes { } elsif ($attribute eq 'handler') { my $linked = readlink $pPath; - my $h = SCST_HANDLERS; - - if ($linked =~ /\.\.\/\.\.\/$h\/(.*)/) { - my $handler = $1; - $attributes{$attribute}->{'static'} = TRUE; - $attributes{$attribute}->{'value'} = $handler; - } + $linked =~ s/.*\///; + $attributes{$attribute}->{'static'} = TRUE; + $attributes{$attribute}->{'value'} = $linked; } elsif ($attribute eq 'scsi_device') { my $linked = readlink $pPath; - $linked =~ s/^\.\.\/\.\.\/\.\.\/\.\.\//\/sys\//; - + $linked =~ s/.*\///; $attributes{$attribute}->{'static'} = TRUE; $attributes{$attribute}->{'value'} = $linked; } else { @@ -1793,7 +2035,11 @@ sub deviceAttributes { $attributes{$attribute}->{'value'} = undef; } else { my $is_static; - if (($mode & S_IWUSR) >> 6) { + if ($attribute eq 'cpu_mask' || + $attribute eq 'filename' || + $attribute eq 'threads_num' || + $attribute eq 'threads_pool_type' || + ($mode & S_IWUSR) >> 6) { $is_static = FALSE; } else { $is_static = TRUE; @@ -1855,15 +2101,16 @@ sub driverAttributes { } my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "driverAttributes(): Unable to read directory '$_path': $!"; return undef; } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $attribute); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); + my $pPath = mkpath(SCST_TARGETS_DIR(), $driver, $attribute); my $mode = (stat($pPath))[2]; if (-d $pPath) { @@ -1957,7 +2204,7 @@ sub setDriverAttribute { return SCST_C_DRV_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_DRV_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $attribute); + my $path = mkpath(SCST_TARGETS_DIR(), $driver, $attribute); my $io = new IO::File $path, O_WRONLY; @@ -1994,22 +2241,22 @@ sub targetAttributes { } my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "targetAttributes(): Unable to read directory '$_path': $!"; return undef; } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, $attribute); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO || $attribute eq 'uevent'); + my $pPath = mkpath(SCST_TARGETS_DIR(), $driver, $target, $attribute); my $mode = (stat($pPath))[2]; if ($attribute eq 'host') { my $linked = readlink($pPath); - $linked =~ s/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\//\/sys\//; - + $linked =~ s/.*\///; $attributes{$attribute}->{'static'} = TRUE; $attributes{$attribute}->{'value'} = $linked; } elsif (-d $pPath) { @@ -2020,7 +2267,9 @@ sub targetAttributes { $attributes{$attribute}->{'value'} = undef; } else { my $is_static; - if (($mode & S_IWUSR) >> 6) { + if ($attribute eq 'enabled' || + $attribute eq 'cpu_mask' || + ($mode & S_IWUSR) >> 6) { $is_static = FALSE; } else { $is_static = TRUE; @@ -2086,7 +2335,19 @@ sub setTargetAttribute { return SCST_C_TGT_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_TGT_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, $attribute); + my ($path, $cmd); + if (new_sysfs_interface() && + ($attribute eq 'enabled' || $attribute eq 'cpu_mask')) { + $path = mkpath(SCST_ROOT_DIR, SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target " . + ($attribute eq 'enabled' ? + ($value eq '1' ? 'enable' : 'disable') : + "set_$attribute $value"); + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + $attribute); + $cmd = $value; + } my $io = new IO::File $path, O_WRONLY; @@ -2095,9 +2356,9 @@ sub setTargetAttribute { my $bytes; if ($self->{'debug'}) { - print "DBG($$): $path -> $attribute = $value\n"; + print "DBG($$): $cmd > $path\n"; } else { - $bytes = _syswrite($io, $value, length($value)); + $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; @@ -2129,15 +2390,16 @@ sub groupAttributes { } my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, $group); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "groupAttributes(): Unable to read directory '$_path': $!"; return undef; } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); + my $pPath = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, $attribute); my $mode = (stat($pPath))[2]; @@ -2149,7 +2411,8 @@ sub groupAttributes { $attributes{$attribute}->{'value'} = undef; } else { my $is_static; - if (($mode & S_IWUSR) >> 6) { + if ($attribute eq 'cpu_mask' || + ($mode & S_IWUSR) >> 6) { $is_static = FALSE; } else { $is_static = TRUE; @@ -2220,8 +2483,16 @@ sub setGroupAttribute { return SCST_C_GRP_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_GRP_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, - $group, $attribute); + my ($path, $cmd); + if (new_sysfs_interface() && $attribute eq 'cpu_mask') { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_TARGETS . "/$driver/$target/" . + SCST_GROUPS . "/$group set_$attribute "; + } else { + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, $attribute); + } + $cmd .= $value; my $io = new IO::File $path, O_WRONLY; @@ -2230,7 +2501,7 @@ sub setGroupAttribute { my $bytes; if ($self->{'debug'}) { - print "DBG($$): $path -> $attribute = $value\n"; + print "DBG($$): $cmd > $path\n"; } else { $bytes = _syswrite($io, $value, length($value)); } @@ -2267,10 +2538,10 @@ sub lunAttributes { return undef; } - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_LUNS, $lun); } else { - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, $lun); + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_LUNS, $lun); } if ($self->lunExists($driver, $target, $lun, $group) != TRUE) { @@ -2285,19 +2556,15 @@ sub lunAttributes { } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); my $pPath = mkpath($_path, $attribute); my $mode = (stat($pPath))[2]; if ($attribute eq 'device') { my $linked = readlink($pPath); - my $r = SCST_ROOT; - - $linked =~ s/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\//\/$r\//; - $linked =~ s/\.\.\/\.\.\/\.\.\/\.\.\/\.\.\//\/$r\//; - $linked =~ s/^\/+/\//; - + $linked =~ s/.*\///; $attributes{$attribute}->{'static'} = TRUE; $attributes{$attribute}->{'value'} = $linked; } elsif (-d $pPath) { @@ -2376,10 +2643,10 @@ sub setLunAttribute { return SCST_C_GRP_NO_GROUP if (!$rc); return $rc if ($rc > 1); - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_LUNS, $lun, $attribute); } else { - $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_LUNS, $lun, $attribute); + $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_LUNS, $lun, $attribute); } $rc = $self->lunExists($driver, $target, $lun, $group); @@ -2440,7 +2707,7 @@ sub initiatorAttributes { } my $pHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_INITIATORS, $initiator); if (!(opendir $pHandle, $_path)) { $self->{'err_string'} = "initiatorAttributes(): Unable to read directory '$_path': $!"; @@ -2448,8 +2715,9 @@ sub initiatorAttributes { } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - my $pPath = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); + my $pPath = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_INITIATORS, $initiator, $attribute); my $mode = (stat($pPath))[2]; if (-d $pPath) { @@ -2536,7 +2804,7 @@ sub setInitiatorAttribute { return SCST_C_INI_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_INI_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_GROUPS, + my $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_GROUPS, $group, SCST_LUNS, $initiator, $attribute); my $io = new IO::File $path, O_WRONLY; @@ -2562,7 +2830,7 @@ sub handlers { my @handlers; my $hHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_HANDLERS); + my $_path = SCST_HANDLERS_DIR(); if (!(opendir $hHandle, $_path)) { $self->{'err_string'} = "handlers(): Unable to read directory '$_path': $!"; return undef; @@ -2571,7 +2839,7 @@ sub handlers { foreach my $handler (readdir($hHandle)) { next if (($handler eq '.') || ($handler eq '..')); - if (-d mkpath(SCST_ROOT, SCST_HANDLERS, $handler)) { + if (-d mkpath(SCST_HANDLERS_DIR(), $handler)) { push @handlers, $handler; } } @@ -2615,7 +2883,7 @@ sub setHandlerAttribute { return SCST_C_HND_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_HND_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_HANDLERS, $handler, $attribute); + my $path = mkpath(SCST_HANDLERS_DIR(), $handler, $attribute); my $io = new IO::File $path, O_WRONLY; @@ -2646,22 +2914,46 @@ sub handlerAttributes { } my $hHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_HANDLERS, $handler); + my $_path = mkpath(SCST_HANDLERS_DIR(), $handler); if (!(opendir $hHandle, $_path)) { $self->{'err_string'} = "handlerAttributes(): Unable to read directory '$_path': $!"; return undef; } - foreach my $attribute (readdir($hHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); - next if ($attribute eq SCST_MGMT_IO); - my $pPath = mkpath(SCST_ROOT, SCST_HANDLERS, $handler, $attribute); - my $mode = (stat($pPath))[2]; - - if (-d $pPath) { - push @{$attributes{'devices'}->{'value'}}, $attribute; - next; + if (new_sysfs_interface()) { + $_path = SCST_DEVICES_DIR(); + if (!opendir($hHandle, $_path)) { + $self->{'err_string'} = "handlerAttributes(): Unable". + " to read directory '$_path': $!"; + return undef; } + foreach my $dev (readdir($hHandle)) { + next if ($dev eq '.' || $dev eq '..'); + + my $driver = readlink("$_path/$dev/driver"); + $driver =~ s/.*\///; + if ($driver eq $handler) { + push @{$attributes{'devices'}->{'value'}}, $dev; + } + } + } else { + foreach my $attribute (readdir($hHandle)) { + next if ($attribute eq '.' || $attribute eq '..'); + + my $pPath = mkpath($_path, $attribute); + if (-d $pPath) { + push @{$attributes{'devices'}->{'value'}}, + $attribute; + } + } + } + + foreach my $attribute (readdir($hHandle)) { + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO || $attribute eq 'uevent' || + $attribute eq 'module'); + my $pPath = mkpath(SCST_HANDLERS_DIR(), $handler, $attribute); + my $mode = (stat($pPath))[2]; my $is_static; if (($mode & S_IWUSR) >> 6) { @@ -2670,7 +2962,7 @@ sub handlerAttributes { $is_static = TRUE; } - my $path = mkpath(SCST_ROOT, SCST_HANDLERS, $handler, $attribute); + my $path = mkpath(SCST_HANDLERS_DIR(), $handler, $attribute); my $io = new IO::File $path, O_RDONLY; @@ -2820,27 +3112,37 @@ sub deviceCreateAttributes { return undef; } - my $io = new IO::File mkpath(SCST_ROOT, SCST_HANDLERS, $handler, SCST_MGMT_IO), O_RDONLY; + if (new_sysfs_interface()) { + my $io = new IO::File mkpath(SCST_HANDLERS_DIR(), $handler, + SCST_ADD_DEV_PARAMS), O_RDONLY; - if (!$io) { - $self->{'err_string'} = "deviceCreateAttributes(): Unable to open mgmt ". - "interface for handler '$handler': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following parameters available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; - } - } - - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; + while (my $attribute = <$io>) { + chomp($attribute); $attributes{$attribute} = ''; } + } else { + my $io = new IO::File mkpath(SCST_HANDLERS_DIR(), $handler, SCST_MGMT_IO), O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "deviceCreateAttributes(): Unable to open mgmt ". + "interface for handler '$handler': $!"; + return undef; + } + + while (my $in = <$io>) { + if ($in =~ /^The following parameters available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } + + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } + } } return \%attributes; @@ -2860,14 +3162,6 @@ sub openDevice { return SCST_C_DEV_BAD_ATTRIBUTES if ($rc == TRUE); return $rc if ($rc > 1); - my $io = new IO::File mkpath(SCST_ROOT, SCST_HANDLERS, $handler, SCST_MGMT_IO), O_WRONLY; - - if (!$io) { - $self->{'err_string'} = "openDevice(): Unable to open mgmt interface for ". - "handler '$handler': $!"; - return SCST_C_FATAL_ERROR; - } - $rc = $self->handlerDeviceExists($handler, $device); return SCST_C_DEV_EXISTS if ($rc == TRUE); return $rc if ($rc > 1); @@ -2879,7 +3173,23 @@ sub openDevice { } $o_string =~ s/\s$//; - my $cmd = "add_device $device $o_string\n"; + + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_HANDLERS . "/$handler "; + } else { + $path = mkpath(SCST_HANDLERS_DIR(), $handler, SCST_MGMT_IO); + } + $cmd .= "add_device $device $o_string"; + + my $io = new IO::File $path, O_WRONLY; + + if (!$io) { + $self->{'err_string'} = "openDevice(): Unable to open mgmt interface for ". + "handler '$handler': $!"; + return SCST_C_FATAL_ERROR; + } my $bytes; @@ -2902,7 +3212,20 @@ sub closeDevice { return SCST_C_HND_NO_HANDLER if (!$rc); return $rc if ($rc > 1); - my $io = new IO::File mkpath(SCST_ROOT, SCST_HANDLERS, $handler, SCST_MGMT_IO), O_WRONLY; + $rc = $self->handlerDeviceExists($handler, $device); + return SCST_C_DEV_NO_DEVICE if ($rc != TRUE); + return $rc if ($rc > 1); + + my ($path, $cmd); + if (new_sysfs_interface()) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_HANDLERS . "/$handler "; + } else { + $path = mkpath(SCST_HANDLERS_DIR(), $handler, SCST_MGMT_IO); + } + $cmd .= "del_device $device"; + + my $io = new IO::File $path, O_WRONLY; if (!$io) { $self->{'err_string'} = "closeDevice(): Unable to open mgmt interface for handler ". @@ -2910,12 +3233,6 @@ sub closeDevice { return SCST_C_FATAL_ERROR; } - $rc = $self->handlerDeviceExists($handler, $device); - return SCST_C_DEV_NO_DEVICE if ($rc != TRUE); - return $rc if ($rc > 1); - - my $cmd = "del_device $device\n"; - my $bytes; if ($self->{'debug'}) { @@ -2945,7 +3262,17 @@ sub setDeviceAttribute { return SCST_C_DEV_BAD_ATTRIBUTES if (!defined($$attributes{$attribute})); return SCST_C_DEV_ATTRIBUTE_STATIC if ($$attributes{$attribute}->{'static'}); - my $path = mkpath(SCST_ROOT, SCST_DEVICES, $device, $attribute); + my ($path, $cmd); + if (new_sysfs_interface() && + ($attribute eq 'filename' || + $attribute eq 'threads_num' || + $attribute eq 'threads_pool_type')) { + $path = mkpath(SCST_ROOT_DIR(), SCST_MGMT_IO); + $cmd = "in " . IN_SCST_DEVICES . "/$device set_$attribute "; + } else { + $path = mkpath(SCST_DEVICES_DIR(), $device, $attribute); + } + $cmd .= $value; my $io = new IO::File $path, O_WRONLY; @@ -2954,9 +3281,9 @@ sub setDeviceAttribute { my $bytes; if ($self->{'debug'}) { - print "DBG($$): $path -> $attribute = $value\n"; + print "DBG($$): $cmd > $path\n"; } else { - $bytes = _syswrite($io, $value, length($value)); + $bytes = _syswrite($io, $cmd, length($cmd)); } close $io; @@ -3007,27 +3334,37 @@ sub targetCreateAttributes { return undef; } - my $io = new IO::File mkpath(SCST_ROOT, SCST_TARGETS, $driver, SCST_MGMT_IO), O_RDONLY; - - if (!$io) { - $self->{'err_string'} = "targetCreateAttributes(): Unable to open driver mgmt ". - "interface for driver '$driver': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following parameters available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; - } - } - - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; + if (new_sysfs_interface()) { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_ADD_TGT_PARAMS), O_RDONLY; + while (my $attribute = <$io>) { + chomp($attribute); $attributes{$attribute} = ''; } + } else { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + SCST_MGMT_IO), O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "targetCreateAttributes(): Unable to open driver mgmt ". + "interface for driver '$driver': $!"; + return undef; + } + + while (my $in = <$io>) { + if ($in =~ /^The following parameters available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } + + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } + } } return \%attributes; @@ -3123,43 +3460,66 @@ sub lunCreateAttributes { my $_path; - if ($group) { - if ($self->groupExists($driver, $target, $group) != TRUE) { - $self->{'err_string'} = "lunCreateAttributes(): Group '$group' ". - "does not exist"; + if (new_sysfs_interface()) { + if ($group) { + if ($self->groupExists($driver, $target, $group) != TRUE) { + $self->{'err_string'} = "lunCreateAttributes(): Group '$group' ". + "does not exist"; + return undef; + } + + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_PARAM_ATTR); + } else { + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_PARAM_ATTR); + } + + my $io = new IO::File $_path, O_RDONLY; + while (my $attribute = <$io>) { + chomp($attribute); + $attributes{$attribute} = ''; + } + } else { + if ($group) { + if ($self->groupExists($driver, $target, $group) != TRUE) { + $self->{'err_string'} = "lunCreateAttributes(): Group '$group' ". + "does not exist"; + return undef; + } + + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_GROUPS, $group, SCST_LUNS, + SCST_MGMT_IO); + } else { + $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, + SCST_LUNS, SCST_MGMT_IO); + } + + my $io = new IO::File $_path, O_RDONLY; + + if (!$io) { + $self->{'err_string'} = "lunCreateAttributes(): Unable to open luns mgmt ". + "interface for group '$group': $!"; return undef; } - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, - SCST_GROUPS, $group, SCST_LUNS, SCST_MGMT_IO), O_RDONLY; - } else { - $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, - SCST_LUNS, SCST_MGMT_IO), O_RDONLY; - } + while (my $in = <$io>) { + if ($in =~ /^The following parameters available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } - my $io = new IO::File $_path; - - if (!$io) { - $self->{'err_string'} = "lunCreateAttributes(): Unable to open luns mgmt ". - "interface for group '$group': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following parameters available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } } } - - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; - $attributes{$attribute} = ''; - } - } - return \%attributes; } @@ -3229,27 +3589,33 @@ sub initiatorCreateAttributes { return undef; } - my $io = new IO::File mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, - SCST_GROUPS, $group, SCST_INITIATORS, SCST_MGMT_IO), O_RDONLY; + if (new_sysfs_interface()) { + # Do nothing - there are no initiator attributes (yet). + } else { + my $io = new IO::File mkpath(SCST_TARGETS_DIR(), $driver, + $target, SCST_GROUPS, $group, + SCST_INITIATORS, SCST_MGMT_IO), + O_RDONLY; - if (!$io) { - $self->{'err_string'} = "initiatorCreateAttributes(): Unable to open initiators mgmt ". - "interface for group '$group': $!"; - return undef; - } - - while (my $in = <$io>) { - if ($in =~ /^The following parameters available\:/) { - (undef, $available) = split(/\:/, $in, 2); - $available =~ s/\.$//; + if (!$io) { + $self->{'err_string'} = "initiatorCreateAttributes(): Unable to open initiators mgmt ". + "interface for group '$group': $!"; + return undef; } - } - if ($available) { - foreach my $attribute (split(/\,/, $available)) { - $attribute =~ s/^\s+//; - $attribute =~ s/\s+$//; - $attributes{$attribute} = ''; + while (my $in = <$io>) { + if ($in =~ /^The following parameters available\:/) { + (undef, $available) = split(/\:/, $in, 2); + $available =~ s/\.$//; + } + } + + if ($available) { + foreach my $attribute (split(/\,/, $available)) { + $attribute =~ s/^\s+//; + $attribute =~ s/\s+$//; + $attributes{$attribute} = ''; + } } } @@ -3275,7 +3641,7 @@ sub sessions { } my $sHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_TARGETS, $driver, $target, SCST_SESSIONS); + my $_path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_SESSIONS); if (!(opendir $sHandle, $_path)) { $self->{'err_string'} = "sessions(): Unable to read directory '$_path': $!"; return undef; @@ -3291,7 +3657,8 @@ sub sessions { } foreach my $attribute (readdir($pHandle)) { - next if (($attribute eq '.') || ($attribute eq '..')); + next if ($attribute eq '.' || $attribute eq '..' || + $attribute eq SCST_MGMT_IO); my $pPath = mkpath($sPath, $attribute); if ($attribute eq 'luns') { @@ -3354,7 +3721,7 @@ sub closeSession { # 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 $path = mkpath(SCST_TARGETS_DIR(), $driver, $target, SCST_SESSIONS, $session, 'force_close'); my $io = new IO::File $path, O_WRONLY; @@ -3377,7 +3744,7 @@ sub sgvStats { my %stats; my $sHandle = new IO::Handle; - my $_path = mkpath(SCST_ROOT, SCST_SGV); + my $_path = SCST_SGV_DIR(); if (!(opendir $sHandle, $_path)) { $self->{'err_string'} = "svgStats(): Unable to read directory '$_path': $!"; return undef; @@ -3386,7 +3753,7 @@ sub sgvStats { foreach my $stat (readdir($sHandle)) { next if (($stat eq '.') || ($stat eq '..')); - my $sPath = mkpath(SCST_ROOT, SCST_SGV, $stat); + my $sPath = mkpath(SCST_SGV_DIR(), $stat); if (-d $sPath) { my $lHandle = new IO::Handle; @@ -3453,11 +3820,11 @@ sub _syswrite { my $length = shift; my $now = time(); - my $res_file = mkpath(SCST_ROOT, SCST_QUEUE_RES); + my $res_file = SCST_QUEUE_RES_PATH(); my $bytes = syswrite($io, $cmd, $length); - if (!defined($bytes)) { + if (!defined($bytes) && defined($res_file)) { if ($! == EAGAIN) { my $res = new IO::File $res_file, O_RDONLY;