Revision 4fae38c5

b/lib/cmdlib.py
5311 5311
  """
5312 5312
  results = []
5313 5313
  for val in exts:
5314
    new_id = lu.cfg.GenerateUniqueID()
5314
    new_id = lu.cfg.GenerateUniqueID(lu.proc.GetECId())
5315 5315
    results.append("%s%s" % (new_id, val))
5316 5316
  return results
5317 5317

  
b/lib/config.py
47 47

  
48 48
_config_lock = locking.SharedLock()
49 49

  
50
# job id used for resource management at config upgrade time
51
_UPGRADE_CONFIG_JID="jid-cfg-upgrade"
52

  
50 53

  
51 54
def _ValidateConfig(data):
52 55
  """Verifies that a configuration objects looks valid.
......
132 135
      self._cfg_file = constants.CLUSTER_CONF_FILE
133 136
    else:
134 137
      self._cfg_file = cfg_file
135
    self._temporary_ids = set()
138
    self._temporary_ids = TemporaryReservationManager()
136 139
    self._temporary_drbds = {}
137 140
    self._temporary_macs = set()
138 141
    # Note: in order to prevent errors when resolving our name in
......
225 228
    """
226 229
    existing = set()
227 230
    if include_temporary:
228
      existing.update(self._temporary_ids)
231
      existing.update(self._temporary_ids.GetReserved())
229 232
    existing.update(self._AllLVs())
230 233
    existing.update(self._config_data.instances.keys())
231 234
    existing.update(self._config_data.nodes.keys())
232 235
    existing.update([i.uuid for i in self._AllUUIDObjects() if i.uuid])
233 236
    return existing
234 237

  
235
  def _GenerateUniqueID(self):
238
  def _GenerateUniqueID(self, ec_id):
236 239
    """Generate an unique UUID.
237 240

  
238 241
    This checks the current node, instances and disk names for
......
242 245
    @return: the unique id
243 246

  
244 247
    """
245
    existing = self._AllIDs(include_temporary=True)
246
    retries = 64
247
    while retries > 0:
248
      unique_id = utils.NewUUID()
249
      if unique_id not in existing and unique_id is not None:
250
        break
251
    else:
252
      raise errors.ConfigurationError("Not able generate an unique ID"
253
                                      " (last tried ID: %s" % unique_id)
254
    self._temporary_ids.add(unique_id)
255
    return unique_id
248
    existing = self._AllIDs(include_temporary=False)
249
    return self._temporary_ids.Generate(existing, utils.NewUUID, ec_id)
256 250

  
257 251
  @locking.ssynchronized(_config_lock, shared=1)
258
  def GenerateUniqueID(self):
252
  def GenerateUniqueID(self, ec_id):
259 253
    """Generate an unique ID.
260 254

  
261 255
    This is just a wrapper over the unlocked version.
262 256

  
263
    """
264
    return self._GenerateUniqueID()
265

  
266
  def _CleanupTemporaryIDs(self):
267
    """Cleanups the _temporary_ids structure.
257
    @type ec_id: string
258
    @param ec_id: unique id for the job to reserve the id to
268 259

  
269 260
    """
270
    existing = self._AllIDs(include_temporary=False)
271
    self._temporary_ids = self._temporary_ids - existing
261
    return self._GenerateUniqueID(ec_id)
272 262

  
273 263
  def _AllMACs(self):
274 264
    """Return all MACs present in the config.
......
821 811

  
822 812
    """
823 813
    if not item.uuid:
824
      item.uuid = self._GenerateUniqueID()
814
      item.uuid = self._GenerateUniqueID(ec_id)
825 815
    elif item.uuid in self._AllIDs(temporary=True):
826 816
      raise errors.ConfigurationError("Cannot add '%s': UUID already in use" %
827 817
                                      (item.name, item.uuid))
......
1205 1195
    modified = False
1206 1196
    for item in self._AllUUIDObjects():
1207 1197
      if item.uuid is None:
1208
        item.uuid = self._GenerateUniqueID()
1198
        item.uuid = self._GenerateUniqueID(_UPGRADE_CONFIG_JID)
1209 1199
        modified = True
1210 1200
    if modified:
1211 1201
      self._WriteConfig()
1202
      # This is ok even if it acquires the internal lock, as _UpgradeConfig is
1203
      # only called at config init time, without the lock held
1204
      self.DropECReservations(_UPGRADE_CONFIG_JID)
1205

  
1212 1206

  
1213 1207
  def _DistributeConfig(self, feedback_fn):
1214 1208
    """Distribute the configuration to the other nodes.
......
1260 1254
    """
1261 1255
    assert feedback_fn is None or callable(feedback_fn)
1262 1256

  
1263
    # First, cleanup the _temporary_ids set, if an ID is now in the
1264
    # other objects it should be discarded to prevent unbounded growth
1265
    # of that structure
1266
    self._CleanupTemporaryIDs()
1267

  
1268 1257
    # Warn on config errors, but don't abort the save - the
1269 1258
    # configuration has already been modified, and we can't revert;
1270 1259
    # the best we can do is to warn the user and save as is, leaving
......
1441 1430
    """Drop per-execution-context reservations
1442 1431

  
1443 1432
    """
1444
    pass
1433
    self._temporary_ids.DropECReservations(ec_id)
1445 1434

  

Also available in: Unified diff