diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 4d172eefced3efee5ead904d01929c1a6e1ff93d..a6d759f073154b7410da13561a67c078b9d45ca0 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -83,6 +83,7 @@ class LogicalUnit(object):
     self.sstore = sstore
     self.context = context
     self.needed_locks = None
+    self.share_locks = dict(((i, 0) for i in locking.LEVELS))
     self.__ssh = None
 
     for attr_name in self._OP_REQP:
@@ -128,6 +129,10 @@ class LogicalUnit(object):
         (this reflects what LockSet does, and will be replaced before
         CheckPrereq with the full list of nodes that have been locked)
 
+    If you need to share locks (rather than acquire them exclusively) at one
+    level you can modify self.share_locks, setting a true value (usually 1) for
+    that level. By default locks are not shared.
+
     Examples:
     # Acquire all nodes and one instance
     self.needed_locks = {
diff --git a/lib/mcpu.py b/lib/mcpu.py
index 66f657d48e10c5f52bac7927da5b9097a545ab1d..93dfaea9f8474425a11f04047a16f0d8ebafe461 100644
--- a/lib/mcpu.py
+++ b/lib/mcpu.py
@@ -134,10 +134,13 @@ class Processor(object):
       # This gives a chance to LUs to make last-minute changes after acquiring
       # locks at any preceding level.
       lu.DeclareLocks(level)
+      needed_locks = lu.needed_locks[level]
+      share = lu.share_locks[level]
       # This is always safe to do, as we can't acquire more/less locks than
       # what was requested.
       lu.needed_locks[level] = self.context.glm.acquire(level,
-                                                        lu.needed_locks[level])
+                                                        needed_locks,
+                                                        shared=share)
       try:
         result = self._LockAndExecLU(lu, level + 1)
       finally: