summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Vu-Brugier <cvubrugier@fastmail.fm>2015-01-09 21:09:22 +0100
committerChristophe Vu-Brugier <cvubrugier@fastmail.fm>2015-01-12 09:53:20 +0100
commit1f3a182a166eace0865afeece11bbe77e81e3f31 (patch)
tree495f1bd6e1074b6e958bea1daa8b5c427abf04f9
parent08882e7b260cf53cbb7acf4bed70f82aad300b8c (diff)
downloadtargetcli-1f3a182a166eace0865afeece11bbe77e81e3f31.tar.gz
Document target parameters and attributes
Parameters read from the config file system have the same generic description that does not provide much information: > get parameter MaxBurstLength=262144 --------------------- The MaxBurstLength parameter. This patch provides a description for parameters and attributes by adding 'ui_desc_parameters' and 'ui_desc_attributes' class members to the UITPG, UINodeACL and UIStorageObject classes. The description is read when the parameter is registered with define_config_group_param(). It is displayed when the user invokes `get parameter` or `get attribute`: > get parameter MaxBurstLength=262144 --------------------- Maximum SCSI data payload in bytes in a Data-In or a solicited Data-Out iSCSI sequence. This patch also declares the types of parameters. Thus, targetcli can more efficiently check the parameters when they are set. Signed-off-by: Christophe Vu-Brugier <cvubrugier@fastmail.fm>
-rw-r--r--targetcli/ui_backstore.py32
-rw-r--r--targetcli/ui_node.py8
-rw-r--r--targetcli/ui_target.py51
3 files changed, 87 insertions, 4 deletions
diff --git a/targetcli/ui_backstore.py b/targetcli/ui_backstore.py
index 5d30e5b..163b491 100644
--- a/targetcli/ui_backstore.py
+++ b/targetcli/ui_backstore.py
@@ -453,6 +453,38 @@ class UIStorageObject(UIRTSLibNode):
A storage object UI.
Abstract Base Class, do not instantiate.
'''
+ ui_desc_attributes = {
+ 'block_size': ('number', 'Block size of the underlying device.'),
+ 'emulate_3pc': ('number', 'If set to 1, enable Third Party Copy.'),
+ 'emulate_caw': ('number', 'If set to 1, enable Compare and Write.'),
+ 'emulate_dpo': ('number', 'If set to 1, turn on Disable Page Out.'),
+ 'emulate_fua_read': ('number', 'If set to 1, enable Force Unit Access read.'),
+ 'emulate_fua_write': ('number', 'If set to 1, enable Force Unit Access write.'),
+ 'emulate_model_alias': ('number', 'If set to 1, use the backend device name for the model alias.'),
+ 'emulate_rest_reord': ('number', 'If set to 0, the Queue Algorithm Modifier is Restricted Reordering.'),
+ 'emulate_tas': ('number', 'If set to 1, enable Task Aborted Status.'),
+ 'emulate_tpu': ('number', 'If set to 1, enable Thin Provisioning Unmap.'),
+ 'emulate_tpws': ('number', 'If set to 1, enable Thin Provisioning Write Same.'),
+ 'emulate_ua_intlck_ctrl': ('number', 'If set to 1, enable Unit Attention Interlock.'),
+ 'emulate_write_cache': ('number', 'If set to 1, turn on Write Cache Enable.'),
+ 'enforce_pr_isids': ('number', 'If set to 1, enforce persistent reservation ISIDs.'),
+ 'fabric_max_sectors': ('number', 'Maximum number of sectors the fabric can transfer at once.'),
+ 'hw_block_size': ('number', 'Hardware block size in bytes.'),
+ 'hw_max_sectors': ('number', 'Maximum number of sectors the hardware can transfer at once.'),
+ 'hw_pi_prot_type': ('number', 'If non-zero, DIF protection is enabled on the underlying hardware.'),
+ 'hw_queue_depth': ('number', 'Hardware queue depth.'),
+ 'is_nonrot': ('number', 'If set to 1, the backstore is a non rotational device.'),
+ 'max_unmap_block_desc_count': ('number', 'Maximum number of block descriptors for UNMAP.'),
+ 'max_unmap_lba_count': ('number', 'Maximum number of LBA for UNMAP.'),
+ 'max_write_same_len': ('number', 'Maximum length for WRITE_SAME.'),
+ 'optimal_sectors': ('number', 'Optimal request size in sectors.'),
+ 'pi_prot_format': ('number', 'DIF protection format.'),
+ 'pi_prot_type': ('number', 'DIF protection type.'),
+ 'queue_depth': ('number', 'Queue depth.'),
+ 'unmap_granularity': ('number', 'UNMAP granularity.'),
+ 'unmap_granularity_alignment': ('number', 'UNMAP granularity alignment.'),
+ }
+
def __init__(self, storage_object, parent):
name = storage_object.name
UIRTSLibNode.__init__(self, name, storage_object, parent)
diff --git a/targetcli/ui_node.py b/targetcli/ui_node.py
index 883fb4d..838f124 100644
--- a/targetcli/ui_node.py
+++ b/targetcli/ui_node.py
@@ -145,18 +145,18 @@ class UIRTSLibNode(UINode):
parameters_ro = self.rtsnode.list_parameters(writable=False)
for parameter in parameters:
writable = parameter not in parameters_ro
- description = "The %s parameter." % parameter
+ type, desc = getattr(self.__class__, 'ui_desc_parameters', {}).get(parameter, ('string', ''))
self.define_config_group_param(
- 'parameter', parameter, 'string', description, writable)
+ 'parameter', parameter, type, desc, writable)
# If the rtsnode has attributes, enable them
attributes = self.rtsnode.list_attributes()
attributes_ro = self.rtsnode.list_attributes(writable=False)
for attribute in attributes:
writable = attribute not in attributes_ro
- description = "The %s attribute." % attribute
+ type, desc = getattr(self.__class__, 'ui_desc_attributes', {}).get(attribute, ('string', ''))
self.define_config_group_param(
- 'attribute', attribute, 'string', description, writable)
+ 'attribute', attribute, type, desc, writable)
def ui_getgroup_attribute(self, attribute):
'''
diff --git a/targetcli/ui_target.py b/targetcli/ui_target.py
index 7fcaab0..8e3519a 100644
--- a/targetcli/ui_target.py
+++ b/targetcli/ui_target.py
@@ -390,6 +390,44 @@ class UIMultiTPGTarget(UIRTSLibNode):
class UITPG(UIRTSLibNode):
+ ui_desc_attributes = {
+ 'authentication': ('number', 'If set to 1, enforce authentication for this TPG.'),
+ 'cache_dynamic_acls': ('number', 'If set to 1 in demo mode, cache dynamically generated ACLs.'),
+ 'default_cmdsn_depth': ('number', 'Default CmdSN (Command Sequence Number) depth.'),
+ 'default_erl': ('number', 'Default Error Recovery Level.'),
+ 'demo_mode_discovery': ('number', 'If set to 1 in demo mode, enable discovery.'),
+ 'demo_mode_write_protect': ('number', 'If set to 1 in demo mode, prevent writes to LUNs.'),
+ 'generate_node_acls': ('number', 'If set to 1, allow all initiators to login (i.e. demo mode).'),
+ 'login_timeout': ('number', 'Login timeout value in seconds.'),
+ 'netif_timeout': ('number', 'NIC failure timeout in seconds.'),
+ 'prod_mode_write_protect': ('number', 'If set to 1, prevent writes to LUNs.'),
+ 't10_pi': ('number', 'If set to 1, enable T10 Protection Information.'),
+ }
+
+ ui_desc_parameters = {
+ 'AuthMethod': ('string', 'Authentication method used by the TPG.'),
+ 'DataDigest': ('string', 'If set to CRC32C, the integrity of the PDU data part is verified.'),
+ 'DataPDUInOrder': ('yesno', 'If set to Yes, the data PDUs within sequences must be in order.'),
+ 'DataSequenceInOrder': ('yesno', 'If set to Yes, the data sequences must be in order.'),
+ 'DefaultTime2Retain': ('number', 'Maximum time, in seconds, after an initial wait, before which an active task reassignment is still possible after an unexpected connection termination or a connection reset.'),
+ 'DefaultTime2Wait': ('number', 'Minimum time, in seconds, to wait before attempting an explicit/implicit logout or an active task reassignment after an unexpected connection termination or a connection reset.'),
+ 'ErrorRecoveryLevel': ('number', 'Recovery levels represent a combination of recovery capabilities.'),
+ 'FirstBurstLength': ('number', 'Maximum amount in bytes of unsolicited data an initiator may send.'),
+ 'HeaderDigest': ('yesno', 'If set to CRC32C, the integrity of the PDU header part is verified.'),
+ 'IFMarker': ('yesno', 'Deprecated according to RFC 7143.'),
+ 'IFMarkInt': ('string', 'Deprecated according to RFC 7143.'),
+ 'ImmediateData': ('string', 'Immediate data support.'),
+ 'InitialR2T': ('yesno', 'If set to No, the default use of R2T (Ready To Transfer) is disabled.'),
+ 'MaxBurstLength': ('number', 'Maximum SCSI data payload in bytes in a Data-In or a solicited Data-Out iSCSI sequence.'),
+ 'MaxConnections': ('number', 'Maximum number of connections acceptable.'),
+ 'MaxOutstandingR2T': ('number', 'Maximum number of outstanding R2Ts per task.'),
+ 'MaxRecvDataSegmentLength': ('number', 'Maximum data segment length in bytes the target can receive in an iSCSI PDU.'),
+ 'MaxXmitDataSegmentLength': ('number', 'Outgoing MaxRecvDataSegmentLength sent over the wire during iSCSI login response.'),
+ 'OFMarker': ('yesno', 'Deprecated according to RFC 7143.'),
+ 'OFMarkInt': ('string', 'Deprecated according to RFC 7143.'),
+ 'TargetAlias': ('string', 'Human-readable target name or description.'),
+ }
+
'''
A generic TPG UI.
'''
@@ -734,6 +772,19 @@ class UINodeACL(UIRTSLibNode):
All sets are performed on all NodeACLs.
This is to make management of multiple ACLs easier.
'''
+ ui_desc_attributes = {
+ 'dataout_timeout': ('number', 'Data-Out timeout in seconds before invoking recovery.'),
+ 'dataout_timeout_retries': ('number', 'Number of Data-Out timeout recovery attempts before failing a path.'),
+ 'default_erl': ('number', 'Default Error Recovery Level.'),
+ 'nopin_response_timeout': ('number', 'Nop-In response timeout in seconds.'),
+ 'nopin_timeout': ('number', 'Nop-In timeout in seconds.'),
+ 'random_datain_pdu_offsets': ('number', 'If set to 1, request random Data-In PDU offsets.'),
+ 'random_datain_seq_offsets': ('number', 'If set to 1, request random Data-In sequence offsets.'),
+ 'random_r2t_offsets': ('number', 'If set to 1, request random R2T (Ready To Transfer) offsets.'),
+ }
+
+ ui_desc_parameters = UITPG.ui_desc_parameters
+
def __init__(self, name, parent):
# Don't want to duplicate work in UIRTSLibNode, so call it but