Commit 4fae38c5 authored by Guido Trotter's avatar Guido Trotter
Browse files

ConfigWriter: move _temporary_ids to reservation



In order to do this we need to pass a job id when reserving a resource.
We have one during _EnsureUUIDs because we passed it in from AddNode and
AddInstance. During config upgrade we use a fake job ID which we then
cleanup. We can delete the _CleanupTemporaryIDs code, since the cleanup
is going to be done at job finish time by mcpu.
Signed-off-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarIustin Pop <iustin@google.com>
parent 013da361
...@@ -5311,7 +5311,7 @@ def _GenerateUniqueNames(lu, exts): ...@@ -5311,7 +5311,7 @@ def _GenerateUniqueNames(lu, exts):
""" """
results = [] results = []
for val in exts: for val in exts:
new_id = lu.cfg.GenerateUniqueID() new_id = lu.cfg.GenerateUniqueID(lu.proc.GetECId())
results.append("%s%s" % (new_id, val)) results.append("%s%s" % (new_id, val))
return results return results
......
...@@ -47,6 +47,9 @@ from ganeti import serializer ...@@ -47,6 +47,9 @@ from ganeti import serializer
_config_lock = locking.SharedLock() _config_lock = locking.SharedLock()
# job id used for resource management at config upgrade time
_UPGRADE_CONFIG_JID="jid-cfg-upgrade"
def _ValidateConfig(data): def _ValidateConfig(data):
"""Verifies that a configuration objects looks valid. """Verifies that a configuration objects looks valid.
...@@ -132,7 +135,7 @@ class ConfigWriter: ...@@ -132,7 +135,7 @@ class ConfigWriter:
self._cfg_file = constants.CLUSTER_CONF_FILE self._cfg_file = constants.CLUSTER_CONF_FILE
else: else:
self._cfg_file = cfg_file self._cfg_file = cfg_file
self._temporary_ids = set() self._temporary_ids = TemporaryReservationManager()
self._temporary_drbds = {} self._temporary_drbds = {}
self._temporary_macs = set() self._temporary_macs = set()
# Note: in order to prevent errors when resolving our name in # Note: in order to prevent errors when resolving our name in
...@@ -225,14 +228,14 @@ class ConfigWriter: ...@@ -225,14 +228,14 @@ class ConfigWriter:
""" """
existing = set() existing = set()
if include_temporary: if include_temporary:
existing.update(self._temporary_ids) existing.update(self._temporary_ids.GetReserved())
existing.update(self._AllLVs()) existing.update(self._AllLVs())
existing.update(self._config_data.instances.keys()) existing.update(self._config_data.instances.keys())
existing.update(self._config_data.nodes.keys()) existing.update(self._config_data.nodes.keys())
existing.update([i.uuid for i in self._AllUUIDObjects() if i.uuid]) existing.update([i.uuid for i in self._AllUUIDObjects() if i.uuid])
return existing return existing
def _GenerateUniqueID(self): def _GenerateUniqueID(self, ec_id):
"""Generate an unique UUID. """Generate an unique UUID.
This checks the current node, instances and disk names for This checks the current node, instances and disk names for
...@@ -242,33 +245,20 @@ class ConfigWriter: ...@@ -242,33 +245,20 @@ class ConfigWriter:
@return: the unique id @return: the unique id
""" """
existing = self._AllIDs(include_temporary=True) existing = self._AllIDs(include_temporary=False)
retries = 64 return self._temporary_ids.Generate(existing, utils.NewUUID, ec_id)
while retries > 0:
unique_id = utils.NewUUID()
if unique_id not in existing and unique_id is not None:
break
else:
raise errors.ConfigurationError("Not able generate an unique ID"
" (last tried ID: %s" % unique_id)
self._temporary_ids.add(unique_id)
return unique_id
@locking.ssynchronized(_config_lock, shared=1) @locking.ssynchronized(_config_lock, shared=1)
def GenerateUniqueID(self): def GenerateUniqueID(self, ec_id):
"""Generate an unique ID. """Generate an unique ID.
This is just a wrapper over the unlocked version. This is just a wrapper over the unlocked version.
""" @type ec_id: string
return self._GenerateUniqueID() @param ec_id: unique id for the job to reserve the id to
def _CleanupTemporaryIDs(self):
"""Cleanups the _temporary_ids structure.
""" """
existing = self._AllIDs(include_temporary=False) return self._GenerateUniqueID(ec_id)
self._temporary_ids = self._temporary_ids - existing
def _AllMACs(self): def _AllMACs(self):
"""Return all MACs present in the config. """Return all MACs present in the config.
...@@ -821,7 +811,7 @@ class ConfigWriter: ...@@ -821,7 +811,7 @@ class ConfigWriter:
""" """
if not item.uuid: if not item.uuid:
item.uuid = self._GenerateUniqueID() item.uuid = self._GenerateUniqueID(ec_id)
elif item.uuid in self._AllIDs(temporary=True): elif item.uuid in self._AllIDs(temporary=True):
raise errors.ConfigurationError("Cannot add '%s': UUID already in use" % raise errors.ConfigurationError("Cannot add '%s': UUID already in use" %
(item.name, item.uuid)) (item.name, item.uuid))
...@@ -1205,10 +1195,14 @@ class ConfigWriter: ...@@ -1205,10 +1195,14 @@ class ConfigWriter:
modified = False modified = False
for item in self._AllUUIDObjects(): for item in self._AllUUIDObjects():
if item.uuid is None: if item.uuid is None:
item.uuid = self._GenerateUniqueID() item.uuid = self._GenerateUniqueID(_UPGRADE_CONFIG_JID)
modified = True modified = True
if modified: if modified:
self._WriteConfig() self._WriteConfig()
# This is ok even if it acquires the internal lock, as _UpgradeConfig is
# only called at config init time, without the lock held
self.DropECReservations(_UPGRADE_CONFIG_JID)
def _DistributeConfig(self, feedback_fn): def _DistributeConfig(self, feedback_fn):
"""Distribute the configuration to the other nodes. """Distribute the configuration to the other nodes.
...@@ -1260,11 +1254,6 @@ class ConfigWriter: ...@@ -1260,11 +1254,6 @@ class ConfigWriter:
""" """
assert feedback_fn is None or callable(feedback_fn) assert feedback_fn is None or callable(feedback_fn)
# First, cleanup the _temporary_ids set, if an ID is now in the
# other objects it should be discarded to prevent unbounded growth
# of that structure
self._CleanupTemporaryIDs()
# Warn on config errors, but don't abort the save - the # Warn on config errors, but don't abort the save - the
# configuration has already been modified, and we can't revert; # configuration has already been modified, and we can't revert;
# the best we can do is to warn the user and save as is, leaving # the best we can do is to warn the user and save as is, leaving
...@@ -1441,5 +1430,5 @@ class ConfigWriter: ...@@ -1441,5 +1430,5 @@ class ConfigWriter:
"""Drop per-execution-context reservations """Drop per-execution-context reservations
""" """
pass self._temporary_ids.DropECReservations(ec_id)
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