Add ALUA supported method
Passthrough backends like pscsi and user do not support ALUA managment through configfs. You can create groups, but writing to files can cause the kernel crashes. This adds a alua_supported method that backends can override and return False to indicate they do not support ALUA. Signed-off-by: Mike Christie <mchristi@redhat.com>
This commit is contained in:
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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', [])):
|
||||
|
@@ -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()
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user