Revision c4a2fee1 lib/cmdlib.py

b/lib/cmdlib.py
84 84
    self.context = context
85 85
    self.needed_locks = None
86 86
    self.share_locks = dict(((i, 0) for i in locking.LEVELS))
87
    # Used to force good behavior when calling helper functions
88
    self.recalculate_locks = {}
87 89
    self.__ssh = None
88 90

  
89 91
    for attr_name in self._OP_REQP:
......
262 264
    self.needed_locks[locking.LEVEL_INSTANCE] = expanded_name
263 265
    self.op.instance_name = expanded_name
264 266

  
267
  def _LockInstancesNodes(self):
268
    """Helper function to declare instances' nodes for locking.
269

  
270
    This function should be called after locking one or more instances to lock
271
    their nodes. Its effect is populating self.needed_locks[locking.LEVEL_NODE]
272
    with all primary or secondary nodes for instances already locked and
273
    present in self.needed_locks[locking.LEVEL_INSTANCE].
274

  
275
    It should be called from DeclareLocks, and for safety only works if
276
    self.recalculate_locks[locking.LEVEL_NODE] is set.
277

  
278
    In the future it may grow parameters to just lock some instance's nodes, or
279
    to just lock primaries or secondary nodes, if needed.
280

  
281
    If should be called in DeclareLocks in a way similar to:
282

  
283
    if level == locking.LEVEL_NODE:
284
      self._LockInstancesNodes()
285

  
286
    """
287
    assert locking.LEVEL_NODE in self.recalculate_locks, \
288
      "_LockInstancesNodes helper function called with no nodes to recalculate"
289

  
290
    # TODO: check if we're really been called with the instance locks held
291

  
292
    # For now we'll replace self.needed_locks[locking.LEVEL_NODE], but in the
293
    # future we might want to have different behaviors depending on the value
294
    # of self.recalculate_locks[locking.LEVEL_NODE]
295
    wanted_nodes = []
296
    for instance_name in self.needed_locks[locking.LEVEL_INSTANCE]:
297
      instance = self.context.cfg.GetInstanceInfo(instance_name)
298
      wanted_nodes.append(instance.primary_node)
299
      wanted_nodes.extend(instance.secondary_nodes)
300
    self.needed_locks[locking.LEVEL_NODE] = wanted_nodes
301

  
302
    del self.recalculate_locks[locking.LEVEL_NODE]
303

  
265 304

  
266 305
class NoHooksLU(LogicalUnit):
267 306
  """Simple LU which runs no hooks.

Also available in: Unified diff