Revision 04864530

b/lib/mcpu.py
37 37
from ganeti import config
38 38
from ganeti import ssconf
39 39
from ganeti import logger
40
from ganeti import locking
40 41

  
41 42

  
42 43
class Processor(object):
......
98 99
    """
99 100
    self.context = context
100 101
    self._feedback_fn = feedback
102
    self.exclusive_BGL = False
101 103

  
102 104
  def ExecOpCode(self, op):
103 105
    """Execute an opcode.
......
120 122
      sstore = ssconf.SimpleStore()
121 123

  
122 124
    write_count = self.context.cfg.write_count
123
    lu = lu_class(self, op, self.context.cfg, sstore)
124
    lu.CheckPrereq()
125
    hm = HooksMaster(rpc.call_hooks_runner, self, lu)
126
    h_results = hm.RunPhase(constants.HOOKS_PHASE_PRE)
127
    lu.HooksCallBack(constants.HOOKS_PHASE_PRE,
128
                     h_results, self._feedback_fn, None)
125

  
126
    # Acquire the Big Ganeti Lock exclusively if this LU requires it, and in a
127
    # shared fashion otherwise (to prevent concurrent run with an exclusive LU.
128
    self.context.GLM.acquire(locking.LEVEL_CLUSTER, [locking.BGL],
129
                             shared=not lu_class.REQ_BGL)
129 130
    try:
130
      result = lu.Exec(self._feedback_fn)
131
      h_results = hm.RunPhase(constants.HOOKS_PHASE_POST)
132
      result = lu.HooksCallBack(constants.HOOKS_PHASE_POST,
133
                       h_results, self._feedback_fn, result)
134
    finally:
135
      if lu.cfg is not None:
136
        # we use lu.cfg and not self.cfg as for init cluster, self.cfg
137
        # is None but lu.cfg has been recently initialized in the
138
        # lu.Exec method
139
        if write_count != lu.cfg.write_count:
131
      self.exclusive_BGL = lu_class.REQ_BGL
132
      lu = lu_class(self, op, self.context.cfg, sstore)
133
      lu.CheckPrereq()
134
      hm = HooksMaster(rpc.call_hooks_runner, self, lu)
135
      h_results = hm.RunPhase(constants.HOOKS_PHASE_PRE)
136
      lu.HooksCallBack(constants.HOOKS_PHASE_PRE, h_results,
137
                       self._feedback_fn, None)
138
      try:
139
        result = lu.Exec(self._feedback_fn)
140
        h_results = hm.RunPhase(constants.HOOKS_PHASE_POST)
141
        result = lu.HooksCallBack(constants.HOOKS_PHASE_POST, h_results,
142
                                  self._feedback_fn, result)
143
      finally:
144
        # FIXME: This needs locks if not lu_class.REQ_BGL
145
        if write_count != self.context.cfg.write_count:
140 146
          hm.RunConfigUpdate()
147
    finally:
148
      self.context.GLM.release(locking.LEVEL_CLUSTER)
149
      self.exclusive_BGL = False
141 150

  
142 151
    return result
143 152

  
......
158 167
    if lu_class is None:
159 168
      raise errors.OpCodeUnknown("Unknown opcode")
160 169

  
170
    if lu_class.REQ_BGL and not self.exclusive_BGL:
171
      raise errors.ProgrammerError("LUs which require the BGL cannot"
172
                                   " be chained to granular ones.")
173

  
161 174
    if lu_class.REQ_WSSTORE:
162 175
      sstore = ssconf.WritableSimpleStore()
163 176
    else:

Also available in: Unified diff