- All list/set attribute options now work.

- Adding and removing target & driver attributes now work.



git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1957 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Mark Buechler
2010-08-18 15:02:33 +00:00
parent e38cc66c2b
commit 95cbc2bbf5
2 changed files with 246 additions and 70 deletions

View File

@@ -132,6 +132,8 @@ my %VERBOSE_ERROR = (
(SCST_C_DRV_NO_DRIVER) => 'No such driver exists.',
(SCST_C_DRV_NOTVIRT) => 'Driver is incapable of dynamically adding/removing targets or attributes.',
(SCST_C_DRV_ADDATTR_FAIL) => 'Failed to add driver dynamic attribute. See "dmesg" for more information.',
(SCST_C_DRV_REMATTR_FAIL) => 'Failed to remove driver dymanic attribute. See "dmesg" for more information.',
(SCST_C_DRV_BAD_ATTRIBUTES) => 'Bad attributes given for driver.',
(SCST_C_DRV_ATTRIBUTE_STATIC) => 'Driver attribute specified is static.',
(SCST_C_DRV_SETATTR_FAIL) => 'Failed to set driver attribute. See "dmesg" for more information.',
@@ -141,6 +143,8 @@ my %VERBOSE_ERROR = (
(SCST_C_TGT_ADD_FAIL) => 'Failed to add target. See "dmesg" for more information.',
(SCST_C_TGT_REM_FAIL) => 'Failed to remove target. See "dmesg" for more information.',
(SCST_C_TGT_SETATTR_FAIL) => 'Failed to set target attribute. See "dmesg" for more information.',
(SCST_C_TGT_ADDATTR_FAIL) => 'Failed to add target dynamic attribute. See "dmesg" for more information.',
(SCST_C_TGT_REMATTR_FAIL) => 'Failed to remove target dynamic attribute. See "dmesg" for more information.',
(SCST_C_TGT_NO_LUN) => 'No such LUN exists.',
(SCST_C_TGT_ADD_LUN_FAIL) => 'Failed to add LUN. See "dmesg" for more information.',
(SCST_C_TGT_LUN_EXISTS) => 'LUN already exists.',

View File

@@ -250,6 +250,11 @@ sub getArgs {
my $setLunAttr;
my $setInitiatorAttr;
my $addDriverAttr;
my $addTargetAttr;
my $remDriverAttr;
my $remTargetAttr;
my $openDev;
my $closeDev;
my $resyncDev;
@@ -314,6 +319,11 @@ sub getArgs {
'set_lun_attr=s' => \$setLunAttr,
'set_ini_attr=s' => \$setInitiatorAttr,
'add_drv_attr=s' => \$addDriverAttr,
'add_tgt_attr=s' => \$addTargetAttr,
'rem_drv_attr=s' => \$remDriverAttr,
'rem_tgt_attr=s' => \$remTargetAttr,
'open_dev=s' => \$openDev,
'close_dev=s' => \$closeDev,
'resync_dev=s' => \$resyncDev,
@@ -374,6 +384,7 @@ sub getArgs {
my $op_mode = defined($clearConfig) + defined($writeConfig) + defined($checkConfig) +
defined($openDev) + defined($closeDev) + defined($addGroup) + defined($removeGroup) +
defined($addInitiator) + defined($removeInitiator) + defined($clearInitiators) +
defined($addDriverAttr) + defined($addTargetAttr) + defined($remDriverAttr) + defined($remTargetAttr) +
defined($addLun) + defined($removeLun) + defined($replaceLun) + defined($clearLuns) +
defined($enableTarget) + defined($disableTarget) + defined($issueLip);
@@ -428,7 +439,7 @@ sub getArgs {
}
if (defined($setLunAttr) &&
(!defined($driver) || !defined($target) || !defined($group) || !defined($attributes))) {
(!defined($driver) || !defined($target) || !defined($attributes))) {
print "Please specify -driver -target -group and -attributes with -set_lun_attr.\n";
usage();
}
@@ -439,6 +450,28 @@ sub getArgs {
usage();
}
if (defined($addDriverAttr) && !defined($attributes)) {
print "Please specify -attributes with -add_drv_attr.\n";
usage();
}
if (defined($addTargetAttr) &&
(!defined($driver) || !defined($attributes))) {
print "Please specify -driver and -attributes with -add_tgt_attr.\n";
usage();
}
if (defined($remDriverAttr) && !defined($attributes)) {
print "Please specify -attributes with -rem_drv_attr.\n";
usage();
}
if (defined($remTargetAttr) &&
(!defined($driver) || !defined($attributes))) {
print "Please specify -driver and -attributes with -rem_tgt_attr.\n";
usage();
}
if ((defined($openDev) || defined($closeDev)) && !defined($handler)) {
print "Please specify -handler with -open_dev/-close_dev.\n";
usage();
@@ -497,6 +530,7 @@ sub getArgs {
$listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr,
$listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, $setDeviceAttr,
$setDriverAttr, $setTargetAttr, $setLunAttr, $setInitiatorAttr,
$addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr,
$openDev, $closeDev, $resyncDev,
$addGroup, $removeGroup,
$addInitiator, $removeInitiator, $moveInitiator, $clearInitiators,
@@ -520,6 +554,7 @@ sub main {
$listSessions, $listHandlerAttr, $listDeviceAttr, $listDriverAttr, $listTargetAttr,
$listLunAttr, $listInitiatorAttr, $setScstAttr, $setHandlerAttr, $setDeviceAttr,
$setDriverAttr, $setTargetAttr, $setLunAttr, $setInitiatorAttr,
$addDriverAttr, $addTargetAttr, $remDriverAttr, $remTargetAttr,
$openDev, $closeDev, $resyncDev,
$addGroup, $removeGroup,
$addInitiator, $removeInitiator, $moveInitiator, $clearInitiators,
@@ -634,6 +669,22 @@ sub main {
$rc = setInitiatorAttributes($driver, $target, $group, $setInitiatorAttr, $attributes, TRUE);
last SWITCH;
};
defined($addDriverAttr) && do {
$rc = addDriverDynamicAttributes($addDriverAttr, $attributes);
last SWITCH;
};
defined($addTargetAttr) && do {
$rc = addTargetDynamicAttributes($driver, $addTargetAttr, $attributes);
last SWITCH;
};
defined($remDriverAttr) && do {
$rc = removeDriverDynamicAttributes($remDriverAttr, $attributes);
last SWITCH;
};
defined($remTargetAttr) && do {
$rc = removeTargetDynamicAttributes($driver, $remTargetAttr, $attributes);
last SWITCH;
};
defined($openDev) && do {
$rc = openDevice($handler, $openDev, $attributes);
last SWITCH;
@@ -699,6 +750,8 @@ sub main {
last SWITCH;
};
return if issueWarning($SCST->errorString($rc));
if (!$all_good) {
print "No valid operations specified.\n";
usage();
@@ -1839,6 +1892,8 @@ sub listDevice {
my $attributes = $SCST->deviceAttributes($device);
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "No such device '$device' exists.\n";
return;
@@ -1942,6 +1997,8 @@ sub listGroup {
$luns = $SCST->luns($driver, $target, $group) if (!$luns);
$initiators = $SCST->initiators($driver, $target, $group) if (!$initiators);
return if issueWarning($SCST->errorString());
if ((keys %{$luns}) || ($#{$initiators} > -1)) {
my $l_device;
my $l_initiator;
@@ -2068,6 +2125,8 @@ sub listExported {
$attributes = $SCST->deviceAttributes($device) if (!$attributes);
return if issueWarning($SCST->errorString());
if (keys %{$$attributes{'exported'}}) {
my $exported = $$attributes{'exported'}->{'value'};
@@ -2232,6 +2291,8 @@ sub listScstAttributes {
my $attributes = $SCST->scstAttributes();
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "FATAL: Unable to get a list of SCST attributes! Please make sure SCST is loaded.\n";
return;
@@ -2246,6 +2307,8 @@ sub listHandlerAttributes {
my $attributes = $SCST->handlerAttributes($handler);
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "No such handler '$handler' found.\n";
return;
@@ -2260,6 +2323,8 @@ sub listDriverAttributes {
my $attributes = $SCST->driverAttributes($driver);
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "No such driver '$driver' found.\n";
return;
@@ -2275,6 +2340,8 @@ sub listTargetAttributes {
my $attributes = $SCST->targetAttributes($driver, $target);
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "No such driver/target '$driver/$target' found.\n";
return;
@@ -2292,6 +2359,8 @@ sub listLunAttributes {
my $attributes = $SCST->lunAttributes($driver, $target, $lun, $group);
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
if (defined($group)) {
print "No such driver/target/group/lun '$driver/$target/$group/$lun' found.\n";
@@ -2320,6 +2389,8 @@ sub listInitiatorAttributes {
return;
}
return if issueWarning($SCST->errorString());
if (!scalar(keys %{$attributes})) {
print "No such driver/target/group/initiator '$driver/$target/$group/$initiator' found.\n";
return;
@@ -2352,6 +2423,8 @@ sub setScstAttributes {
my $error = "-> WARNING: SCST lacks the settable attribute '%s', ignoring.\n\n";
my $_attributes = $SCST->scstAttributes();
return if issueWarning($SCST->errorString());
return setAttributes(undef, undef, undef, undef, $attributes,
$_attributes, $error, \&setScstAttribute, $showset);
}
@@ -2380,6 +2453,8 @@ sub setDeviceAttributes {
"attribute '%s', ignoring.\n\n";
my $_attributes = $SCST->deviceAttributes($device);
return if issueWarning($SCST->errorString());
return setAttributes(undef, undef, undef, $device, $attributes,
$_attributes, $error, \&setDeviceAttribute, $showset);
}
@@ -2408,6 +2483,8 @@ sub setHandlerAttributes {
"attribute '%s', ignoring.\n\n";
my $_attributes = $SCST->handlerAttributes($handler);
return if issueWarning($SCST->errorString());
return setAttributes(undef, undef, undef, $handler, $attributes,
$_attributes, $error, \&setHandlerAttribute, $showset);
}
@@ -2439,6 +2516,8 @@ sub setGroupAttributes {
"attribute '%s', ignoring.\n\n";
my $_attributes = $SCST->groupAttributes($driver, $target, $group);
return if issueWarning($SCST->errorString());
return setAttributes(undef, $driver, $target, $group, $attributes,
$_attributes, $error, \&setGroupAttribute, $showset);
}
@@ -2484,6 +2563,8 @@ sub setLunAttributes {
my $_attributes = $SCST->lunAttributes($driver, $target, $lun, $group);
return if issueWarning($SCST->errorString());
return setAttributes($driver, $target, $lun, $group, $attributes,
$_attributes, $error, \&setLunAttribute, $showset);
}
@@ -2513,9 +2594,19 @@ sub setInitiatorAttributes {
my $attributes = shift;
my $showset = shift;
my $_attributes = $SCST->initiatorAttributes($driver, $target, $group, $initiator);
return if issueWarning($SCST->errorString());
# As if writing, initiators didn't have attributes. This will
# allow us to support it in the future.
if ($SCST->errorString() =~ /Not a directory/) {
print "Initiators do not (yet) have attributes.\n";
return;
}
my $error = "-> WARNING: Driver/target/group/initiator '$driver/$target/$group/$initiator' ".
"lacks the settable attribute '%s', ignoring.\n\n";
my $_attributes = $SCST->initiatorAttributes($driver, $target, $group, $initiator);
return setAttributes($driver, $target, $group, $initiator, $attributes,
$_attributes, $error, \&setInitiatorAttribute, $showset);
@@ -2533,7 +2624,6 @@ sub setAttributes {
my $callback = shift;
my $showset = shift;
my %toset;
my %existing;
# build caches for easier matching
foreach my $attribute (keys %{$attributes}) {
@@ -2546,30 +2636,17 @@ sub setAttributes {
}
}
foreach my $attribute (keys %{$_attributes}) {
next if ($$_attributes{$attribute}->{'static'});
if (defined($$_attributes{$attribute}->{'keys'})) {
foreach my $key (keys %{$$_attributes{$attribute}->{'keys'}}) {
my $value = $$_attributes{$attribute}->{'keys'}->{$key}->{'value'};
$existing{$attribute}->{$value}++
if (defined($value) && ($value ne ''));
}
} else {
my $value = $$_attributes{$attribute}->{'value'};
$existing{$attribute}->{$value} = FALSE;
}
}
my $existing = cacheAttributes($_attributes);
foreach my $attribute (keys %toset) {
foreach my $value (keys %{$toset{$attribute}}) {
if (!defined($existing{$attribute})) {
if (!defined($$existing{$attribute})) {
print sprintf($error, $attribute);
next;
}
# already set, move on
if (defined($existing{$attribute}->{$value})) {
if (defined($$existing{$attribute}->{$value})) {
print "-> Attribute '$attribute' already set to value '$value', ignoring.\n"
if ($showset);
next;
@@ -2604,11 +2681,12 @@ sub setDriverAttributes {
my $attributes = shift;
my $deletions = shift;
my %toset;
my %existing;
my $driverCap = $SCST->driverIsVirtualCapable($driver);
my $_attributes = $SCST->driverAttributes($driver);
return if issueWarning($SCST->errorString());
# build caches for easier matching
foreach my $attribute (keys %{$attributes}) {
if (ref($$attributes{$attribute}) eq 'ARRAY') {
@@ -2620,38 +2698,24 @@ sub setDriverAttributes {
}
}
foreach my $attribute (keys %{$_attributes}) {
next if ($$_attributes{$attribute}->{'static'});
if (defined($$_attributes{$attribute}->{'keys'})) {
foreach my $key (keys %{$$_attributes{$attribute}->{'keys'}}) {
my $value = $$_attributes{$attribute}->{'keys'}->{$key}->{'value'};
$existing{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
} else {
my $value = $$_attributes{$attribute}->{'value'};
$existing{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
}
my $existing = cacheAttributes($_attributes);
# add/change
foreach my $attribute (keys %toset) {
foreach my $value (keys %{$toset{$attribute}}) {
if (!defined($existing{$attribute}) &&
if (!defined($$existing{$attribute}) &&
$driverCap && !$SCST->checkDriverDynamicAttributes($driver, $attribute)) {
addDriverDynamicAttribute($driver, $attribute, $value);
next;
} elsif (!defined($existing{$attribute})) {
} elsif (!defined($$existing{$attribute})) {
print "-> WARNING: Driver '$driver' lacks the settable attribute ".
"'$attribute', ignoring.\n\n";
next;
}
# already set, move on
if (defined($existing{$attribute}->{$value})) {
$existing{$attribute}->{$value} = TRUE;
if (defined($$existing{$attribute}->{$value})) {
$$existing{$attribute}->{$value} = TRUE;
next;
}
@@ -2662,15 +2726,15 @@ sub setDriverAttributes {
setDriverAttribute($driver, $attribute, $value);
}
$existing{$attribute}->{$value} = TRUE;
$$existing{$attribute}->{$value} = TRUE;
}
}
foreach my $attribute (keys %existing) {
foreach my $attribute (keys %{$existing}) {
next if (!$driverCap || $SCST->checkDriverDynamicAttributes($driver, $attribute));
foreach my $value (keys %{$existing{$attribute}}) {
if (!$existing{$attribute}->{$value}) {
foreach my $value (keys %{$$existing{$attribute}}) {
if (!$$existing{$attribute}->{$value}) {
if ($deletions) {
removeDriverDynamicAttribute($driver, $attribute, $value);
} else {
@@ -2682,6 +2746,27 @@ sub setDriverAttributes {
}
}
sub addDriverDynamicAttributes {
my $driver = shift;
my $attributes = shift;
my $_attributes = $SCST->driverAttributes($driver);
return if issueWarning($SCST->errorString());
my $existing = cacheAttributes($_attributes);
foreach my $attribute (keys %{$attributes}) {
if (defined($$existing{$attribute}->{$$attributes{$attribute}})) {
my $value = $$attributes{$attribute};
print "-> Attribute/value '$attribute/$value' already exists for driver '$driver'.\n";
next;
}
addDriverDynamicAttribute($driver, $attribute, $$attributes{$attribute});
}
}
sub addDriverDynamicAttribute {
my $driver = shift;
my $attribute = shift;
@@ -2694,6 +2779,27 @@ sub addDriverDynamicAttribute {
immediateExit($SCST->errorString($rc)) if ($rc);
}
sub removeDriverDynamicAttributes {
my $driver = shift;
my $attributes = shift;
my $_attributes = $SCST->driverAttributes($driver);
return if issueWarning($SCST->errorString());
my $existing = cacheAttributes($_attributes);
foreach my $attribute (keys %{$attributes}) {
if (!defined($$existing{$attribute}->{$$attributes{$attribute}})) {
my $value = $$attributes{$attribute};
print "-> Attribute/value '$attribute/$value' doesn't exist for driver '$driver'.\n";
next;
}
removeDriverDynamicAttribute($driver, $attribute, $$attributes{$attribute});
}
}
sub removeDriverDynamicAttribute {
my $driver = shift;
my $attribute = shift;
@@ -2734,12 +2840,12 @@ sub setTargetAttributes {
my $attributes = shift;
my $deletions = shift;
my %toset;
my %existing;
my $driverCap = $SCST->driverIsVirtualCapable($driver);
my $_attributes = $SCST->targetAttributes($driver, $target);
return if issueWarning($SCST->errorString());
# build caches for easier matching
foreach my $attribute (keys %{$attributes}) {
if (ref($$attributes{$attribute}) eq 'ARRAY') {
@@ -2751,38 +2857,24 @@ sub setTargetAttributes {
}
}
foreach my $attribute (keys %{$_attributes}) {
next if ($$_attributes{$attribute}->{'static'});
if (defined($$_attributes{$attribute}->{'keys'})) {
foreach my $key (keys %{$$_attributes{$attribute}->{'keys'}}) {
my $value = $$_attributes{$attribute}->{'keys'}->{$key}->{'value'};
$existing{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
} else {
my $value = $$_attributes{$attribute}->{'value'};
$existing{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
}
my $existing = cacheAttributes($_attributes);
# add/change
foreach my $attribute (keys %toset) {
foreach my $value (keys %{$toset{$attribute}}) {
if (!defined($existing{$attribute}) &&
if (!defined($$existing{$attribute}) &&
$driverCap && !$SCST->checkTargetDynamicAttributes($driver, $attribute)) {
addTargetDynamicAttribute($driver, $target, $attribute, $value);
next;
} elsif (!defined($existing{$attribute})) {
} elsif (!defined($$existing{$attribute})) {
print "-> WARNING: Driver/target '$driver/$target' lacks the settable attribute ".
"'$attribute', ignoring.\n\n";
next;
}
# already set, move on
if (defined($existing{$attribute}->{$value})) {
$existing{$attribute}->{$value} = TRUE;
if (defined($$existing{$attribute}->{$value})) {
$$existing{$attribute}->{$value} = TRUE;
next;
}
@@ -2793,15 +2885,15 @@ sub setTargetAttributes {
setTargetAttribute($driver, $target, $attribute, $value);
}
$existing{$attribute}->{$value} = TRUE;
$$existing{$attribute}->{$value} = TRUE;
}
}
foreach my $attribute (keys %existing) {
foreach my $attribute (keys %{$existing}) {
next if (!$driverCap || $SCST->checkTargetDynamicAttributes($driver, $attribute));
foreach my $value (keys %{$existing{$attribute}}) {
if (!$existing{$attribute}->{$value}) {
foreach my $value (keys %{$$existing{$attribute}}) {
if (!$$existing{$attribute}->{$value}) {
if ($deletions) {
removeTargetDynamicAttribute($driver, $target, $attribute, $value);
} else {
@@ -2813,6 +2905,29 @@ sub setTargetAttributes {
}
}
sub addTargetDynamicAttributes {
my $driver = shift;
my $target = shift;
my $attributes = shift;
my $_attributes = $SCST->targetAttributes($driver, $target);
return if issueWarning($SCST->errorString());
my $existing = cacheAttributes($_attributes);
foreach my $attribute (keys %{$attributes}) {
if (defined($$existing{$attribute}->{$$attributes{$attribute}})) {
my $value = $$attributes{$attribute};
print "-> Attribute/value '$attribute/$value' already exists for driver/target ".
"'$driver/$target'.\n";
next;
}
addTargetDynamicAttribute($driver, $target, $attribute, $$attributes{$attribute});
}
}
sub addTargetDynamicAttribute {
my $driver = shift;
my $target = shift;
@@ -2827,6 +2942,29 @@ sub addTargetDynamicAttribute {
immediateExit($SCST->errorString($rc)) if ($rc);
}
sub removeTargetDynamicAttributes {
my $driver = shift;
my $target = shift;
my $attributes = shift;
my $_attributes = $SCST->targetAttributes($driver, $target);
return if issueWarning($SCST->errorString());
my $existing = cacheAttributes($_attributes);
foreach my $attribute (keys %{$attributes}) {
if (!defined($$existing{$attribute}->{$$attributes{$attribute}})) {
my $value = $$attributes{$attribute};
print "-> Attribute/value '$attribute/$value' doesn't exist for driver/target ".
"'$driver/$target'.\n";
next;
}
removeTargetDynamicAttribute($driver, $target, $attribute, $$attributes{$attribute});
}
}
sub removeTargetDynamicAttribute {
my $driver = shift;
my $target = shift;
@@ -3077,7 +3215,7 @@ sub clearLuns {
immediateExit($SCST->errorString($rc)) if ($rc);
}
sub removeDriverDynamicAttributes {
sub clearDriverDynamicAttributes {
my $driver = shift;
return if (!$SCST->driverIsVirtualCapable($driver));
@@ -3103,7 +3241,7 @@ sub removeDriverDynamicAttributes {
print "done.\n";
}
sub removeTargetDynamicAttributes {
sub clearTargetDynamicAttributes {
my $driver = shift;
my $target = shift;
@@ -3561,6 +3699,29 @@ sub configToAttr {
return \%attributes;
}
sub cacheAttributes {
my $attributes = shift;
my %cache;
foreach my $attribute (keys %{$attributes}) {
next if ($$attributes{$attribute}->{'static'});
if (defined($$attributes{$attribute}->{'keys'})) {
foreach my $key (keys %{$$attributes{$attribute}->{'keys'}}) {
my $value = $$attributes{$attribute}->{'keys'}->{$key}->{'value'};
$cache{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
} else {
my $value = $$attributes{$attribute}->{'value'};
$cache{$attribute}->{$value} = FALSE
if (defined($value) && ($value ne ''));
}
}
return \%cache;
}
sub numerically {
$a <=> $b;
}
@@ -3579,6 +3740,17 @@ sub immediateExit {
exit 1;
}
sub issueWarning {
my $error = shift;
return FALSE if (!$error);
print "\n\nWARNING: Received the following error:\n\n\t";
print "$error\n\n";
return TRUE;
}
# Hey! Stop that!
sub commitSuicide {
print "\n\nAborting immediately.\n";