summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Christie <mchristi@redhat.com>2017-01-03 13:20:21 -0600
committerMike Christie <mchristi@redhat.com>2017-01-03 13:56:28 -0600
commitb85519f44bd7e940243d89fccf8b59992ef8361a (patch)
treee0c4a15c6318bc542d92c6a2327faacd3ff54963
parent1f3abc3caddc8663abd529ace41e84088f4761c5 (diff)
downloadrtslib-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.py14
-rw-r--r--rtslib/target.py9
-rw-r--r--rtslib/tcm.py12
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