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

LogicalUnit: add ExpandNames function

New concurrent LUs will need to call ExpandNames so that any names
passed in by the user are canonicalized, and can be used by hooks,
locking and other parts of the code. This was done in CheckPrereq
before, but it's now splitted out, as it's needed for locking, which in
turn CheckPrereq needs. Old LUs can be converted gradually.

Reviewed-by: iustinp
parent 36c381d7
...@@ -50,8 +50,8 @@ class LogicalUnit(object): ...@@ -50,8 +50,8 @@ class LogicalUnit(object):
"""Logical Unit base class. """Logical Unit base class.
Subclasses must follow these rules: Subclasses must follow these rules:
- implement CheckPrereq which also fills in the opcode instance - implement ExpandNames
with all the fields (even if as None) - implement CheckPrereq
- implement Exec - implement Exec
- implement BuildHooksEnv - implement BuildHooksEnv
- redefine HPATH and HTYPE - redefine HPATH and HTYPE
...@@ -82,6 +82,7 @@ class LogicalUnit(object): ...@@ -82,6 +82,7 @@ class LogicalUnit(object):
self.cfg = context.cfg self.cfg = context.cfg
self.sstore = sstore self.sstore = sstore
self.context = context self.context = context
self.needed_locks = None
self.__ssh = None self.__ssh = None
for attr_name in self._OP_REQP: for attr_name in self._OP_REQP:
...@@ -109,6 +110,46 @@ class LogicalUnit(object): ...@@ -109,6 +110,46 @@ class LogicalUnit(object):
ssh = property(fget=__GetSSH) ssh = property(fget=__GetSSH)
def ExpandNames(self):
"""Expand names for this LU.
This method is called before starting to execute the opcode, and it should
update all the parameters of the opcode to their canonical form (e.g. a
short node name must be fully expanded after this method has successfully
completed). This way locking, hooks, logging, ecc. can work correctly.
LUs which implement this method must also populate the self.needed_locks
member, as a dict with lock levels as keys, and a list of needed lock names
as values. Rules:
- Use an empty dict if you don't need any lock
- If you don't need any lock at a particular level omit that level
- Don't put anything for the BGL level
- If you want all locks at a level use None as a value
(this reflects what LockSet does, and will be replaced before
CheckPrereq with the full list of nodes that have been locked)
Examples:
# Acquire all nodes and one instance
self.needed_locks = {
locking.LEVEL_NODE: None,
locking.LEVEL_INSTANCES: ['instance1.example.tld'],
}
# Acquire just two nodes
self.needed_locks = {
locking.LEVEL_NODE: ['node1.example.tld', 'node2.example.tld'],
}
# Acquire no locks
self.needed_locks = {} # No, you can't leave it to the default value None
"""
# The implementation of this method is mandatory only if the new LU is
# concurrent, so that old LUs don't need to be changed all at the same
# time.
if self.REQ_BGL:
self.needed_locks = {} # Exclusive LUs don't need locks.
else:
raise NotImplementedError
def CheckPrereq(self): def CheckPrereq(self):
"""Check prerequisites for this LU. """Check prerequisites for this LU.
...@@ -121,9 +162,7 @@ class LogicalUnit(object): ...@@ -121,9 +162,7 @@ class LogicalUnit(object):
not fulfilled. Its return value is ignored. not fulfilled. Its return value is ignored.
This method should also update all the parameters of the opcode to This method should also update all the parameters of the opcode to
their canonical form; e.g. a short node name must be fully their canonical form if it hasn't been done by ExpandNames before.
expanded after this method has successfully completed (so that
hooks, logging, etc. work correctly).
""" """
raise NotImplementedError raise NotImplementedError
......
...@@ -150,6 +150,7 @@ class Processor(object): ...@@ -150,6 +150,7 @@ class Processor(object):
try: try:
self.exclusive_BGL = lu_class.REQ_BGL self.exclusive_BGL = lu_class.REQ_BGL
lu = lu_class(self, op, self.context, sstore) lu = lu_class(self, op, self.context, sstore)
lu.ExpandNames()
result = self._ExecLU(lu) result = self._ExecLU(lu)
finally: finally:
self.context.glm.release(locking.LEVEL_CLUSTER) self.context.glm.release(locking.LEVEL_CLUSTER)
......
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