diff --git a/lib/mcpu.py b/lib/mcpu.py index cd5a4e4c36efdb7bc895d340c545a653a5d2e6dc..6e8be77744c5600bbc70d5b74fabb1e63ab2bdee 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -246,7 +246,7 @@ class Processor(object): """Object which runs OpCodes""" DISPATCH_TABLE = _ComputeDispatchTable() - def __init__(self, context, ec_id): + def __init__(self, context, ec_id, enable_locks=True): """Constructor for Processor @type context: GanetiContext @@ -260,6 +260,16 @@ class Processor(object): self._cbs = None self.rpc = context.rpc self.hmclass = HooksMaster + self._enable_locks = enable_locks + + def _CheckLocksEnabled(self): + """Checks if locking is enabled. + + @raise errors.ProgrammerError: In case locking is not enabled + + """ + if not self._enable_locks: + raise errors.ProgrammerError("Attempted to use disabled locks") def _AcquireLocks(self, level, names, shared, timeout, priority): """Acquires locks via the Ganeti lock manager. @@ -276,6 +286,8 @@ class Processor(object): amount of time """ + self._CheckLocksEnabled() + if self._cbs: self._cbs.CheckCancel() @@ -350,6 +362,8 @@ class Processor(object): " others") elif adding_locks or acquiring_locks: + self._CheckLocksEnabled() + lu.DeclareLocks(level) share = lu.share_locks[level] @@ -420,12 +434,17 @@ class Processor(object): self._cbs = cbs try: - # Acquire the Big Ganeti Lock exclusively if this LU requires it, - # and in a shared fashion otherwise (to prevent concurrent run with - # an exclusive LU. - self._AcquireLocks(locking.LEVEL_CLUSTER, locking.BGL, - not lu_class.REQ_BGL, calc_timeout(), - priority) + if self._enable_locks: + # Acquire the Big Ganeti Lock exclusively if this LU requires it, + # and in a shared fashion otherwise (to prevent concurrent run with + # an exclusive LU. + self._AcquireLocks(locking.LEVEL_CLUSTER, locking.BGL, + not lu_class.REQ_BGL, calc_timeout(), + priority) + elif lu_class.REQ_BGL: + raise errors.ProgrammerError("Opcode '%s' requires BGL, but locks are" + " disabled" % op.OP_ID) + try: lu = lu_class(self, op, self.context, self.rpc) lu.ExpandNames() @@ -438,7 +457,10 @@ class Processor(object): if self._ec_id: self.context.cfg.DropECReservations(self._ec_id) finally: - self.context.glm.release(locking.LEVEL_CLUSTER) + # Release BGL if owned + if self.context.glm.is_owned(locking.LEVEL_CLUSTER): + assert self._enable_locks + self.context.glm.release(locking.LEVEL_CLUSTER) finally: self._cbs = None diff --git a/lib/server/masterd.py b/lib/server/masterd.py index d799faa7bd3a8779677b5886703efdbcec738198..ee3a12eab684368c9fbda5cfc2c7d528fcc36086 100644 --- a/lib/server/masterd.py +++ b/lib/server/masterd.py @@ -427,7 +427,7 @@ class ClientOps: """ # Queries don't have a job id - proc = mcpu.Processor(self.server.context, None) + proc = mcpu.Processor(self.server.context, None, enable_locks=False) # TODO: Executing an opcode using locks will acquire them in blocking mode. # Consider using a timeout for retries.