Commit ca2a79e1 authored by Guido Trotter's avatar Guido Trotter
Browse files

Implement adding/removal of locks by declaration

With this patch LUs can declare locks to be added when they start and/or
removed after they finish. For now locks can only be added in the
acquired state, and removed if owned, and added locks default to be
removed again, unless some action is taken.

Reviewed-by: imsnah
parent d2aff862
...@@ -80,9 +80,12 @@ class LogicalUnit(object): ...@@ -80,9 +80,12 @@ class LogicalUnit(object):
self.cfg = context.cfg self.cfg = context.cfg
self.sstore = sstore self.sstore = sstore
self.context = context self.context = context
# Dicts used to declare locking needs to mcpu
self.needed_locks = None self.needed_locks = None
self.acquired_locks = {} self.acquired_locks = {}
self.share_locks = dict(((i, 0) for i in locking.LEVELS)) self.share_locks = dict(((i, 0) for i in locking.LEVELS))
self.add_locks = {}
self.remove_locks = {}
# Used to force good behavior when calling helper functions # Used to force good behavior when calling helper functions
self.recalculate_locks = {} self.recalculate_locks = {}
self.__ssh = None self.__ssh = None
...@@ -129,21 +129,40 @@ class Processor(object): ...@@ -129,21 +129,40 @@ class Processor(object):
given LU and its opcodes. given LU and its opcodes.
""" """
adding_locks = level in lu.add_locks
acquiring_locks = level in lu.needed_locks
if level not in locking.LEVELS: if level not in locking.LEVELS:
result = self._ExecLU(lu) result = self._ExecLU(lu)
elif level in lu.needed_locks: elif adding_locks and acquiring_locks:
# This gives a chance to LUs to make last-minute changes after acquiring # We could both acquire and add locks at the same level, but for now we
# locks at any preceding level. # don't need this, so we'll avoid the complicated code needed.
raise NotImplementedError(
"Can't declare locks to acquire when adding others")
elif adding_locks or acquiring_locks:
lu.DeclareLocks(level) lu.DeclareLocks(level)
needed_locks = lu.needed_locks[level]
share = lu.share_locks[level] share = lu.share_locks[level]
# This is always safe to do, as we can't acquire more/less locks than if acquiring_locks:
# what was requested. needed_locks = lu.needed_locks[level]
lu.acquired_locks[level] = self.context.glm.acquire(level, lu.acquired_locks[level] = self.context.glm.acquire(level,
needed_locks, needed_locks,
shared=share) shared=share)
else: # adding_locks
add_locks = lu.add_locks[level]
lu.remove_locks[level] = add_locks
self.context.glm.add(level, add_locks, acquired=1, shared=share)
except errors.LockError:
raise errors.OpPrereqError(
"Coudn't add locks (%s), probably because of a race condition"
" with another job, who added them first" % add_locks)
try: try:
if adding_locks:
lu.acquired_locks[level] = add_locks
result = self._LockAndExecLU(lu, level + 1) result = self._LockAndExecLU(lu, level + 1)
if level in lu.remove_locks:
self.context.glm.remove(level, lu.remove_locks[level])
finally: finally:
if self.context.glm.is_owned(level): if self.context.glm.is_owned(level):
self.context.glm.release(level) self.context.glm.release(level)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment