summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Grover <agrover@redhat.com>2013-01-03 12:02:31 -0800
committerAndy Grover <agrover@redhat.com>2013-01-03 12:17:23 -0800
commit15e4ad063f0751f4249a0020d913c44381b51145 (patch)
tree5445a4199ef015c5c241d95259e0f905ae1c77d1
parent53876e897a1f47d980bad9d3c322d33bf39dde26 (diff)
downloadrtslib-fb-15e4ad063f0751f4249a0020d913c44381b51145.tar.gz
Add a cache for backstore lookups
For each new SO we need to verify there isn't an existing one with the same (type, name). Unfortunately these are nested in directories, so adding each new SO requires more directory searches. AFAIK there's no way around this without changing configfs layout. This change adds a backstore cache. We still resort to glob() for new SOs (it's still O(n^2)) but avoiding this for SOs we've seen before really seems to help a lot. Signed-off-by: Andy Grover <agrover@redhat.com>
-rw-r--r--rtslib/tcm.py29
1 files changed, 19 insertions, 10 deletions
diff --git a/rtslib/tcm.py b/rtslib/tcm.py
index 7dbc1b9..b3fb374 100644
--- a/rtslib/tcm.py
+++ b/rtslib/tcm.py
@@ -713,6 +713,7 @@ bs_params = {
BlockStorageObject: dict(name='block', alt_dirprefix='iblock'),
}
+bs_cache = {}
class _Backstore(CFSNode):
"""
@@ -721,27 +722,31 @@ class _Backstore(CFSNode):
Created by storageobject ctor before SO configfs entry.
"""
- def __init__(self, name, storage_object_cls, mode, index=None):
+ def __init__(self, name, storage_object_cls, mode):
super(_Backstore, self).__init__()
self._so_cls = storage_object_cls
self._plugin = bs_params[self._so_cls]['name']
- self._index = index
dirp = bs_params[self._so_cls].get("alt_dirprefix", self._plugin)
- # does (so_cls, index) exist already?
- for plugin, num in self._hbas(self.path):
- if os.path.isdir("%s/core/%s_%s/%s" %
- (self.path, dirp, num, name)):
+ # mapping in cache?
+ lookup_key = "%s/%s" % (dirp, name)
+ self._index = bs_cache.get(lookup_key, None)
+
+ if not self._index:
+ # cache miss. does (so_cls, index) exist already?
+ dirs = glob.glob("%s/core/%s_*/%s" % (self.configfs_dir, dirp, name))
+ if len(dirs):
if mode == 'create':
raise RTSLibError("Storage object %s/%s already exists" %
(self._plugin, name))
else:
- self._index = int(num)
- break
+ self._index = int(dirs[0].split("/")[-2].rsplit("_", 1)[1])
+ else:
+ self._index = self._next_hba_index(self.configfs_dir)
+ bs_cache[lookup_key] = self._index
- if self._index == None:
- self._index = self._next_hba_index(self.configfs_dir)
+ self.lookup_key = lookup_key
self._path = "%s/core/%s_%d" % (self.configfs_dir,
dirp,
@@ -768,6 +773,10 @@ class _Backstore(CFSNode):
if regex:
yield(regex.group(1), regex.group(3))
+ def delete(self):
+ super(_Backstore, self).delete()
+ del bs_cache[self.lookup_key]
+
def _get_index(self):
return self._index