Prevent race condition on MAC addresses
authorIustin Pop <iustin@google.com>
Thu, 12 Feb 2009 17:04:19 +0000 (17:04 +0000)
committerIustin Pop <iustin@google.com>
Thu, 12 Feb 2009 17:04:19 +0000 (17:04 +0000)
This patch adds a temporary set for MACs that have been requested but
are not yet in the configuration (as part of an instance NIC). The MACs
of an instance are automatically removed from this set when the instance
is updated (or first added to the config).

Reviewed-by: ultrotter

lib/config.py

index dbb0083..46574df 100644 (file)
@@ -79,6 +79,7 @@ class ConfigWriter:
       self._cfg_file = cfg_file
     self._temporary_ids = set()
     self._temporary_drbds = {}
+    self._temporary_macs = set()
     # Note: in order to prevent errors when resolving our name in
     # _DistributeConfig, we compute it here once and reuse it; it's
     # better to raise an error before starting to modify the config
@@ -110,11 +111,12 @@ class ConfigWriter:
       byte2 = random.randrange(0, 256)
       byte3 = random.randrange(0, 256)
       mac = "%s:%02x:%02x:%02x" % (prefix, byte1, byte2, byte3)
-      if mac not in all_macs:
+      if mac not in all_macs and mac not in self._temporary_macs:
         break
       retries -= 1
     else:
       raise errors.ConfigurationError("Can't generate unique MAC")
+    self._temporary_macs.add(mac)
     return mac
 
   @locking.ssynchronized(_config_lock, shared=1)
@@ -126,7 +128,7 @@ class ConfigWriter:
 
     """
     all_macs = self._AllMACs()
-    return mac in all_macs
+    return mac in all_macs or mac in self._temporary_macs
 
   @locking.ssynchronized(_config_lock, shared=1)
   def GenerateDRBDSecret(self):
@@ -687,6 +689,8 @@ class ConfigWriter:
     self._config_data.instances[instance.name] = instance
     self._config_data.cluster.serial_no += 1
     self._UnlockedReleaseDRBDMinors(instance.name)
+    for nic in instance.nics:
+      self._temporary_macs.discard(nic.mac)
     self._WriteConfig()
 
   def _SetInstanceStatus(self, instance_name, status):
@@ -1236,5 +1240,7 @@ class ConfigWriter:
 
     if isinstance(target, objects.Instance):
       self._UnlockedReleaseDRBDMinors(target.name)
+      for nic in target.nics:
+        self._temporary_macs.discard(nic.mac)
 
     self._WriteConfig()