diff options
-rw-r--r-- | rtslib/__init__.py | 1 | ||||
-rw-r--r-- | rtslib/alua.py | 8 | ||||
-rw-r--r-- | rtslib/root.py | 7 | ||||
-rw-r--r-- | rtslib/tcm.py | 24 | ||||
-rw-r--r-- | rtslib/utils.py | 6 |
5 files changed, 42 insertions, 4 deletions
diff --git a/rtslib/__init__.py b/rtslib/__init__.py index 48aab2a..568619e 100644 --- a/rtslib/__init__.py +++ b/rtslib/__init__.py @@ -23,6 +23,7 @@ if __name__ == "rtslib": from .root import RTSRoot from .utils import RTSLibError, RTSLibBrokenLink, RTSLibNotInCFS +from .utils import RTSLibALUANotSupported from .target import LUN, MappedLUN from .target import NodeACL, NetworkPortal, TPG, Target diff --git a/rtslib/alua.py b/rtslib/alua.py index 86a4dd3..390e74a 100644 --- a/rtslib/alua.py +++ b/rtslib/alua.py @@ -18,7 +18,7 @@ a copy of the License at ''' from .node import CFSNode -from .utils import RTSLibError, fread, fwrite +from .utils import RTSLibError, RTSLibALUANotSupported, fread, fwrite alua_rw_params = ['alua_access_state', 'alua_access_status', 'alua_write_metadata', 'alua_access_type', 'preferred', @@ -46,6 +46,12 @@ class ALUATargetPortGroup(CFSNode): @param tag: target port group id. If not passed in, try to look up existing ALUA TPG with the same name """ + # kernel partially sets up default_tg_pt_gp and will let you partially + # setup ALUA groups for pscsi and user, but writing to some of the + # files will crash the kernel. Just fail to even create groups until + # the kernel is fixed. + if storage_object.alua_supported is False: + raise RTSLibALUANotSupported("Backend does not support ALUA setup") # default_tg_pt_gp takes tag 1 if tag is not None and (tag > 65535 or tag < 1): diff --git a/rtslib/root.py b/rtslib/root.py index 3cc6fbf..6d6b5ee 100644 --- a/rtslib/root.py +++ b/rtslib/root.py @@ -26,7 +26,7 @@ from .node import CFSNode from .target import Target from .fabric import FabricModule from .tcm import so_mapping, StorageObject -from .utils import RTSLibError, modprobe, mount_configfs +from .utils import RTSLibError, RTSLibALUANotSupported, modprobe, mount_configfs from .utils import dict_remove, set_attributes from .alua import ALUATargetPortGroup @@ -224,7 +224,10 @@ class RTSRoot(CFSNode): set_attributes(so_obj, so.get('attributes', {}), so_err_func) for alua_tpg in so.get('alua_tpgs', {}): - ALUATargetPortGroup.setup(so_obj, alua_tpg, err_func) + try: + ALUATargetPortGroup.setup(so_obj, alua_tpg, err_func) + except RTSLibALUANotSupported: + pass # Don't need to create fabric modules for index, fm in enumerate(config.get('fabric_modules', [])): diff --git a/rtslib/tcm.py b/rtslib/tcm.py index 5452f92..aa3530a 100644 --- a/rtslib/tcm.py +++ b/rtslib/tcm.py @@ -222,7 +222,15 @@ class StorageObject(CFSNode): ''' self._check_self() for tpg in os.listdir("%s/alua" % self.path): - yield ALUATargetPortGroup(self, tpg) + if self.alua_supported: + yield ALUATargetPortGroup(self, tpg) + + def _get_alua_supported(self): + ''' + Children should override and return false if ALUA setup is not supported. + ''' + self._check_self() + return True # StorageObject public stuff @@ -279,6 +287,8 @@ class StorageObject(CFSNode): doc="Get the list of all LUN objects attached.") alua_tpgs = property(_list_alua_tpgs, doc="Get list of ALUA Target Port Groups attached.") + alua_supported = property(_get_alua_supported, + doc="Returns true if ALUA can be setup. False if not supported.") def dump(self): d = super(StorageObject, self).dump() @@ -408,6 +418,10 @@ class PSCSIStorageObject(StorageObject): self._check_self() return int(self._parse_info('Host ID')) + def _get_alua_supported(self): + self._check_self() + return False + # PSCSIStorageObject public stuff wwn = property(StorageObject._get_wwn, _set_wwn, @@ -427,6 +441,8 @@ class PSCSIStorageObject(StorageObject): doc="Get the SCSI device target id") lun = property(_get_lun, doc="Get the SCSI device LUN") + alua_supported = property(_get_alua_supported, + doc="ALUA cannot be setup with rtslib, so False is returned."); def dump(self): d = super(PSCSIStorageObject, self).dump() @@ -808,10 +824,16 @@ class UserBackedStorageObject(StorageObject): return None return val + def _get_alua_supported(self): + self._check_self() + return False + size = property(_get_size, doc="Get the size in bytes.") config = property(_get_config, doc="Get the TCMU config.") + alua_supported = property(_get_alua_supported, + doc="ALUA cannot be setup with rtslib, so False is returned."); def dump(self): d = super(UserBackedStorageObject, self).dump() diff --git a/rtslib/utils.py b/rtslib/utils.py index 969d2d7..1a5315e 100644 --- a/rtslib/utils.py +++ b/rtslib/utils.py @@ -37,6 +37,12 @@ class RTSLibError(Exception): ''' pass +class RTSLibALUANotSupported(RTSLibError): + ''' + Backend does not support ALUA. + ''' + pass + class RTSLibBrokenLink(RTSLibError): ''' Broken link in configfs, i.e. missing LUN storage object. |