Remove flattern_nested_list() and gen_list_item() The things that needed flatten_nested_list are more suited to using generators directly, rather than indirectly via gen_list_item. There are a few instances where the code really *does* want a list instead of an iterator, so some callsite changes were also needed. Signed-off-by: Andy Grover <agrover@xxxxxxxxxx> --- rtslib/root.py | 52 +++++++++++++++++++++++++++++----------------------- rtslib/target.py | 47 ++++++++++++++++------------------------------- rtslib/tcm.py | 12 +++--------- rtslib/utils.py | 27 --------------------------- 4 files changed, 48 insertions(+), 90 deletions(-) diff --git a/rtslib/root.py b/rtslib/root.py index 9c43834..12410d2 100644 --- a/rtslib/root.py +++ b/rtslib/root.py @@ -25,7 +25,7 @@ from node import CFSNode from target import Target, FabricModule, TPG, MappedLUN, LUN, NetworkPortal, NodeACL from tcm import FileIOBackstore, BlockBackstore from tcm import PSCSIBackstore, RDMCPBackstore -from utils import RTSLibError, RTSLibBrokenLink, flatten_nested_list, modprobe +from utils import RTSLibError, RTSLibBrokenLink, modprobe backstores = dict( fileio=FileIOBackstore, @@ -77,12 +77,11 @@ class RTSRoot(CFSNode): self._check_self() targets = set([]) for fabric_module in self.fabric_modules: - targets.update(fabric_module.targets) - return targets + for target in fabric_module.targets: + yield target def _list_backstores(self): self._check_self() - backstores = set([]) if os.path.isdir("%s/core" % self.path): backstore_dirs = glob.glob("%s/core/*_*" % self.path) for backstore_dir in [os.path.basename(path) @@ -91,48 +90,55 @@ class RTSRoot(CFSNode): backstore_dir) if regex: if regex.group(1) == "fileio": - backstores.add( - FileIOBackstore(int(regex.group(3)), 'lookup')) + yield FileIOBackstore(int(regex.group(3)), 'lookup') elif regex.group(1) == "pscsi": - backstores.add( - PSCSIBackstore(int(regex.group(3)), 'lookup')) + yield PSCSIBackstore(int(regex.group(3)), 'lookup') elif regex.group(1) == "iblock": - backstores.add( - BlockBackstore(int(regex.group(3)), 'lookup')) + yield BlockBackstore(int(regex.group(3)), 'lookup') elif regex.group(1) == "rd_mcp": - backstores.add( - RDMCPBackstore(int(regex.group(3)), 'lookup')) - return backstores + yield RDMCPBackstore(int(regex.group(3)), 'lookup') + def _list_storage_objects(self): self._check_self() - return set(flatten_nested_list([backstore.storage_objects - for backstore in self.backstores])) + for bs in self.backstores: + for so in bs.storage_objects: + yield so def _list_tpgs(self): self._check_self() - return set(flatten_nested_list([t.tpgs for t in self.targets])) + for t in self.targets: + for tpg in t.tpgs: + yield tpg def _list_node_acls(self): self._check_self() - return set(flatten_nested_list([t.node_acls for t in self.tpgs])) + for t in self.tpgs: + for node_acl in t.node_acls: + yield node_acl def _list_network_portals(self): self._check_self() - return set(flatten_nested_list([t.network_portals for t in self.tpgs])) + for t in self.tpgs: + for p in t.network_portals: + yield p def _list_luns(self): self._check_self() - return set(flatten_nested_list([t.luns for t in self.tpgs])) + for t in self.tpgs: + for lun in t.luns: + yield lun def _list_fabric_modules(self): self._check_self() mod_names = [mod_name[:-5] for mod_name in os.listdir(self.spec_dir) if mod_name.endswith('.spec')] - modules = [FabricModule(mod_name) for mod_name in mod_names] - return modules + for name in mod_names: + yield FabricModule(name) def _list_loaded_fabric_modules(self): - return [fm for fm in self._list_fabric_modules() if fm.exists] + for module in self._list_fabric_modules(): + if module.exists: + yield module def __str__(self): return "rtsadmin" @@ -180,7 +186,7 @@ class RTSRoot(CFSNode): if clear_existing: self.clear_existing(confirm=True) - if not clear_existing and (self.storage_objects or self.targets): + if not clear_existing and (list(self.storage_objects) or list(self.targets)): raise RTSLibError("backstores or targets present, not restoring." + " Set clear_existing=True?") diff --git a/rtslib/target.py b/rtslib/target.py index 584809e..a4b7939 100644 --- a/rtslib/target.py +++ b/rtslib/target.py @@ -196,13 +196,10 @@ class FabricModule(CFSNode): def _list_targets(self): if self.exists: - return set( - [Target(self, wwn, 'lookup') - for wwn in os.listdir(self.path) - if os.path.isdir("%s/%s" % (self.path, wwn)) - if wwn not in self.target_names_excludes]) - else: - return set([]) + for wwn in os.listdir(self.path): + if os.path.isdir("%s/%s" % (self.path, wwn)) and \ + wwn not in self.target_names_excludes: + yield Target(self, wwn, 'lookup') def _get_version(self): if self.exists: @@ -844,12 +841,9 @@ class NodeACL(CFSNode): def _list_mapped_luns(self): self._check_self() - mapped_luns = [] - mapped_lun_dirs = glob.glob("%s/lun_*" % self.path) - for mapped_lun_dir in mapped_lun_dirs: + for mapped_lun_dir in glob.glob("%s/lun_*" % self.path): mapped_lun = int(os.path.basename(mapped_lun_dir).split("_")[1]) - mapped_luns.append(MappedLUN(self, mapped_lun)) - return mapped_luns + yield MappedLUN(self, mapped_lun) # NodeACL public stuff def has_feature(self, feature): @@ -1063,10 +1057,9 @@ class TPG(CFSNode): def _list_network_portals(self): self._check_self() if not self.has_feature('nps'): - return [] - network_portals = [] - network_portal_dirs = os.listdir("%s/np" % self.path) - for network_portal_dir in network_portal_dirs: + return + + for network_portal_dir in os.listdir("%s/np" % self.path): if network_portal_dir.startswith('['): # IPv6 portals are [IPv6]:PORT (ip_address, port) = \ @@ -1077,9 +1070,7 @@ class TPG(CFSNode): (ip_address, port) = \ os.path.basename(network_portal_dir).split(":") port = int(port) - network_portals.append( - NetworkPortal(self, ip_address, port, 'lookup')) - return network_portals + yield NetworkPortal(self, ip_address, port, 'lookup') def _get_enable(self): self._check_self() @@ -1146,24 +1137,21 @@ class TPG(CFSNode): def _list_node_acls(self): self._check_self() if not self.has_feature('acls'): - return [] - node_acls = [] + return + node_acl_dirs = [os.path.basename(path) for path in os.listdir("%s/acls" % self.path)] for node_acl_dir in node_acl_dirs: - node_acls.append(NodeACL(self, node_acl_dir, 'lookup')) - return node_acls + yield NodeACL(self, node_acl_dir, 'lookup') def _list_luns(self): self._check_self() - luns = [] lun_dirs = [os.path.basename(path) for path in os.listdir("%s/lun" % self.path)] for lun_dir in lun_dirs: lun = lun_dir.split('_')[1] lun = int(lun) - luns.append(LUN(self, lun)) - return luns + yield LUN(self, lun) def _control(self, command): self._check_self() @@ -1314,13 +1302,10 @@ class Target(CFSNode): def _list_tpgs(self): self._check_self() - tpgs = [] - tpg_dirs = glob.glob("%s/tpgt*" % self.path) - for tpg_dir in tpg_dirs: + for tpg_dir in glob.glob("%s/tpgt*" % self.path): tag = os.path.basename(tpg_dir).split('_')[1] tag = int(tag) - tpgs.append(TPG(self, tag, 'lookup')) - return tpgs + yield TPG(self, tag, 'lookup') # Target public stuff diff --git a/rtslib/tcm.py b/rtslib/tcm.py index 326b8ad..d4c08ed 100644 --- a/rtslib/tcm.py +++ b/rtslib/tcm.py @@ -56,16 +56,12 @@ class Backstore(CFSNode): def _list_storage_objects(self): self._check_self() - storage_objects = [] storage_object_names = [os.path.basename(s) for s in os.listdir(self.path) if s not in set(["hba_info", "hba_mode"])] for storage_object_name in storage_object_names: - storage_objects.append(self._storage_object_class( - self, storage_object_name)) - - return storage_objects + yield self._storage_object_class(self, storage_object_name) def _create_in_cfs_ine(self, mode): try: @@ -399,13 +395,11 @@ class StorageObject(CFSNode): def _list_attached_luns(self): ''' - Just returns a set of all luns attached to a storage object. + Generates all luns attached to a storage object. ''' self._check_self() - luns = set([]) for lun in self._gen_attached_luns(): - luns.add(lun) - return luns + yield lun # StorageObject public stuff diff --git a/rtslib/utils.py b/rtslib/utils.py index 1cad383..d1be95b 100644 --- a/rtslib/utils.py +++ b/rtslib/utils.py @@ -54,33 +54,6 @@ class RTSLibNotInCFS(RTSLibError): ''' pass -def flatten_nested_list(nested_list): - ''' - Function to flatten a nested list. - - >>> import rtslib.utils as utils - >>> utils.flatten_nested_list([[1,2,3,[4,5,6]],[7,8],[[[9,10]],[11,]]]) - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] - - @param nested_list: A nested list (list of lists of lists etc.) - @type nested_list: list - @return: A list with only non-list elements - ''' - return list(gen_list_item(nested_list)) - -def gen_list_item(nested_list): - ''' - The generator for flatten_nested_list(). - It returns one by one items that are not a list, and recurses when - he finds an item that is a list. - ''' - for item in nested_list: - if type(item) is list: - for nested_item in gen_list_item(item): - yield nested_item - else: - yield item - def fwrite(path, string): ''' This function writes a string to a file, and takes care of -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html