Change in vdsm[master]: Add ResourceLocker

alitke at redhat.com alitke at redhat.com
Mon Jul 13 19:45:56 UTC 2015


Adam Litke has uploaded a new change for review.

Change subject: Add ResourceLocker
......................................................................

Add ResourceLocker

Change-Id: I29589889efd39920d72979e89405ff6cf36b803b
Signed-off-by: Adam Litke <alitke at redhat.com>
---
A tests/resourcelocker_tests.py
M vdsm.spec.in
M vdsm/storage/Makefile.am
A vdsm/storage/resourceLocker.py
4 files changed, 125 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/54/43554/1

diff --git a/tests/resourcelocker_tests.py b/tests/resourcelocker_tests.py
new file mode 100644
index 0000000..0ba7461
--- /dev/null
+++ b/tests/resourcelocker_tests.py
@@ -0,0 +1,53 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import uuid
+import threading
+
+from testlib import VdsmTestCase
+
+from storage.resourceLocker import ResourceLocker, LOCK_CACHE_SIZE
+
+
+class ResourceLockerTests(VdsmTestCase):
+    def test_lock_cache(self):
+        def worker(res):
+            locker.acquireResource(res, False)
+            event.set()
+
+        locker = ResourceLocker()
+        event = threading.Event()
+        nr_resources = LOCK_CACHE_SIZE + 1
+        uuid_list = [str(uuid.uuid4()) for _ in range(nr_resources)]
+
+        t = threading.Thread(target=worker, args=(uuid_list[0],))
+        t.daemon = True
+        t.start()
+        event.wait()
+
+        for res in uuid_list[1:]:
+            locker.acquireResource(res, False)
+            locker.releaseResource(res)
+        t.join()
+
+        # The first resource is still in use
+        self.assertIn(uuid_list[0], locker._resources)
+        self.assertNotIn(uuid_list[1], locker._resources)
+
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 966a974..4ba9812 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -930,6 +930,7 @@
 %{_datadir}/%{vdsm_name}/storage/persistentDict.py*
 %{_datadir}/%{vdsm_name}/storage/resourceFactories.py*
 %{_datadir}/%{vdsm_name}/storage/remoteFileHandler.py*
+%{_datadir}/%{vdsm_name}/storage/resourceLocker.py*
 %{_datadir}/%{vdsm_name}/storage/resourceManager.py*
 %{_datadir}/%{vdsm_name}/storage/clusterlock.py*
 %{_datadir}/%{vdsm_name}/storage/sdc.py*
diff --git a/vdsm/storage/Makefile.am b/vdsm/storage/Makefile.am
index 4ebe0a2..a4ec93a 100644
--- a/vdsm/storage/Makefile.am
+++ b/vdsm/storage/Makefile.am
@@ -54,6 +54,7 @@
 	persistentDict.py \
 	remoteFileHandler.py \
 	resourceFactories.py \
+	resourceLocker.py \
 	resourceManager.py \
 	sdc.py \
 	sd.py \
diff --git a/vdsm/storage/resourceLocker.py b/vdsm/storage/resourceLocker.py
new file mode 100644
index 0000000..f6d2403
--- /dev/null
+++ b/vdsm/storage/resourceLocker.py
@@ -0,0 +1,70 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+import logging
+import threading
+from contextlib import contextmanager
+from collections import OrderedDict
+
+from storage.misc import RWLock
+
+LOCK_CACHE_SIZE = 50
+
+
+class ResourceLocker(object):
+    log = logging.getLogger('sdm.ResourceLocker')
+
+    def __init__(self):
+        self._lock = threading.Lock()
+        self._resources = OrderedDict()
+
+    def acquireResource(self, res, exclusive):
+        with self._lock:
+            if len(self._resources) >= LOCK_CACHE_SIZE:
+                self._drop_cached_lock()
+            if res not in self._resources:
+                self._resources[res] = RWLock()
+            self._resources[res].acquire(exclusive)
+
+    def releaseResource(self, res):
+        with self._lock:
+            self._resources[res].release()
+
+    @contextmanager
+    def lockResource(self, res, exclusive):
+        self.acquireResource(res, exclusive)
+        try:
+            yield
+        finally:
+            self.releaseResource(res)
+
+    def _drop_cached_lock(self):
+        for res, lock in self._resources.iteritems():
+            if lock.acquire(exclusive=True, block=False):
+                try:
+                    self.log.debug("Forgetting lock for resource %s", res)
+                    del self._resources[res]
+                    return
+                finally:
+                    lock.release()
+        self.log.debug("No free locks found")
+
+
+locker = ResourceLocker()


-- 
To view, visit https://gerrit.ovirt.org/43554
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I29589889efd39920d72979e89405ff6cf36b803b
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke at redhat.com>


More information about the vdsm-patches mailing list