diff options
author | Mike Christie <mchristi@redhat.com> | 2017-01-03 13:20:21 -0600 |
---|---|---|
committer | Mike Christie <mchristi@redhat.com> | 2017-01-03 13:56:28 -0600 |
commit | b85519f44bd7e940243d89fccf8b59992ef8361a (patch) | |
tree | e0c4a15c6318bc542d92c6a2327faacd3ff54963 | |
parent | 1f3abc3caddc8663abd529ace41e84088f4761c5 (diff) | |
download | rtslib-fb-b85519f44bd7e940243d89fccf8b59992ef8361a.tar.gz |
Add ALUA restore support
Add support to save ALUA info and restore it.
Signed-off-by: Mike Christie <mchristi@redhat.com>
-rw-r--r-- | rtslib/root.py | 14 | ||||
-rw-r--r-- | rtslib/target.py | 9 | ||||
-rw-r--r-- | rtslib/tcm.py | 12 |
3 files changed, 33 insertions, 2 deletions
diff --git a/rtslib/root.py b/rtslib/root.py index b65825f..3cc6fbf 100644 --- a/rtslib/root.py +++ b/rtslib/root.py @@ -28,6 +28,7 @@ from .fabric import FabricModule from .tcm import so_mapping, StorageObject from .utils import RTSLibError, modprobe, mount_configfs from .utils import dict_remove, set_attributes +from .alua import ALUATargetPortGroup default_save_file = "/etc/target/saveconfig.json" @@ -85,6 +86,12 @@ class RTSRoot(CFSNode): for so in StorageObject.all(): yield so + def _list_alua_tpgs(self): + self._check_self() + for so in self.storage_objects: + for a in so.alua_tpgs: + yield a + def _list_tpgs(self): self._check_self() for t in self.targets: @@ -203,7 +210,7 @@ class RTSRoot(CFSNode): err_func("'plugin' not defined or invalid in storageobject %s" % so['name']) continue kwargs = so.copy() - dict_remove(kwargs, ('exists', 'attributes', 'plugin', 'buffered_mode')) + dict_remove(kwargs, ('exists', 'attributes', 'plugin', 'buffered_mode', 'alua_tpgs')) try: so_obj = so_cls(**kwargs) except Exception as e: @@ -216,6 +223,9 @@ 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) + # Don't need to create fabric modules for index, fm in enumerate(config.get('fabric_modules', [])): if 'name' not in fm: @@ -299,6 +309,8 @@ class RTSRoot(CFSNode): doc="Get the list of all existing LUN objects.") fabric_modules = property(_list_fabric_modules, doc="Get the list of all FabricModule objects.") + alua_tpgs = property(_list_alua_tpgs, + doc="Get the list of all ALUA TPG objects.") def _test(): '''Run the doctests.''' diff --git a/rtslib/target.py b/rtslib/target.py index d8dc655..4c06cf4 100644 --- a/rtslib/target.py +++ b/rtslib/target.py @@ -655,17 +655,24 @@ class LUN(CFSNode): return try: - cls(tpg_obj, lun['index'], storage_object=match_so, alias=lun.get('alias')) + lun_obj = cls(tpg_obj, lun['index'], storage_object=match_so, alias=lun.get('alias')) except (RTSLibError, KeyError): err_func("Creating TPG %d LUN index %d failed" % (tpg_obj.tag, lun['index'])) + try: + lun_obj.alua_tg_pt_gp_name = lun['alua_tg_pt_gp_name'] + except KeyError: + # alua_tg_pt_gp support not present in older versions + pass + def dump(self): d = super(LUN, self).dump() d['storage_object'] = "/backstores/%s/%s" % \ (self.storage_object.plugin, self.storage_object.name) d['index'] = self.lun d['alias'] = self.alias + d['alua_tg_pt_gp_name'] = self.alua_tg_pt_gp_name return d diff --git a/rtslib/tcm.py b/rtslib/tcm.py index 2ea5d0f..64dd48c 100644 --- a/rtslib/tcm.py +++ b/rtslib/tcm.py @@ -25,6 +25,7 @@ import glob import resource from six.moves import range +from .alua import ALUATargetPortGroup from .node import CFSNode from .utils import fread, fwrite, generate_wwn, RTSLibError, RTSLibNotInCFS from .utils import convert_scsi_path_to_hctl, convert_scsi_hctl_to_path @@ -215,6 +216,14 @@ class StorageObject(CFSNode): for lun in self._gen_attached_luns(): yield lun + def _list_alua_tpgs(self): + ''' + Generate all ALUA groups attach to a storage object. + ''' + self._check_self() + for tpg in os.listdir("%s/alua" % self.path): + yield ALUATargetPortGroup(self, tpg) + # StorageObject public stuff def delete(self): @@ -264,11 +273,14 @@ class StorageObject(CFSNode): + "is used by any LUN") attached_luns = property(_list_attached_luns, doc="Get the list of all LUN objects attached.") + alua_tpgs = property(_list_alua_tpgs, + doc="Get list of ALUA Target Port Groups attached.") def dump(self): d = super(StorageObject, self).dump() d['name'] = self.name d['plugin'] = self.plugin + d['alua_tpgs'] = [tpg.dump() for tpg in self.alua_tpgs] return d |